summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2023-03-23 21:06:47 +0200
committerTarja Sundqvist <tarja.sundqvist@qt.io>2023-03-23 21:06:47 +0200
commit42e4ae042a4c86e58bcb8b6d2d59ba4a988285b4 (patch)
treea7f25b1d335a834a7c3ae104cee913ef3a4dd4fb /src/network/access
parent4ee4fc18b4067b90efa46ca9baba74f53b54d9ec (diff)
parent168ff3419f256fdb35b586275d293fc0cd773fe1 (diff)
Merge remote-tracking branch 'origin/tqtc/lts-5.15.9' into tqtc/lts-5.15-opensourcev5.15.9-lts-lgpl
Diffstat (limited to 'src/network/access')
-rw-r--r--src/network/access/qhttp2configuration.cpp2
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp20
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp50
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h6
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp2
-rw-r--r--src/network/access/qnetworkreplywasmimpl.cpp10
-rw-r--r--src/network/access/qnetworkrequest.cpp13
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