From b5652df775efbd1c52eecee5f08e40e600e5d70b Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Fri, 21 Dec 2012 14:02:38 +0100 Subject: SSL: Implement session sharing and use it from QNetworkAccessManager This improves performance since a network round trip can be avoided. Change-Id: I1aaff7e48ef9638cb137de0f43942c3a4dd2884a Initial-patch-by: Markus Goetz Reviewed-by: Richard J. Moore --- src/network/access/qhttpnetworkconnection.cpp | 12 ++++++++++++ src/network/access/qhttpnetworkconnection_p.h | 9 +++++++++ src/network/access/qhttpnetworkconnectionchannel.cpp | 19 ++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) (limited to 'src/network/access') diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index eec5cfa96d..509f8b3251 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1224,6 +1224,18 @@ void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config d->channels[i].setSslConfiguration(config); } +QSharedPointer QHttpNetworkConnection::sslContext() +{ + Q_D(QHttpNetworkConnection); + return d->sslContext; +} + +void QHttpNetworkConnection::setSslContext(QSharedPointer context) +{ + Q_D(QHttpNetworkConnection); + d->sslContext = context; +} + void QHttpNetworkConnection::ignoreSslErrors(int channel) { Q_D(QHttpNetworkConnection); diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 57d40bfcf2..956499ddab 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -72,6 +73,8 @@ #ifndef QT_NO_HTTP #ifndef QT_NO_SSL +# include +# include # include # include #else @@ -124,6 +127,8 @@ public: void setSslConfiguration(const QSslConfiguration &config); void ignoreSslErrors(int channel = -1); void ignoreSslErrors(const QList &errors, int channel = -1); + QSharedPointer sslContext(); + void setSslContext(QSharedPointer context); #endif private: @@ -234,6 +239,10 @@ public: QList highPriorityQueue; QList lowPriorityQueue; +#ifndef QT_NO_SSL + QSharedPointer sslContext; +#endif + #ifndef QT_NO_BEARERMANAGEMENT QSharedPointer networkSession; #endif diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 38723a7032..4dfed762f5 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -622,6 +622,13 @@ bool QHttpNetworkConnectionChannel::ensureConnection() if (ssl) { #ifndef QT_NO_SSL QSslSocket *sslSocket = qobject_cast(socket); + + // check whether we can re-use an existing SSL session + // (meaning another socket in this connection has already + // performed a full handshake) + if (!connection->sslContext().isNull()) + QSslSocketPrivate::checkSettingSslContext(sslSocket, connection->sslContext()); + sslSocket->connectToHostEncrypted(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference); if (ignoreAllSslErrors) sslSocket->ignoreSslErrors(); @@ -1065,7 +1072,17 @@ void QHttpNetworkConnectionChannel::_q_connected() // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! //channels[i].reconnectAttempts = 2; - if (!pendingEncrypt) { + if (pendingEncrypt) { +#ifndef QT_NO_SSL + if (connection->sslContext().isNull()) { + // this socket is making the 1st handshake for this connection, + // we need to set the SSL context so new sockets can reuse it + QSharedPointer socketSslContext = QSslSocketPrivate::sslContext(static_cast(socket)); + if (!socketSslContext.isNull()) + connection->setSslContext(socketSslContext); + } +#endif + } else { state = QHttpNetworkConnectionChannel::IdleState; if (!reply) connection->d_func()->dequeueRequest(socket); -- cgit v1.2.3