summaryrefslogtreecommitdiffstats
path: root/src/network/access/qhttpnetworkconnection.cpp
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2016-12-28 15:27:57 +0100
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2017-01-17 18:51:32 +0000
commitcebf1fea4a6802b8999469f647f52171e87d02b6 (patch)
treeca858bb7eb3b482d1e555c285b08c0e627497256 /src/network/access/qhttpnetworkconnection.cpp
parent27e27966bf01b4c42343100a49b1dd6b014025fe (diff)
Add redirects policy to QNetworkAccessManager
This patch makes it possible to enable/disable redirects on QNAM level (before it was per-request only). This policy would be applied to all subsequent requests* created by QNAM. The policies we support at the moment: a. Manual - that's what we always had - it's up to a user to handle redirects. b. NoLessSafeRedirectsPolicy - we allow http->http, http->https and https->https redirects, but no protocol 'downgrade' (no https->http redirects). c. SameOriginPolicy - we check that protocol/host/port are the same. Updated tst_qnetworkreply. *We previously were enabling redirect for each request, by setting FollowRedirectsAttribute on QNetworkRequest object. For backward compatibility this attribute has a higher priority (if set) than QNAM's policy (and it will work as NoLessSafeRedirectsPolicy). [ChangeLog][QtNetwork] Added redirects policy to QNAM Task-number: QTPM-239 Task-number: QTPM-237 Change-Id: I493d1728254b71b61b5504937e8e01dca5953527 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network/access/qhttpnetworkconnection.cpp')
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 128f75f93b..e5c6c2f81c 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -522,17 +522,17 @@ QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socke
if (!reply->request().isFollowRedirects())
return QUrl();
- QUrl rUrl;
+ QUrl redirectUrl;
const QList<QPair<QByteArray, QByteArray> > fields = reply->header();
for (const QNetworkReply::RawHeaderPair &header : fields) {
if (header.first.toLower() == "location") {
- rUrl = QUrl::fromEncoded(header.second);
+ redirectUrl = QUrl::fromEncoded(header.second);
break;
}
}
// If the location url is invalid/empty, we emit ProtocolUnknownError
- if (!rUrl.isValid()) {
+ if (!redirectUrl.isValid()) {
emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError);
return QUrl();
}
@@ -544,24 +544,37 @@ QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socke
}
// Resolve the URL if it's relative
- if (rUrl.isRelative())
- rUrl = reply->request().url().resolved(rUrl);
+ if (redirectUrl.isRelative())
+ redirectUrl = reply->request().url().resolved(redirectUrl);
// Check redirect url protocol
- QString scheme = rUrl.scheme();
- if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) {
- QString previousUrlScheme = reply->request().url().scheme();
- // Check if we're doing an unsecure redirect (https -> http)
- if (previousUrlScheme == QLatin1String("https")
- && scheme == QLatin1String("http")) {
- emitReplyError(socket, reply, QNetworkReply::InsecureRedirectError);
- return QUrl();
+ const QUrl priorUrl(reply->request().url());
+ if (redirectUrl.scheme() == QLatin1String("http") || redirectUrl.scheme() == QLatin1String("https")) {
+ switch (reply->request().redirectsPolicy()) {
+ case QNetworkRequest::NoLessSafeRedirectsPolicy:
+ // Check if we're doing an unsecure redirect (https -> http)
+ if (priorUrl.scheme() == QLatin1String("https")
+ && redirectUrl.scheme() == QLatin1String("http")) {
+ emitReplyError(socket, reply, QNetworkReply::InsecureRedirectError);
+ return QUrl();
+ }
+ break;
+ case QNetworkRequest::SameOriginRedirectsPolicy:
+ if (priorUrl.host() != redirectUrl.host()
+ || priorUrl.scheme() != redirectUrl.scheme()
+ || priorUrl.port() != redirectUrl.port()) {
+ emitReplyError(socket, reply, QNetworkReply::InsecureRedirectError);
+ return QUrl();
+ }
+ break;
+ default:
+ Q_ASSERT(!"Unexpected redirect policy");
}
} else {
emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError);
return QUrl();
}
- return rUrl;
+ return redirectUrl;
}
void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request)