Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrieve server port #9

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 101 additions & 20 deletions src/http/QDjangoHttpServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

/** Constructs a new HTTP connection.
*/
QDjangoHttpConnection::QDjangoHttpConnection(QTcpSocket *device, QDjangoHttpServer *server)
QDjangoHttpConnection::QDjangoHttpConnection(QAbstractSocket *device, QDjangoHttpServer *server)
: QObject(server),
m_closeAfterResponse(false),
m_pendingRequest(0),
Expand Down Expand Up @@ -265,12 +265,41 @@ void QDjangoHttpConnection::_q_writeResponse()

/// \endcond

class TcpServer : public QTcpServer {
public:
TcpServer(QDjangoHttpServer* a_djandoHttpServer) :
QTcpServer(a_djandoHttpServer), m_djandoHttpServer(a_djandoHttpServer) {}


protected:
/** Call the HttpListener.incomingConnection passing the port of the server. */
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
void incomingConnection(int a_socketDescriptor)
#else
void incomingConnection(qintptr a_socketDescriptor) Q_DECL_OVERRIDE
#endif
{
m_djandoHttpServer->_q_incomingConnection(a_socketDescriptor);
}

private:
/** Reference to the HttpListener who owns the TcpServer */
QDjangoHttpServer* m_djandoHttpServer;
};

class QDjangoHttpServerPrivate
{
public:
int connectionCount;
QTcpServer *tcpServer;
QDjangoUrlResolver *urlResolver;

#ifndef QT_NO_OPENSSL
bool ssl;
QSslKey sslKey;
QSslCertificate sslCert;
QList<QSslCertificate> sslCaCerts;
#endif
};

/** Constructs a new HTTP server.
Expand All @@ -282,6 +311,9 @@ QDjangoHttpServer::QDjangoHttpServer(QObject *parent)
d->connectionCount = 0;
d->tcpServer = 0;
d->urlResolver = new QDjangoUrlResolver(this);
#ifndef QT_NO_OPENSSL
d->ssl = false;
#endif
}

/** Destroys the HTTP server.
Expand All @@ -306,13 +338,7 @@ void QDjangoHttpServer::close()
bool QDjangoHttpServer::listen(const QHostAddress &address, quint16 port)
{
if (!d->tcpServer) {
bool check;
Q_UNUSED(check);

d->tcpServer = new QTcpServer(this);
check = connect(d->tcpServer, SIGNAL(newConnection()),
this, SLOT(_q_newTcpConnection()));
Q_ASSERT(check);
d->tcpServer = new TcpServer(this);
}

return d->tcpServer->listen(address, port);
Expand All @@ -326,26 +352,81 @@ QDjangoUrlResolver* QDjangoHttpServer::urls() const
return d->urlResolver;
}

/** Tells the server to use ssl and setup the:
* \a sslKey: Ssl Key
* \a sslCert: Local Certificate
* \a sslCaCert: CA Certificates
* Qt need to be compiled with open ssl support
*/
#ifndef QT_NO_OPENSSL
void QDjangoHttpServer::setupSSL(const QSslKey &sslKey, const QSslCertificate &sslCert, const QList<QSslCertificate> &sslCaCerts)
{
d->ssl = true;
d->sslKey = sslKey;
d->sslCert = sslCert;
d->sslCaCerts = sslCaCerts;
}
#endif

/** Returns the server's port if the server is listening for connections; otherwise returns 0.
*/
quint32 QDjangoHttpServer::serverPort() const
{
if (!d->tcpServer) return 0;
return d->tcpServer->serverPort();
}

/** Handles the creation of new HTTP connections.
*/
void QDjangoHttpServer::_q_newTcpConnection()

