101 lines
4.6 KiB
Diff
101 lines
4.6 KiB
Diff
From 29618d33243783725bb601ff8d9bd263309f4f32 Mon Sep 17 00:00:00 2001
|
|
From: Vladimir Prus <vladimir.prus@gmail.com>
|
|
Date: Fri, 20 Nov 2015 11:20:02 +0300
|
|
Subject: [PATCH] Make sure SSL configuration is correct in
|
|
QNetworkReply::encrypted.
|
|
|
|
In some cases, when QNetworkReply::encrypted is emitted,
|
|
QNetworkReply::sslConfiguration is not yet initialized, in particular
|
|
certificate chain is empty, which breaks the documented usage of
|
|
'encrypted' to perform additional checks on certificate chain.
|
|
|
|
It looks to be caused by the fact that QHttpNetworkReply is originally
|
|
associated with 0th QHttpNetworkConnectionChannel, and this association
|
|
is not updated if HTTP pipelining is not used. Therefore, a reply on
|
|
channel >0 might arrive before reply on channel 0, and then using ssl
|
|
configuration from channel 0, which not made it through handshake, is
|
|
not usable.
|
|
|
|
Task-number: QTBUG-49554
|
|
Change-Id: Ie5d4b5a0c503d5bdc44761ce8581f6ffe4e3bac2
|
|
---
|
|
src/network/access/qhttpnetworkconnection.cpp | 15 +++++++++++----
|
|
src/network/access/qhttpnetworkconnection_p.h | 1 +
|
|
src/network/access/qhttpnetworkconnectionchannel.cpp | 3 +--
|
|
3 files changed, 13 insertions(+), 6 deletions(-)
|
|
|
|
diff --git x/qtbase/src/network/access/qhttpnetworkconnection.cpp y/qtbase/src/network/access/qhttpnetworkconnection.cpp
|
|
index 79f418f..7f07403 100644
|
|
--- x/qtbase/src/network/access/qhttpnetworkconnection.cpp
|
|
+++ y/qtbase/src/network/access/qhttpnetworkconnection.cpp
|
|
@@ -674,8 +674,7 @@ bool QHttpNetworkConnectionPrivate::dequeueRequest(QAbstractSocket *socket)
|
|
HttpMessagePair messagePair = highPriorityQueue.takeLast();
|
|
if (!messagePair.second->d_func()->requestIsPrepared)
|
|
prepareRequest(messagePair);
|
|
- channels[i].request = messagePair.first;
|
|
- channels[i].reply = messagePair.second;
|
|
+ updateChannel(i, messagePair);
|
|
return true;
|
|
}
|
|
|
|
@@ -684,13 +683,21 @@ bool QHttpNetworkConnectionPrivate::dequeueRequest(QAbstractSocket *socket)
|
|
HttpMessagePair messagePair = lowPriorityQueue.takeLast();
|
|
if (!messagePair.second->d_func()->requestIsPrepared)
|
|
prepareRequest(messagePair);
|
|
- channels[i].request = messagePair.first;
|
|
- channels[i].reply = messagePair.second;
|
|
+ updateChannel(i, messagePair);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
+void QHttpNetworkConnectionPrivate::updateChannel(int i, const HttpMessagePair &messagePair)
|
|
+{
|
|
+ channels[i].request = messagePair.first;
|
|
+ channels[i].reply = messagePair.second;
|
|
+ // Now that reply is assigned a channel, correct reply to channel association
|
|
+ // previously set in queueRequest.
|
|
+ channels[i].reply->d_func()->connectionChannel = &channels[i];
|
|
+}
|
|
+
|
|
QHttpNetworkRequest QHttpNetworkConnectionPrivate::predictNextRequest() const
|
|
{
|
|
if (!highPriorityQueue.isEmpty())
|
|
diff --git x/qtbase/src/network/access/qhttpnetworkconnection_p.h y/qtbase/src/network/access/qhttpnetworkconnection_p.h
|
|
index e05bc1d..df71425 100644
|
|
--- x/qtbase/src/network/access/qhttpnetworkconnection_p.h
|
|
+++ y/qtbase/src/network/access/qhttpnetworkconnection_p.h
|
|
@@ -213,6 +213,7 @@ public:
|
|
void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke
|
|
bool dequeueRequest(QAbstractSocket *socket);
|
|
void prepareRequest(HttpMessagePair &request);
|
|
+ void updateChannel(int i, const HttpMessagePair &messagePair);
|
|
QHttpNetworkRequest predictNextRequest() const;
|
|
|
|
void fillPipeline(QAbstractSocket *socket);
|
|
diff --git x/qtbase/src/network/access/qhttpnetworkconnectionchannel.cpp y/qtbase/src/network/access/qhttpnetworkconnectionchannel.cpp
|
|
index 56716cb..8e0e88d 100644
|
|
--- x/qtbase/src/network/access/qhttpnetworkconnectionchannel.cpp
|
|
+++ y/qtbase/src/network/access/qhttpnetworkconnectionchannel.cpp
|
|
@@ -1076,6 +1076,7 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
|
|
connection->d_func()->dequeueRequest(socket);
|
|
if (reply) {
|
|
reply->setSpdyWasUsed(false);
|
|
+ Q_ASSERT(reply->d_func()->connectionChannel == this);
|
|
emit reply->encrypted();
|
|
}
|
|
if (reply)
|
|
@@ -1115,8 +1116,6 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors)
|
|
connection->d_func()->pauseConnection();
|
|
if (pendingEncrypt && !reply)
|
|
connection->d_func()->dequeueRequest(socket);
|
|
- if (reply) // a reply was actually dequeued.
|
|
- reply->d_func()->connectionChannel = this; // set correct channel like in sendRequest() and queueRequest();
|
|
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP) {
|
|
if (reply)
|
|
emit reply->sslErrors(errors);
|
|
--
|
|
2.10.0
|
|
|