summaryrefslogtreecommitdiffstats
path: root/src/network/access/qhttpnetworkconnectionchannel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/access/qhttpnetworkconnectionchannel.cpp')
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp220
1 files changed, 106 insertions, 114 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index ba05e75794..6766989690 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -1,49 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qhttpnetworkconnectionchannel_p.h"
#include "qhttpnetworkconnection_p.h"
#include "qhttp2configuration.h"
#include "private/qnoncontiguousbytedevice_p.h"
-#include <qpair.h>
#include <qdebug.h>
#include <private/qhttp2protocolhandler_p.h>
@@ -58,6 +21,9 @@
#include "private/qnetconmonitor_p.h"
+#include <memory>
+#include <utility>
+
QT_BEGIN_NAMESPACE
namespace
@@ -74,7 +40,7 @@ private:
}
-// TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp
+// TODO: Put channel specific stuff here so it does not pollute qhttpnetworkconnection.cpp
// Because in-flight when sending a request, the server might close our connection (because the persistent HTTP
// connection times out)
@@ -93,8 +59,6 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
, lastStatus(0)
, pendingEncrypt(false)
, reconnectAttempts(reconnectAttemptsDefault)
- , authMethod(QAuthenticatorPrivate::None)
- , proxyAuthMethod(QAuthenticatorPrivate::None)
, authenticationCredentialsSent(false)
, proxyCredentialsSent(false)
, protocolHandler(nullptr)
@@ -244,7 +208,7 @@ void QHttpNetworkConnectionChannel::abort()
bool QHttpNetworkConnectionChannel::sendRequest()
{
- Q_ASSERT(!protocolHandler.isNull());
+ Q_ASSERT(protocolHandler);
return protocolHandler->sendRequest();
}
@@ -257,7 +221,7 @@ bool QHttpNetworkConnectionChannel::sendRequest()
void QHttpNetworkConnectionChannel::sendRequestDelayed()
{
QMetaObject::invokeMethod(this, [this] {
- Q_ASSERT(!protocolHandler.isNull());
+ Q_ASSERT(protocolHandler);
if (reply)
protocolHandler->sendRequest();
}, Qt::ConnectionType::QueuedConnection);
@@ -265,13 +229,13 @@ void QHttpNetworkConnectionChannel::sendRequestDelayed()
void QHttpNetworkConnectionChannel::_q_receiveReply()
{
- Q_ASSERT(!protocolHandler.isNull());
+ Q_ASSERT(protocolHandler);
protocolHandler->_q_receiveReply();
}
void QHttpNetworkConnectionChannel::_q_readyRead()
{
- Q_ASSERT(!protocolHandler.isNull());
+ Q_ASSERT(protocolHandler);
protocolHandler->_q_readyRead();
}
@@ -358,6 +322,13 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
QString connectHost = connection->d_func()->hostName;
quint16 connectPort = connection->d_func()->port;
+ QHttpNetworkReply *potentialReply = connection->d_func()->predictNextRequestsReply();
+ if (potentialReply) {
+ QMetaObject::invokeMethod(potentialReply, "socketStartedConnecting", Qt::QueuedConnection);
+ } else if (!h2RequestsToSend.isEmpty()) {
+ QMetaObject::invokeMethod(std::as_const(h2RequestsToSend).first().second, "socketStartedConnecting", Qt::QueuedConnection);
+ }
+
#ifndef QT_NO_NETWORKPROXY
// HTTPS always use transparent proxy.
if (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy && !ssl) {
@@ -367,11 +338,20 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
if (socket->proxy().type() == QNetworkProxy::HttpProxy) {
// Make user-agent field available to HTTP proxy socket engine (QTBUG-17223)
QByteArray value;
- // ensureConnection is called before any request has been assigned, but can also be called again if reconnecting
- if (request.url().isEmpty())
- value = connection->d_func()->predictNextRequest().headerField("user-agent");
- else
+ // ensureConnection is called before any request has been assigned, but can also be
+ // called again if reconnecting
+ if (request.url().isEmpty()) {
+ if (connection->connectionType()
+ == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
+ || (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
+ && !h2RequestsToSend.isEmpty())) {
+ value = std::as_const(h2RequestsToSend).first().first.headerField("user-agent");
+ } else {
+ value = connection->d_func()->predictNextRequest().headerField("user-agent");
+ }
+ } else {
value = request.headerField("user-agent");
+ }
if (!value.isEmpty()) {
QNetworkProxy proxy(socket->proxy());
proxy.setRawHeader("User-Agent", value); //detaches
@@ -386,8 +366,8 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
// 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());
+ if (auto ctx = connection->sslContext())
+ QSslSocketPrivate::checkSettingSslContext(sslSocket, std::move(ctx));
sslSocket->setPeerVerifyName(connection->d_func()->peerVerifyName);
sslSocket->connectToHostEncrypted(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference);
@@ -464,18 +444,18 @@ void QHttpNetworkConnectionChannel::allDone()
// trick with ProtocolHandlerDeleter, a QObject-derived class.
// These dances below just make it somewhat exception-safe.
// 1. Create a new owner:
- QAbstractProtocolHandler *oldHandler = protocolHandler.data();
- QScopedPointer<ProtocolHandlerDeleter> deleter(new ProtocolHandlerDeleter(oldHandler));
+ QAbstractProtocolHandler *oldHandler = protocolHandler.get();
+ auto deleter = std::make_unique<ProtocolHandlerDeleter>(oldHandler);
// 2. Retire the old one:
- protocolHandler.take();
+ Q_UNUSED(protocolHandler.release());
// 3. Call 'deleteLater':
deleter->deleteLater();
// 3. Give up the ownerthip:
- deleter.take();
+ Q_UNUSED(deleter.release());
connection->fillHttp2Queue();
protocolHandler.reset(new QHttp2ProtocolHandler(this));
- QHttp2ProtocolHandler *h2c = static_cast<QHttp2ProtocolHandler *>(protocolHandler.data());
+ QHttp2ProtocolHandler *h2c = static_cast<QHttp2ProtocolHandler *>(protocolHandler.get());
QMetaObject::invokeMethod(h2c, "_q_receiveReply", Qt::QueuedConnection);
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
// If we only had one request sent with H2 allowed, we may fail to send
@@ -570,7 +550,7 @@ void QHttpNetworkConnectionChannel::detectPipeliningSupport()
QByteArray serverHeaderField;
if (
// check for HTTP/1.1
- (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1)
+ (reply->majorVersion() == 1 && reply->minorVersion() == 1)
// check for not having connection close
&& (!reply->d_func()->isConnectionCloseEnabled())
// check if it is still connected
@@ -593,7 +573,7 @@ void QHttpNetworkConnectionChannel::detectPipeliningSupport()
// called when the connection broke and we need to queue some pipelined requests again
void QHttpNetworkConnectionChannel::requeueCurrentlyPipelinedRequests()
{
- for (int i = 0; i < alreadyPipelinedRequests.length(); i++)
+ for (int i = 0; i < alreadyPipelinedRequests.size(); i++)
connection->d_func()->requeueRequest(alreadyPipelinedRequests.at(i));
alreadyPipelinedRequests.clear();
@@ -678,17 +658,19 @@ bool QHttpNetworkConnectionChannel::resetUploadData()
//this happens if server closes connection while QHttpNetworkConnectionPrivate::_q_startNextRequest is pending
return false;
}
- QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
- if (!uploadByteDevice)
- return true;
-
- if (uploadByteDevice->reset()) {
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
+ || switchedToHttp2) {
+ // The else branch doesn't make any sense for HTTP/2, since 1 channel is multiplexed into
+ // many streams. And having one stream fail to reset upload data should not completely close
+ // the channel. Handled in the http2 protocol handler.
+ } else if (QNonContiguousByteDevice *uploadByteDevice = request.uploadByteDevice()) {
+ if (!uploadByteDevice->reset()) {
+ connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ContentReSendError);
+ return false;
+ }
written = 0;
- return true;
- } else {
- connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ContentReSendError);
- return false;
}
+ return true;
}
#ifndef QT_NO_NETWORKPROXY
@@ -847,7 +829,7 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
state = QHttpNetworkConnectionChannel::IdleState;
- if (alreadyPipelinedRequests.length()) {
+ if (alreadyPipelinedRequests.size()) {
// If nothing was in a pipeline, no need in calling
// _q_startNextRequest (which it does):
requeueCurrentlyPipelinedRequests();
@@ -874,9 +856,14 @@ void QHttpNetworkConnectionChannel::_q_connected()
connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
}
connection->d_func()->networkLayerDetected(networkLayerPreference);
+ if (connection->d_func()->activeChannelCount > 1 && !connection->d_func()->encrypt)
+ QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
} else {
- if (((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv4) && (networkLayerPreference != QAbstractSocket::IPv4Protocol))
- || ((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv6) && (networkLayerPreference != QAbstractSocket::IPv6Protocol))) {
+ bool anyProtocol = networkLayerPreference == QAbstractSocket::AnyIPProtocol;
+ if (((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv4)
+ && (networkLayerPreference != QAbstractSocket::IPv4Protocol && !anyProtocol))
+ || ((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv6)
+ && (networkLayerPreference != QAbstractSocket::IPv6Protocol && !anyProtocol))) {
close();
// This is the second connection so it has to be closed and we can schedule it for another request.
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
@@ -899,7 +886,7 @@ void QHttpNetworkConnectionChannel::_q_connected()
pipeliningSupported = QHttpNetworkConnectionChannel::PipeliningSupportUnknown;
- if (QNetworkStatusMonitor::isEnabled()) {
+ if (QNetworkConnectionMonitor::isEnabled()) {
auto connectionPrivate = connection->d_func();
if (!connectionPrivate->connectionMonitor.isMonitoring()) {
// Now that we have a pair of addresses, we can start monitoring the
@@ -913,18 +900,17 @@ void QHttpNetworkConnectionChannel::_q_connected()
//channels[i].reconnectAttempts = 2;
if (ssl || pendingEncrypt) { // FIXME: Didn't work properly with pendingEncrypt only, we should refactor this into an EncrypingState
#ifndef QT_NO_SSL
- if (connection->sslContext().isNull()) {
+ if (!connection->sslContext()) {
// this socket is making the 1st handshake for this connection,
// we need to set the SSL context so new sockets can reuse it
- QSharedPointer<QSslContext> socketSslContext = QSslSocketPrivate::sslContext(static_cast<QSslSocket*>(socket));
- if (!socketSslContext.isNull())
- connection->setSslContext(socketSslContext);
+ if (auto socketSslContext = QSslSocketPrivate::sslContext(static_cast<QSslSocket*>(socket)))
+ connection->setSslContext(std::move(socketSslContext));
}
#endif
} else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
state = QHttpNetworkConnectionChannel::IdleState;
protocolHandler.reset(new QHttp2ProtocolHandler(this));
- if (h2RequestsToSend.count() > 0) {
+ if (h2RequestsToSend.size() > 0) {
// In case our peer has sent us its settings (window size, max concurrent streams etc.)
// let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
@@ -965,6 +951,10 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
break;
case QAbstractSocket::ConnectionRefusedError:
errorCode = QNetworkReply::ConnectionRefusedError;
+#ifndef QT_NO_NETWORKPROXY
+ if (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy && !ssl)
+ errorCode = QNetworkReply::ProxyConnectionRefusedError;
+#endif
break;
case QAbstractSocket::RemoteHostClosedError:
// This error for SSL comes twice in a row, first from SSL layer ("The TLS/SSL connection has been closed") then from TCP layer.
@@ -977,12 +967,12 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
// we do not resend, but must report errors if any request is in progress (note, while
// not in its sendRequest(), protocol handler switches the channel to IdleState, thus
// this check is under this condition in 'if'):
- if (protocolHandler.data()) {
+ if (protocolHandler) {
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
- || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
- auto h2Handler = static_cast<QHttp2ProtocolHandler *>(protocolHandler.data());
+ || (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
+ && switchedToHttp2)) {
+ auto h2Handler = static_cast<QHttp2ProtocolHandler *>(protocolHandler.get());
h2Handler->handleConnectionClosure();
- protocolHandler.reset();
}
}
return;
@@ -1046,6 +1036,9 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
}
errorCode = QNetworkReply::TimeoutError;
break;
+ case QAbstractSocket::ProxyConnectionRefusedError:
+ errorCode = QNetworkReply::ProxyConnectionRefusedError;
+ break;
case QAbstractSocket::ProxyAuthenticationRequiredError:
errorCode = QNetworkReply::ProxyAuthenticationRequiredError;
break;
@@ -1103,10 +1096,12 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
|| connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
- QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
- for (int a = 0; a < h2Pairs.count(); ++a) {
+ const auto h2RequestsToSendCopy = std::exchange(h2RequestsToSend, {});
+ for (const auto &httpMessagePair : h2RequestsToSendCopy) {
// emit error for all replies
- QHttpNetworkReply *currentReply = h2Pairs.at(a).second;
+ QHttpNetworkReply *currentReply = httpMessagePair.second;
+ currentReply->d_func()->errorString = errorString;
+ currentReply->d_func()->httpErrorCode = errorCode;
Q_ASSERT(currentReply);
emit currentReply->finishedWithError(errorCode, errorString);
}
@@ -1132,9 +1127,10 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
#ifndef QT_NO_NETWORKPROXY
void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth)
{
- if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
+ if ((connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
+ && (switchedToHttp2 || h2RequestsToSend.size() > 0))
|| connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
- if (h2RequestsToSend.count() > 0)
+ if (h2RequestsToSend.size() > 0)
connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth);
} else { // HTTP
// Need to dequeue the request before we can emit the error.
@@ -1157,9 +1153,9 @@ void QHttpNetworkConnectionChannel::emitFinishedWithError(QNetworkReply::Network
{
if (reply)
emit reply->finishedWithError(error, QHttpNetworkConnectionChannel::tr(message));
- QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
- for (int a = 0; a < h2Pairs.count(); ++a) {
- QHttpNetworkReply *currentReply = h2Pairs.at(a).second;
+ const auto h2RequestsToSendCopy = h2RequestsToSend;
+ for (const auto &httpMessagePair : h2RequestsToSendCopy) {
+ QHttpNetworkReply *currentReply = httpMessagePair.second;
Q_ASSERT(currentReply);
emit currentReply->finishedWithError(error, QHttpNetworkConnectionChannel::tr(message));
}
@@ -1176,8 +1172,7 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
// after establishing a secure connection we immediately start sending
// HTTP/2 frames.
switch (sslSocket->sslConfiguration().nextProtocolNegotiationStatus()) {
- case QSslConfiguration::NextProtocolNegotiationNegotiated:
- case QSslConfiguration::NextProtocolNegotiationUnsupported: {
+ case QSslConfiguration::NextProtocolNegotiationNegotiated: {
QByteArray nextProtocol = sslSocket->sslConfiguration().nextNegotiatedProtocol();
if (nextProtocol == QSslConfiguration::NextProtocolHttp1_1) {
// fall through to create a QHttpProtocolHandler
@@ -1193,17 +1188,12 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
}
}
Q_FALLTHROUGH();
+ case QSslConfiguration::NextProtocolNegotiationUnsupported: // No agreement, try HTTP/1(.1)
case QSslConfiguration::NextProtocolNegotiationNone: {
protocolHandler.reset(new QHttpProtocolHandler(this));
- if (!sslConfiguration.data()) {
- // Our own auto-tests bypass the normal initialization (done by
- // QHttpThreadDelegate), this means in the past we'd have here
- // the default constructed QSslConfiguration without any protocols
- // to negotiate. Let's create it now:
- sslConfiguration.reset(new QSslConfiguration);
- }
- QList<QByteArray> protocols = sslConfiguration->allowedNextProtocols();
+ QSslConfiguration newConfiguration = sslSocket->sslConfiguration();
+ QList<QByteArray> protocols = newConfiguration.allowedNextProtocols();
const int nProtocols = protocols.size();
// Clear the protocol that we failed to negotiate, so we do not try
// it again on other channels that our connection can create/open.
@@ -1211,10 +1201,10 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
protocols.removeAll(QSslConfiguration::ALPNProtocolHTTP2);
if (nProtocols > protocols.size()) {
- sslConfiguration->setAllowedNextProtocols(protocols);
+ newConfiguration.setAllowedNextProtocols(protocols);
const int channelCount = connection->d_func()->channelCount;
for (int i = 0; i < channelCount; ++i)
- connection->d_func()->channels[i].setSslConfiguration(*sslConfiguration);
+ connection->d_func()->channels[i].setSslConfiguration(newConfiguration);
}
connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeHTTP);
@@ -1246,10 +1236,12 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 ||
connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
- if (h2RequestsToSend.count() > 0) {
+ if (!h2RequestsToSend.isEmpty()) {
+ // Similar to HTTP/1.1 counterpart below:
+ const auto &pair = std::as_const(h2RequestsToSend).first();
+ emit pair.second->encrypted();
// In case our peer has sent us its settings (window size, max concurrent streams etc.)
// let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
- QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
} else { // HTTP
if (!reply)
@@ -1262,14 +1254,14 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
if (reply)
sendRequestDelayed();
}
+ QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
void QHttpNetworkConnectionChannel::requeueHttp2Requests()
{
- QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
- for (int a = 0; a < h2Pairs.count(); ++a)
- connection->d_func()->requeueRequest(h2Pairs.at(a));
- h2RequestsToSend.clear();
+ const auto h2RequestsToSendCopy = std::exchange(h2RequestsToSend, {});
+ for (const auto &httpMessagePair : h2RequestsToSendCopy)
+ connection->d_func()->requeueRequest(httpMessagePair);
}
void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors)
@@ -1288,10 +1280,10 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors)
}
#ifndef QT_NO_SSL
else { // HTTP/2
- QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
- for (int a = 0; a < h2Pairs.count(); ++a) {
+ const auto h2RequestsToSendCopy = h2RequestsToSend;
+ for (const auto &httpMessagePair : h2RequestsToSendCopy) {
// emit SSL errors for all replies
- QHttpNetworkReply *currentReply = h2Pairs.at(a).second;
+ QHttpNetworkReply *currentReply = httpMessagePair.second;
Q_ASSERT(currentReply);
emit currentReply->sslErrors(errors);
}
@@ -1311,10 +1303,10 @@ void QHttpNetworkConnectionChannel::_q_preSharedKeyAuthenticationRequired(QSslPr
if (reply)
emit reply->preSharedKeyAuthenticationRequired(authenticator);
} else {
- QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
- for (int a = 0; a < h2Pairs.count(); ++a) {
+ const auto h2RequestsToSendCopy = h2RequestsToSend;
+ for (const auto &httpMessagePair : h2RequestsToSendCopy) {
// emit SSL errors for all replies
- QHttpNetworkReply *currentReply = h2Pairs.at(a).second;
+ QHttpNetworkReply *currentReply = httpMessagePair.second;
Q_ASSERT(currentReply);
emit currentReply->preSharedKeyAuthenticationRequired(authenticator);
}