diff --git a/src/http/qhttp/private/qhttpclient_private.hpp b/src/http/qhttp/private/qhttpclient_private.hpp index 7b757ccfc..c51c9bbac 100644 --- a/src/http/qhttp/private/qhttpclient_private.hpp +++ b/src/http/qhttp/private/qhttpclient_private.hpp @@ -78,6 +78,9 @@ public: if ( isocket.ibackendType == ETcpSocket ) { initTcpSocket(); + } else if ( isocket.ibackendType == ESslSocket ) { + initSslSocket(); + } else if ( isocket.ibackendType == ELocalSocket ) { initLocalSocket(); } @@ -86,7 +89,7 @@ public: public: int messageBegin(http_parser* parser); int url(http_parser*, const char*, size_t) { - return 0; // not used in parsing incoming respone. + return 0; // not used in parsing incoming response. } int status(http_parser* parser, const char* at, size_t length) ; int headerField(http_parser* parser, const char* at, size_t length); @@ -112,7 +115,7 @@ protected: while ( isocket.bytesAvailable() > 0 ) { char buffer[4097] = {0}; size_t readLength = (size_t) isocket.readRaw(buffer, 4096); - + parse(buffer, readLength); } } @@ -152,6 +155,31 @@ private: ); } + void initSslSocket() { + QSslSocket* sok = new QSslSocket(q_func()); + isocket.itcpSocket = sok; + + QObject::connect( + sok, &QSslSocket::encrypted, + [this](){ onConnected(); } + ); + QObject::connect( + sok, &QSslSocket::readyRead, + [this](){ onReadyRead(); } + ); + QObject::connect( + sok, &QSslSocket::bytesWritten, + [this](qint64){ + const auto& ts = isocket.itcpSocket; + if ( ts->bytesToWrite() == 0 && ilastRequest ) + emit ilastRequest->allBytesWritten(); + }); + QObject::connect( + sok, &QSslSocket::disconnected, + q_func(), &QHttpClient::disconnected + ); + } + void initLocalSocket() { QLocalSocket* sok = new QLocalSocket(q_func()); isocket.ilocalSocket = sok; diff --git a/src/http/qhttp/private/qhttpserver_private.hpp b/src/http/qhttp/private/qhttpserver_private.hpp index ff9a1ec66..93c96d2e1 100644 --- a/src/http/qhttp/private/qhttpserver_private.hpp +++ b/src/http/qhttp/private/qhttpserver_private.hpp @@ -70,7 +70,7 @@ public: void initialize(TBackend backend, QHttpServer* parent) { ibackend = backend; - if ( ibackend == ETcpSocket ) { + if ( ibackend == ETcpSocket || ibackend == ESslSocket ) { itcpServer.reset( new BackendServer(parent) ); ilocalServer.reset( nullptr ); diff --git a/src/http/qhttp/private/qhttpserverconnection_private.hpp b/src/http/qhttp/private/qhttpserverconnection_private.hpp index 879881c50..fd4475864 100644 --- a/src/http/qhttp/private/qhttpserverconnection_private.hpp +++ b/src/http/qhttp/private/qhttpserverconnection_private.hpp @@ -49,6 +49,9 @@ public: if ( bend == ETcpSocket ) { initTcpSocket(sokDesc); + + } else if ( bend == ESslSocket) { + initSslSocket(sokDesc); } else if ( bend == ELocalSocket ) { initLocalSocket(sokDesc); @@ -130,6 +133,29 @@ private: Qt::QueuedConnection ); } + + void initSslSocket(qintptr sokDesc) { + QSslSocket* sok = new QSslSocket( q_func() ); + isocket.itcpSocket = sok; + sok->setSocketDescriptor(sokDesc); + + QObject::connect( + sok, &QSslSocket::readyRead, + [this](){ onReadyRead(); } + ); + QObject::connect( + sok, &QSslSocket::bytesWritten, + [this](){ + auto btw = isocket.itcpSocket->bytesToWrite(); + if ( btw == 0 && ilastResponse ) + emit ilastResponse->allBytesWritten(); + }); + QObject::connect( + sok, &QSslSocket::disconnected, + q_func(), &QHttpConnection::disconnected, + Qt::QueuedConnection + ); + } void initLocalSocket(qintptr sokDesc) { QLocalSocket* sok = new QLocalSocket( q_func() ); diff --git a/src/http/qhttp/private/qsocket.hpp b/src/http/qhttp/private/qsocket.hpp index 11b3082c9..cfda9e60e 100644 --- a/src/http/qhttp/private/qsocket.hpp +++ b/src/http/qhttp/private/qsocket.hpp @@ -13,6 +13,7 @@ #include "qhttpfwd.hpp" #include +#include #include #include /////////////////////////////////////////////////////////////////////////////// @@ -73,8 +74,12 @@ public: } void connectTo(const QString& host, quint16 port) { - if ( itcpSocket ) - itcpSocket->connectToHost(host, port); + if ( itcpSocket ) { + if ( ibackendType == ESslSocket ) + static_cast(itcpSocket)->connectToHostEncrypted(host, port); + else + itcpSocket->connectToHost(host, port); + } } qint64 readRaw(char* buffer, int maxlen) { @@ -88,8 +93,9 @@ public: } void writeRaw(const QByteArray& data) { - if ( itcpSocket ) + if ( itcpSocket ) { itcpSocket->write(data); + } else if ( ilocalSocket ) ilocalSocket->write(data); diff --git a/src/http/qhttp/qhttpclient.cpp b/src/http/qhttp/qhttpclient.cpp index 86de8c37a..b77645ecf 100644 --- a/src/http/qhttp/qhttpclient.cpp +++ b/src/http/qhttp/qhttpclient.cpp @@ -127,7 +127,9 @@ QHttpClient::request(THttpMethod method, QUrl url, d->isocket.connectTo(url); } else { - d->isocket.ibackendType = ETcpSocket; + bool ssl = url.scheme() == "https"; + + d->isocket.ibackendType = ssl ? ESslSocket : ETcpSocket; d->initializeSocket(); requestCreator(); @@ -135,7 +137,7 @@ QHttpClient::request(THttpMethod method, QUrl url, if ( d->isocket.isOpen() ) d->onConnected(); else - d->isocket.connectTo(url.host(), url.port(80)); + d->isocket.connectTo(url.host(), url.port(ssl ? 443 : 80)); } return true; diff --git a/src/http/qhttp/qhttpclient.hpp b/src/http/qhttp/qhttpclient.hpp index 38119fdbc..f73e7b7fc 100644 --- a/src/http/qhttp/qhttpclient.hpp +++ b/src/http/qhttp/qhttpclient.hpp @@ -13,6 +13,7 @@ #include "qhttpfwd.hpp" #include +#include #include /////////////////////////////////////////////////////////////////////////////// diff --git a/src/http/qhttp/qhttpfwd.hpp b/src/http/qhttp/qhttpfwd.hpp index f29059307..d6f38db8b 100644 --- a/src/http/qhttp/qhttpfwd.hpp +++ b/src/http/qhttp/qhttpfwd.hpp @@ -151,7 +151,7 @@ enum TStatusCode { /** The backend of QHttp library. */ enum TBackend { ETcpSocket = 0, ///< client / server work on top of TCP/IP stack. (default) - ESslSocket = 1, ///< client / server work on SSL/TLS tcp stack. (not implemented yet) + ESslSocket = 1, ///< client / server work on SSL/TLS tcp stack. ELocalSocket = 2 ///< client / server work on local socket (unix socket). }; diff --git a/src/http/qhttp/qhttpserver.cpp b/src/http/qhttp/qhttpserver.cpp index fb126ec17..a9c6a082c 100644 --- a/src/http/qhttp/qhttpserver.cpp +++ b/src/http/qhttp/qhttpserver.cpp @@ -35,7 +35,7 @@ bool QHttpServer::listen(const QHostAddress& address, quint16 port, const qhttp::server::TServerHandler& handler) { Q_D(QHttpServer); - d->initialize(ETcpSocket, this); + d->initialize(d->ibackend, this); d->ihandler = handler; return d->itcpServer->listen(address, port); } @@ -44,10 +44,10 @@ bool QHttpServer::isListening() const { const Q_D(QHttpServer); - if ( d->ibackend == ETcpSocket && d->itcpServer ) + if ( ( d->ibackend == ETcpSocket || d->ibackend == ESslSocket ) && d->itcpServer ) return d->itcpServer->isListening(); - else if ( d->ibackend == ELocalSocket && d->ilocalServer ) + else if ( d->ibackend == ELocalSocket && d->ilocalServer ) return d->ilocalServer->isListening(); return false; diff --git a/src/http/qhttp/qhttpserverconnection.cpp b/src/http/qhttp/qhttpserverconnection.cpp index b950c4787..7345c83be 100644 --- a/src/http/qhttp/qhttpserverconnection.cpp +++ b/src/http/qhttp/qhttpserverconnection.cpp @@ -147,7 +147,7 @@ QHttpConnectionPrivate::headersComplete(http_parser* parser) { ); // set client information - if ( isocket.ibackendType == ETcpSocket ) { + if ( isocket.ibackendType == ETcpSocket || isocket.ibackendType == ESslSocket ) { ilastRequest->d_func()->iremoteAddress = isocket.itcpSocket->peerAddress().toString(); ilastRequest->d_func()->iremotePort = isocket.itcpSocket->peerPort();