#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
void QDjangoHttpServer::_q_incomingConnection(qintptr socketDescriptor)
#else
void QDjangoHttpServer::_q_incomingConnection(int socketDescriptor)
#endif
{
bool check;
Q_UNUSED(check);

QTcpSocket *socket;
while ((socket = d->tcpServer->nextPendingConnection()) != 0) {
QDjangoHttpConnection *connection = new QDjangoHttpConnection(socket, this);
#ifdef QDJANGO_DEBUG_HTTP
qDebug("Handling connection %i", d->connectionCount++);
QAbstractSocket *socket;

#ifndef QT_NO_OPENSSL
if (d->ssl)
socket = new QSslSocket(this);
else
#endif
socket = new QTcpSocket(this);

if (!socket->setSocketDescriptor(socketDescriptor)) {
qWarning("HttpConnectionHandler (%p): cannot initialize socket: %s",this, qPrintable(socket->errorString()));
return;
}

check = connect(connection, SIGNAL(closed()),
connection, SLOT(deleteLater()));
Q_ASSERT(check);
#ifndef QT_NO_OPENSSL
if (d->ssl) {
QSslSocket* sslSocket = qobject_cast<QSslSocket*>(socket);

check = connect(connection, SIGNAL(requestFinished(QDjangoHttpRequest*,QDjangoHttpResponse*)),
this, SIGNAL(requestFinished(QDjangoHttpRequest*,QDjangoHttpResponse*)));
Q_ASSERT(check);
foreach (QSslCertificate c, d->sslCaCerts) {
sslSocket->addCaCertificate(c);
}

sslSocket->setProtocol(QSsl::AnyProtocol);
sslSocket->setPrivateKey(d->sslKey);
sslSocket->setLocalCertificate(d->sslCert);
sslSocket->startServerEncryption();
}
#endif

QDjangoHttpConnection *connection = new QDjangoHttpConnection(socket, this);
#ifdef QDJANGO_DEBUG_HTTP
qDebug("Handling connection %i", d->connectionCount++);
#endif

check = connect(connection, SIGNAL(closed()),
connection, SLOT(deleteLater()));
Q_ASSERT(check);

check = connect(connection, SIGNAL(requestFinished(QDjangoHttpRequest*,QDjangoHttpResponse*)),
this, SIGNAL(requestFinished(QDjangoHttpRequest*,QDjangoHttpResponse*)));
Q_ASSERT(check);
}
19 changes: 17 additions & 2 deletions src/http/QDjangoHttpServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

#include <QHostAddress>
#include <QObject>
#ifndef QT_NO_OPENSSL
#include <QSslKey>
#include <QSslSocket>
#endif

#include "QDjangoHttp_p.h"

Expand All @@ -43,6 +47,7 @@ class QDJANGO_EXPORT QDjangoHttpServer : public QObject
{
Q_OBJECT

friend class TcpServer;
public:
QDjangoHttpServer(QObject *parent = 0);
~QDjangoHttpServer();
Expand All @@ -51,13 +56,23 @@ class QDJANGO_EXPORT QDjangoHttpServer : public QObject
bool listen(const QHostAddress &address, quint16 port);
QDjangoUrlResolver *urls() const;

#ifndef QT_NO_OPENSSL
void setupSSL(const QSslKey &sslKey, const QSslCertificate &sslCert, const QList<QSslCertificate> &sslCaCerts = QList<QSslCertificate>());
#endif

quint32 serverPort() const;

signals:
/** This signal is emitted when a request completes.
*/
void requestFinished(QDjangoHttpRequest *request, QDjangoHttpResponse *response);

private slots:
void _q_newTcpConnection();
private:
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
void _q_incomingConnection(qintptr socketDescriptor);
#else
void _q_incomingConnection(int socketDescriptor);
#endif

private:
Q_DISABLE_COPY(QDjangoHttpServer)
Expand Down
6 changes: 3 additions & 3 deletions src/http/QDjangoHttpServer_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
class QDjangoHttpRequest;
class QDjangoHttpResponse;
class QDjangoHttpServer;
class QTcpSocket;
class QAbstractSocket;

typedef QPair<QDjangoHttpRequest*,QDjangoHttpResponse*> QDjangoHttpJob;

Expand All @@ -44,7 +44,7 @@ class QDjangoHttpConnection : public QObject
Q_OBJECT

public:
QDjangoHttpConnection(QTcpSocket *device, QDjangoHttpServer *server);
QDjangoHttpConnection(QAbstractSocket *device, QDjangoHttpServer *server);
~QDjangoHttpConnection();

signals:
Expand All @@ -68,7 +68,7 @@ private slots:
QDjangoHttpRequest *m_pendingRequest;
int m_requestCount;
QDjangoHttpServer *m_server;
QTcpSocket *m_socket;
QAbstractSocket *m_socket;

// request parsing
qint64 m_requestBytesRemaining;
Expand Down