summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp2
-rw-r--r--src/network/access/qnetworkreply.cpp14
-rw-r--r--src/network/access/qnetworkreply.h1
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp21
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h3
-rw-r--r--src/network/access/qnetworkrequest.cpp10
-rw-r--r--src/network/access/qnetworkrequest.h3
7 files changed, 48 insertions, 6 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index e5c6c2f81c..327eaf91bc 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -567,6 +567,8 @@ QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socke
return QUrl();
}
break;
+ case QNetworkRequest::UserVerifiedRedirectsPolicy:
+ break;
default:
Q_ASSERT(!"Unexpected redirect policy");
}
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index b35cfe03d7..17990f02f5 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -305,6 +305,20 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
*/
/*!
+ \fn void QNetworkReply::redirectAllowed()
+ \since 5.9
+
+ When client code handling the redirected() signal has verified the new URL,
+ it emits this signal to allow the redirect to go ahead. This protocol applies
+ to network requests whose redirects policy is set to
+ QNetworkRequest::UserVerifiedRedirectsPolicy.
+
+ \sa QNetworkRequest::UserVerifiedRedirectsPolicy
+ QNetworkAccessManager::setRedirectsPolicy(),
+ QNetworkRequest::RedirectsPolicyAttribute
+*/
+
+/*!
\fn void QNetworkReply::metaDataChanged()
\omit FIXME: Update name? \endomit
diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h
index 1419db8597..d858e07d84 100644
--- a/src/network/access/qnetworkreply.h
+++ b/src/network/access/qnetworkreply.h
@@ -163,6 +163,7 @@ Q_SIGNALS:
void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator);
#endif
void redirected(const QUrl &url);
+ void redirectAllowed();
void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 03ed596586..19f424b35f 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -824,12 +824,16 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
QObject::connect(delegate, SIGNAL(redirected(QUrl,int,int)),
q, SLOT(onRedirected(QUrl,int,int)),
Qt::QueuedConnection);
+
+ QObject::connect(q, SIGNAL(redirectAllowed()), q, SLOT(followRedirect()),
+ Qt::QueuedConnection);
+
#ifndef QT_NO_SSL
QObject::connect(delegate, SIGNAL(sslConfigurationChanged(QSslConfiguration)),
q, SLOT(replySslConfigurationChanged(QSslConfiguration)),
Qt::QueuedConnection);
#endif
- // Those need to report back, therefire BlockingQueuedConnection
+ // Those need to report back, therefore BlockingQueuedConnection
QObject::connect(delegate, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
q, SLOT(httpAuthenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
Qt::BlockingQueuedConnection);
@@ -1121,19 +1125,26 @@ void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int htt
if (httpRequest.isFollowRedirects()) // update the reply's url as it could've changed
url = redirectUrl;
- QNetworkRequest redirectRequest = createRedirectRequest(originalRequest, redirectUrl, maxRedirectsRemaining);
+ redirectRequest = createRedirectRequest(originalRequest, redirectUrl, maxRedirectsRemaining);
operation = getRedirectOperation(operation, httpStatus);
+ if (httpRequest.redirectsPolicy() != QNetworkRequest::UserVerifiedRedirectsPolicy)
+ followRedirect();
+
+ emit q->redirected(redirectUrl);
+}
+
+void QNetworkReplyHttpImplPrivate::followRedirect()
+{
+ Q_Q(QNetworkReplyHttpImpl);
+
cookedHeaders.clear();
if (managerPrivate->thread)
managerPrivate->thread->disconnect();
- // Recurse
QMetaObject::invokeMethod(q, "start", Qt::QueuedConnection,
Q_ARG(QNetworkRequest, redirectRequest));
-
- emit q->redirected(redirectUrl);
}
void QNetworkReplyHttpImplPrivate::checkForRedirect(const int statusCode)
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index 255c23006e..9383149124 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -136,6 +136,7 @@ public:
Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose())
Q_PRIVATE_SLOT(d_func(), void _q_metaDataChanged())
Q_PRIVATE_SLOT(d_func(), void onRedirected(const QUrl &, int, int))
+ Q_PRIVATE_SLOT(d_func(), void followRedirect())
#ifndef QT_NO_SSL
protected:
@@ -212,6 +213,7 @@ public:
QSharedPointer<QRingBuffer> outgoingDataBuffer;
void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal); // dup?
void onRedirected(const QUrl &redirectUrl, int httpStatus, int maxRedirectsRemainig);
+ void followRedirect();
qint64 bytesUploaded;
@@ -263,6 +265,7 @@ public:
QList<QSslError> pendingIgnoreSslErrorsList;
#endif
+ QNetworkRequest redirectRequest;
bool loadFromCacheIfAllowed(QHttpNetworkRequest &httpRequest);
void invalidateCache();
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index abc924d0e2..169695fa27 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -360,6 +360,16 @@ QT_BEGIN_NAMESPACE
Note, http://example.com and http://example.com:80
will fail with this policy (implicit/explicit ports
are considered to be a mismatch).
+
+ \value UserVerifiedRedirectsPolicy Client decides whether to follow each
+ redirect by handling the redirected()
+ signal, emitting redirectAllowed() on
+ the QNetworkReply object to allow
+ the redirect or aborting/finishing it to
+ reject the redirect. This can be used,
+ for example, to ask the user whether to
+ accept the redirect, or to decide
+ based on some app-specific configuration.
*/
class QNetworkRequestPrivate: public QSharedData, public QNetworkHeadersPrivate
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index 52c398663a..06c895af5f 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -116,7 +116,8 @@ public:
enum RedirectsPolicy {
ManualRedirectsPolicy,
NoLessSafeRedirectsPolicy,
- SameOriginRedirectsPolicy
+ SameOriginRedirectsPolicy,
+ UserVerifiedRedirectsPolicy
};