summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp2
-rw-r--r--src/network/access/qhttpnetworkreply_p.h1
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp9
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h2
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp7
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp37
-rw-r--r--src/network/access/qnetworkaccessmanager.h2
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h1
-rw-r--r--src/network/access/qnetworkreply.cpp25
-rw-r--r--src/network/access/qnetworkreply.h1
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp8
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h2
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp8
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h1
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp19
16 files changed, 126 insertions, 0 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 4dfed762f5..4b8fe8aca7 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -1225,6 +1225,8 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
if (!reply)
connection->d_func()->dequeueRequest(socket);
if (reply)
+ emit reply->encrypted();
+ if (reply)
sendRequest();
}
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index e849c66659..7aea9f14ec 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -142,6 +142,7 @@ public:
void ignoreSslErrors(const QList<QSslError> &errors);
Q_SIGNALS:
+ void encrypted();
void sslErrors(const QList<QSslError> &errors);
#endif
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 117265dbfb..a2cee48b22 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -315,6 +315,7 @@ void QHttpThreadDelegate::startRequest()
connect(httpReply,SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
connect(httpReply,SIGNAL(dataReadProgress(qint64,qint64)), this, SLOT(dataReadProgressSlot(qint64,qint64)));
#ifndef QT_NO_SSL
+ connect(httpReply,SIGNAL(encrypted()), this, SLOT(encryptedSlot()));
connect(httpReply,SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrorsSlot(QList<QSslError>)));
#endif
@@ -589,6 +590,14 @@ void QHttpThreadDelegate::cacheCredentialsSlot(const QHttpNetworkRequest &reques
#ifndef QT_NO_SSL
+void QHttpThreadDelegate::encryptedSlot()
+{
+ if (!httpReply)
+ return;
+
+ emit encrypted();
+}
+
void QHttpThreadDelegate::sslErrorsSlot(const QList<QSslError> &errors)
{
if (!httpReply)
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
index 86192c77cc..d9ef1a0a55 100644
--- a/src/network/access/qhttpthreaddelegate_p.h
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -135,6 +135,7 @@ signals:
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
#endif
#ifndef QT_NO_SSL
+ void encrypted();
void sslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
void sslConfigurationChanged(const QSslConfiguration);
#endif
@@ -164,6 +165,7 @@ protected slots:
void dataReadProgressSlot(qint64 done, qint64 total);
void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
#ifndef QT_NO_SSL
+ void encryptedSlot();
void sslErrorsSlot(const QList<QSslError> &errors);
#endif
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 84f9b82a22..a895864d76 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -340,6 +340,13 @@ void QNetworkAccessBackend::redirectionRequested(const QUrl &target)
reply->redirectionRequested(target);
}
+void QNetworkAccessBackend::encrypted()
+{
+#ifndef QT_NO_SSL
+ reply->encrypted();
+#endif
+}
+
void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
{
#ifndef QT_NO_SSL
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index 23f8416e0e..bf284414e0 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -196,6 +196,7 @@ protected slots:
void authenticationRequired(QAuthenticator *auth);
void metaDataChanged();
void redirectionRequested(const QUrl &destination);
+ void encrypted();
void sslErrors(const QList<QSslError> &errors);
void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal);
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index f185f7f695..b83b437b2c 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -374,6 +374,32 @@ static void ensureInitialized()
*/
/*!
+ \fn void QNetworkAccessManager::encrypted(QNetworkReply *reply)
+ \since 5.1
+
+ This signal is emitted when an SSL/TLS session has successfully
+ completed the initial handshake. At this point, no user data
+ has been transmitted. The signal can be used to perform
+ additional checks on the certificate chain, for example to
+ notify users when the certificate for a website has changed. The
+ \a reply parameter specifies which network reply is responsible.
+ If the reply does not match the expected criteria then it should
+ be aborted by calling QNetworkReply::abort() by a slot connected
+ to this signal. The SSL configuration in use can be inspected
+ using the QNetworkReply::sslConfiguration() method.
+
+ Internally, QNetworkAccessManager may open multiple connections
+ to a server, in order to allow it process requests in parallel.
+ These connections may be reused, which means that the encrypted()
+ signal would not be emitted. This means that you are only
+ guaranteed to receive this signal for the first connection to a
+ site in the lifespan of the QNetworkAccessManager.
+
+ \sa QSslSocket::encrypted()
+ \sa QNetworkReply::encrypted()
+*/
+
+/*!
\fn void QNetworkAccessManager::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
This signal is emitted if the SSL/TLS session encountered errors
@@ -1132,6 +1158,16 @@ void QNetworkAccessManagerPrivate::_q_replyFinished()
#endif
}
+void QNetworkAccessManagerPrivate::_q_replyEncrypted()
+{
+#ifndef QT_NO_SSL
+ Q_Q(QNetworkAccessManager);
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
+ if (reply)
+ emit q->encrypted(reply);
+#endif
+}
+
void QNetworkAccessManagerPrivate::_q_replySslErrors(const QList<QSslError> &errors)
{
#ifndef QT_NO_SSL
@@ -1152,6 +1188,7 @@ QNetworkReply *QNetworkAccessManagerPrivate::postProcess(QNetworkReply *reply)
#ifndef QT_NO_SSL
/* In case we're compiled without SSL support, we don't have this signal and we need to
* avoid getting a connection error. */
+ q->connect(reply, SIGNAL(encrypted()), SLOT(_q_replyEncrypted()));
q->connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(_q_replySslErrors(QList<QSslError>)));
#endif
#ifndef QT_NO_BEARERMANAGEMENT
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 0caba127fc..826c8e47d7 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -139,6 +139,7 @@ Q_SIGNALS:
void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator);
void finished(QNetworkReply *reply);
#ifndef QT_NO_SSL
+ void encrypted(QNetworkReply *reply);
void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
#endif
@@ -159,6 +160,7 @@ private:
Q_DECLARE_PRIVATE(QNetworkAccessManager)
Q_PRIVATE_SLOT(d_func(), void _q_replyFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_replyEncrypted())
Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>))
#ifndef QT_NO_BEARERMANAGEMENT
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed())
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index b4ad3511fa..cf756dad7b 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -90,6 +90,7 @@ public:
~QNetworkAccessManagerPrivate();
void _q_replyFinished();
+ void _q_replyEncrypted();
void _q_replySslErrors(const QList<QSslError> &errors);
QNetworkReply *postProcess(QNetworkReply *reply);
void createCookieJar() const;
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index fd3b7760cb..dc42adc612 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -195,6 +195,31 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
*/
/*!
+ \fn void QNetworkReply::encrypted()
+ \since 5.1
+
+ This signal is emitted when an SSL/TLS session has successfully
+ completed the initial handshake. At this point, no user data
+ has been transmitted. The signal can be used to perform
+ additional checks on the certificate chain, for example to
+ notify users when the certificate for a website has changed.
+ If the reply does not match the expected criteria then it should
+ be aborted by calling QNetworkReply::abort() by a slot connected
+ to this signal. The SSL configuration in use can be inspected
+ using the QNetworkReply::sslConfiguration() method.
+
+ Internally, QNetworkAccessManager may open multiple connections
+ to a server, in order to allow it process requests in parallel.
+ These connections may be reused, which means that the encrypted()
+ signal would not be emitted. This means that you are only
+ guaranteed to receive this signal for the first connection to a
+ site in the lifespan of the QNetworkAccessManager.
+
+ \sa QSslSocket::encrypted()
+ \sa QNetworkAccessManager::encrypted()
+*/
+
+/*!
\fn void QNetworkReply::sslErrors(const QList<QSslError> &errors)
This signal is emitted if the SSL/TLS session encountered errors
diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h
index 39901aafb6..a7db2d189c 100644
--- a/src/network/access/qnetworkreply.h
+++ b/src/network/access/qnetworkreply.h
@@ -148,6 +148,7 @@ Q_SIGNALS:
void finished();
void error(QNetworkReply::NetworkError);
#ifndef QT_NO_SSL
+ void encrypted();
void sslErrors(const QList<QSslError> &errors);
#endif
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 522965c104..c04421e5c7 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -830,6 +830,8 @@ void QNetworkReplyHttpImplPrivate::postRequest()
Qt::BlockingQueuedConnection);
#endif
#ifndef QT_NO_SSL
+ QObject::connect(delegate, SIGNAL(encrypted()), q, SLOT(replyEncrypted()),
+ Qt::BlockingQueuedConnection);
QObject::connect(delegate, SIGNAL(sslErrors(QList<QSslError>,bool*,QList<QSslError>*)),
q, SLOT(replySslErrors(QList<QSslError>,bool*,QList<QSslError>*)),
Qt::BlockingQueuedConnection);
@@ -1220,6 +1222,12 @@ void QNetworkReplyHttpImplPrivate::httpError(QNetworkReply::NetworkError errorCo
}
#ifndef QT_NO_SSL
+void QNetworkReplyHttpImplPrivate::replyEncrypted()
+{
+ Q_Q(QNetworkReplyHttpImpl);
+ emit q->encrypted();
+}
+
void QNetworkReplyHttpImplPrivate::replySslErrors(
const QList<QSslError> &list, bool *ignoreAll, QList<QSslError> *toBeIgnored)
{
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index 5f8f0badf7..15cc0ec476 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -116,6 +116,7 @@ public:
Q_PRIVATE_SLOT(d_func(), void httpAuthenticationRequired(const QHttpNetworkRequest &, QAuthenticator *))
Q_PRIVATE_SLOT(d_func(), void httpError(QNetworkReply::NetworkError, const QString &))
#ifndef QT_NO_SSL
+ Q_PRIVATE_SLOT(d_func(), void replyEncrypted())
Q_PRIVATE_SLOT(d_func(), void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *))
Q_PRIVATE_SLOT(d_func(), void replySslConfigurationChanged(const QSslConfiguration&))
#endif
@@ -280,6 +281,7 @@ public:
void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
void httpError(QNetworkReply::NetworkError error, const QString &errorString);
#ifndef QT_NO_SSL
+ void replyEncrypted();
void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
void replySslConfigurationChanged(const QSslConfiguration&);
#endif
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index e12286c459..33357293a3 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -879,6 +879,14 @@ void QNetworkReplyImplPrivate::redirectionRequested(const QUrl &target)
attributes.insert(QNetworkRequest::RedirectionTargetAttribute, target);
}
+void QNetworkReplyImplPrivate::encrypted()
+{
+#ifndef QT_NO_SSL
+ Q_Q(QNetworkReplyImpl);
+ emit q->encrypted();
+#endif
+}
+
void QNetworkReplyImplPrivate::sslErrors(const QList<QSslError> &errors)
{
#ifndef QT_NO_SSL
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index ca9a3b5fd1..9edc0f6b59 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -176,6 +176,7 @@ public:
void error(QNetworkReply::NetworkError code, const QString &errorString);
void metaDataChanged();
void redirectionRequested(const QUrl &target);
+ void encrypted();
void sslErrors(const QList<QSslError> &errors);
QNetworkAccessBackend *backend;
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 4847dedac4..bcc0641973 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -361,6 +361,7 @@ private Q_SLOTS:
void ignoreSslErrorsList();
void ignoreSslErrorsListWithSlot_data();
void ignoreSslErrorsListWithSlot();
+ void encrypted();
void sslConfiguration_data();
void sslConfiguration();
#ifdef QT_BUILD_INTERNAL
@@ -5867,6 +5868,24 @@ void tst_QNetworkReply::sslConfiguration_data()
QTest::newRow("secure") << conf << true;
}
+void tst_QNetworkReply::encrypted()
+{
+ qDebug() << QtNetworkSettings::serverName();
+ QUrl url("https://" + QtNetworkSettings::serverName());
+ QNetworkRequest request(url);
+ QNetworkReply *reply = manager.get(request);
+ reply->ignoreSslErrors();
+
+ QSignalSpy spy(reply, SIGNAL(encrypted()));
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ QTestEventLoop::instance().enterLoop(20);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(spy.count(), 1);
+
+ reply->deleteLater();
+}
+
void tst_QNetworkReply::sslConfiguration()
{
QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/index.html"));