diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-03-23 21:06:47 +0200 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-03-23 21:06:47 +0200 |
commit | 42e4ae042a4c86e58bcb8b6d2d59ba4a988285b4 (patch) | |
tree | a7f25b1d335a834a7c3ae104cee913ef3a4dd4fb /src/network/access | |
parent | 4ee4fc18b4067b90efa46ca9baba74f53b54d9ec (diff) | |
parent | 168ff3419f256fdb35b586275d293fc0cd773fe1 (diff) | |
download | qtbase-5.15.tar.gz |
Merge remote-tracking branch 'origin/tqtc/lts-5.15.9' into tqtc/lts-5.15-opensourcev5.15.9-lts-lgpl5.15
Change-Id: Iaff6b55275e50d19973e1020853d8622587069f9
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qhttp2configuration.cpp | 2 | ||||
-rw-r--r-- | src/network/access/qhttp2protocolhandler.cpp | 20 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 50 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection_p.h | 6 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkreplywasmimpl.cpp | 10 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.cpp | 13 |
7 files changed, 69 insertions, 34 deletions
diff --git a/src/network/access/qhttp2configuration.cpp b/src/network/access/qhttp2configuration.cpp index 408f141e77..e4126905b2 100644 --- a/src/network/access/qhttp2configuration.cpp +++ b/src/network/access/qhttp2configuration.cpp @@ -159,7 +159,7 @@ QHttp2Configuration::~QHttp2Configuration() /*! If \a enable is \c true, a remote server can potentially - use server push to send reponses in advance. + use server push to send responses in advance. \sa serverPushEnabled */ diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index ddd661cc50..39dd460881 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -1135,8 +1135,6 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader // moment and we are probably not done yet. So we extract url and set it // here, if needed. int statusCode = 0; - QUrl redirectUrl; - for (const auto &pair : headers) { const auto &name = pair.name; auto value = pair.value; @@ -1159,8 +1157,6 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader if (ok) httpReply->setContentLength(length); } else { - if (name == "location") - redirectUrl = QUrl::fromEncoded(value); QByteArray binder(", "); if (name == "set-cookie") binder = "\n"; @@ -1225,8 +1221,20 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader } } - if (QHttpNetworkReply::isHttpRedirect(statusCode) && redirectUrl.isValid()) - httpReply->setRedirectUrl(redirectUrl); + if (QHttpNetworkReply::isHttpRedirect(statusCode) && httpRequest.isFollowRedirects()) { + QHttpNetworkConnectionPrivate::ParseRedirectResult result = + m_connection->d_func()->parseRedirectResponse(httpReply); + if (result.errorCode != QNetworkReply::NoError) { + auto errorString = m_connection->d_func()->errorDetail(result.errorCode, m_socket); + finishStreamWithError(stream, result.errorCode, errorString); + sendRST_STREAM(stream.streamID, INTERNAL_ERROR); + markAsReset(stream.streamID); + return; + } + + if (result.redirectUrl.isValid()) + httpReply->setRedirectUrl(result.redirectUrl); + } if (httpReplyPrivate->isCompressed() && httpRequest.d->autoDecompress) httpReplyPrivate->removeAutoDecompressHeader(); diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 1bef9157e6..db4dd591e3 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -462,7 +462,12 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket else channels[i].authMethod = priv->method; - if (priv->phase == QAuthenticatorPrivate::Done) { + if (priv->phase == QAuthenticatorPrivate::Done || + (priv->phase == QAuthenticatorPrivate::Start + && priv->method == QAuthenticatorPrivate::Ntlm)) { + if (priv->phase == QAuthenticatorPrivate::Start) + priv->phase = QAuthenticatorPrivate::Phase1; + pauseConnection(); if (!isProxy) { if (channels[i].authenticationCredentialsSent) { @@ -528,10 +533,23 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket return false; } -QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socket, QHttpNetworkReply *reply) +// Used by the HTTP1 code-path +QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socket, + QHttpNetworkReply *reply) +{ + ParseRedirectResult result = parseRedirectResponse(reply); + if (result.errorCode != QNetworkReply::NoError) { + emitReplyError(socket, reply, result.errorCode); + return {}; + } + return std::move(result.redirectUrl); +} + +QHttpNetworkConnectionPrivate::ParseRedirectResult +QHttpNetworkConnectionPrivate::parseRedirectResponse(QHttpNetworkReply *reply) { if (!reply->request().isFollowRedirects()) - return QUrl(); + return {{}, QNetworkReply::NoError}; QUrl redirectUrl; const QList<QPair<QByteArray, QByteArray> > fields = reply->header(); @@ -542,17 +560,13 @@ QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socke } } - // If the location url is invalid/empty, we emit ProtocolUnknownError - if (!redirectUrl.isValid()) { - emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError); - return QUrl(); - } + // If the location url is invalid/empty, we return ProtocolUnknownError + if (!redirectUrl.isValid()) + return {{}, QNetworkReply::ProtocolUnknownError}; // Check if we have exceeded max redirects allowed - if (reply->request().redirectCount() <= 0) { - emitReplyError(socket, reply, QNetworkReply::TooManyRedirectsError); - return QUrl(); - } + if (reply->request().redirectCount() <= 0) + return {{}, QNetworkReply::TooManyRedirectsError}; // Resolve the URL if it's relative if (redirectUrl.isRelative()) @@ -573,8 +587,7 @@ QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socke if (priorUrl.host() != redirectUrl.host() || priorUrl.scheme() != redirectUrl.scheme() || priorUrl.port() != redirectUrl.port()) { - emitReplyError(socket, reply, QNetworkReply::InsecureRedirectError); - return QUrl(); + return {{}, QNetworkReply::InsecureRedirectError}; } break; case QNetworkRequest::UserVerifiedRedirectPolicy: @@ -583,10 +596,9 @@ QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socke Q_ASSERT(!"Unexpected redirect policy"); } } else { - emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError); - return QUrl(); + return {{}, QNetworkReply::ProtocolUnknownError}; } - return redirectUrl; + return {std::move(redirectUrl), QNetworkReply::NoError}; } void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request) @@ -1446,7 +1458,7 @@ void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy) d->networkProxy = networkProxy; // update the authenticator if (!d->networkProxy.user().isEmpty()) { - for (int i = 0; i < d->activeChannelCount; ++i) { + for (int i = 0; i < d->channelCount; ++i) { d->channels[i].proxyAuthenticator.setUser(d->networkProxy.user()); d->channels[i].proxyAuthenticator.setPassword(d->networkProxy.password()); } @@ -1462,7 +1474,7 @@ QNetworkProxy QHttpNetworkConnection::cacheProxy() const void QHttpNetworkConnection::setTransparentProxy(const QNetworkProxy &networkProxy) { Q_D(QHttpNetworkConnection); - for (int i = 0; i < d->activeChannelCount; ++i) + for (int i = 0; i < d->channelCount; ++i) d->channels[i].setProxy(networkProxy); } diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 845b55bc5d..5fed62fc97 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -273,6 +273,12 @@ public: void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode); bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend); + struct ParseRedirectResult { + QUrl redirectUrl; + QNetworkReply::NetworkError errorCode; + }; + ParseRedirectResult parseRedirectResponse(QHttpNetworkReply *reply); + // Used by the HTTP1 code-path QUrl parseRedirectResponse(QAbstractSocket *socket, QHttpNetworkReply *reply); #ifndef QT_NO_NETWORKPROXY diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 517c460825..a10fe9e3fe 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -755,7 +755,7 @@ bool QNetworkAccessManager::isStrictTransportSecurityEnabled() const store is enabled, these policies will be preserved in the store. In case both cache and store contain the same known hosts, policies from cache are considered to be more up-to-date (and thus will overwrite the previous values in the store). - If this behavior is undesired, enable HSTS store before enabling Strict Tranport + If this behavior is undesired, enable HSTS store before enabling Strict Transport Security. By default, the persistent store of HSTS policies is disabled. \sa isStrictTransportSecurityStoreEnabled(), setStrictTransportSecurityEnabled(), diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index 2ee57a0860..7f23390a8d 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -234,10 +234,13 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() } } + QByteArray userName, password; // username & password if (!request.url().userInfo().isEmpty()) { - attr.userName = request.url().userName().toUtf8(); - attr.password = request.url().password().toUtf8(); + userName = request.url().userName().toUtf8(); + password = request.url().password().toUtf8(); + attr.userName = userName.constData(); + attr.password = password.constData(); } attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; @@ -265,7 +268,8 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() attr.userData = reinterpret_cast<void *>(this); QString dPath = QStringLiteral("/home/web_user/") + request.url().fileName(); - attr.destinationPath = dPath.toUtf8(); + QByteArray destinationPath = dPath.toUtf8(); + attr.destinationPath = destinationPath.constData(); m_fetch = emscripten_fetch(&attr, request.url().toString().toUtf8()); } diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 03ed2a455d..0235790efe 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. @@ -423,6 +423,11 @@ QT_BEGIN_NAMESPACE for example, to ask the user whether to accept the redirect, or to decide based on some app-specific configuration. + + \note When Qt handles redirects it will, for legacy and compatibility + reasons, issue the redirected request using GET when the server returns + a 301 or 302 response, regardless of the original method used, unless it was + HEAD. */ /*! @@ -1036,9 +1041,10 @@ static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVaria case QNetworkRequest::LastModifiedHeader: case QNetworkRequest::IfModifiedSinceHeader: switch (value.userType()) { + // Generate RFC 1123/822 dates: case QMetaType::QDate: + return QNetworkHeadersPrivate::toHttpDate(value.toDate().startOfDay(Qt::UTC)); case QMetaType::QDateTime: - // generate RFC 1123/822 dates: return QNetworkHeadersPrivate::toHttpDate(value.toDateTime()); default: @@ -1482,8 +1488,7 @@ QDateTime QNetworkHeadersPrivate::fromHttpDate(const QByteArray &value) QByteArray QNetworkHeadersPrivate::toHttpDate(const QDateTime &dt) { - return QLocale::c().toString(dt, u"ddd, dd MMM yyyy hh:mm:ss 'GMT'") - .toLatin1(); + return QLocale::c().toString(dt.toUTC(), u"ddd, dd MMM yyyy hh:mm:ss 'GMT'").toLatin1(); } QT_END_NAMESPACE |