summaryrefslogtreecommitdiffstats
path: root/src/network/access/qnetworkaccessmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/access/qnetworkaccessmanager.cpp')
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp81
1 files changed, 62 insertions, 19 deletions
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index a637474..4bc036e 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -54,6 +54,7 @@
#include "qnetworkaccessfilebackend_p.h"
#include "qnetworkaccessdatabackend_p.h"
#include "qnetworkaccessdebugpipebackend_p.h"
+#include "qnetworkaccesscachebackend_p.h"
#include "qfilenetworkreply_p.h"
#include "QtCore/qbuffer.h"
@@ -944,6 +945,22 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
{
Q_D(QNetworkAccessManager);
+ // 4.7 only hotfix fast path for data:// URLs
+ // In 4.8 this is solved with QNetworkReplyDataImpl and will work there
+ // This hotfix is done for not needing a QNetworkSession for data://
+ if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)
+ && (req.url().scheme() == QLatin1String("data"))) {
+ QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
+ QNetworkReplyImplPrivate *priv = reply->d_func();
+ priv->manager = this;
+ priv->backend = new QNetworkAccessDataBackend();
+ priv->backend->manager = this->d_func();
+ priv->backend->setParent(reply);
+ priv->backend->reply = priv;
+ priv->setup(op, req, outgoingData);
+ return reply;
+ }
+
// fast path for GET on file:// URLs
// Also if the scheme is empty we consider it a file.
// The QNetworkAccessFileBackend will right now only be used for PUT
@@ -954,6 +971,26 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QFileNetworkReply(this, req, op);
}
+ // A request with QNetworkRequest::AlwaysCache does not need any bearer management
+ QNetworkRequest::CacheLoadControl mode =
+ static_cast<QNetworkRequest::CacheLoadControl>(
+ req.attribute(QNetworkRequest::CacheLoadControlAttribute,
+ QNetworkRequest::PreferNetwork).toInt());
+ if (mode == QNetworkRequest::AlwaysCache
+ && (op == QNetworkAccessManager::GetOperation
+ || op == QNetworkAccessManager::HeadOperation)) {
+ // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106
+ QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
+ QNetworkReplyImplPrivate *priv = reply->d_func();
+ priv->manager = this;
+ priv->backend = new QNetworkAccessCacheBackend();
+ priv->backend->manager = this->d_func();
+ priv->backend->setParent(reply);
+ priv->backend->reply = priv;
+ priv->setup(op, req, outgoingData);
+ return reply;
+ }
+
#ifndef QT_NO_BEARERMANAGEMENT
// Return a disabled network reply if network access is disabled.
// Except if the scheme is empty or file://.
@@ -1009,16 +1046,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
priv->manager = this;
// second step: fetch cached credentials
- if (static_cast<QNetworkRequest::LoadControl>
- (request.attribute(QNetworkRequest::AuthenticationReuseAttribute,
- QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic) {
- QNetworkAuthenticationCredential *cred = d->fetchCachedCredentials(url);
- if (cred) {
- url.setUserName(cred->user);
- url.setPassword(cred->password);
- priv->urlForLastAuthentication = url;
- }
- }
+ // This is not done for the time being, we should use signal emissions to request
+ // the credentials from cache.
// third step: find a backend
priv->backend = d->findBackend(op, request);
@@ -1031,12 +1060,14 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
priv->backend->setParent(reply);
priv->backend->reply = priv;
}
- // fourth step: setup the reply
- priv->setup(op, request, outgoingData);
#ifndef QT_NO_OPENSSL
reply->setSslConfiguration(request.sslConfiguration());
#endif
+
+ // fourth step: setup the reply
+ priv->setup(op, request, outgoingData);
+
return reply;
}
@@ -1100,7 +1131,9 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend
// don't try the cache for the same URL twice in a row
// being called twice for the same URL means the authentication failed
- if (url != backend->reply->urlForLastAuthentication) {
+ // also called when last URL is empty, e.g. on first call
+ if (backend->reply->urlForLastAuthentication.isEmpty()
+ || url != backend->reply->urlForLastAuthentication) {
QNetworkAuthenticationCredential *cred = fetchCachedCredentials(url, authenticator);
if (cred) {
authenticator->setUser(cred->user);
@@ -1110,9 +1143,14 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend
}
}
+ // if we emit a signal here in synchronous mode, the user might spin
+ // an event loop, which might recurse and lead to problems
+ if (backend->isSynchronous())
+ return;
+
backend->reply->urlForLastAuthentication = url;
emit q->authenticationRequired(backend->reply->q_func(), authenticator);
- addCredentials(url, authenticator);
+ cacheCredentials(url, authenticator);
}
#ifndef QT_NO_NETWORKPROXY
@@ -1129,7 +1167,7 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac
// possible solution: some tracking inside the authenticator
// or a new function proxyAuthenticationSucceeded(true|false)
if (proxy != backend->reply->lastProxyAuthentication) {
- QNetworkAuthenticationCredential *cred = fetchCachedCredentials(proxy);
+ QNetworkAuthenticationCredential *cred = fetchCachedProxyCredentials(proxy);
if (cred) {
authenticator->setUser(cred->user);
authenticator->setPassword(cred->password);
@@ -1137,12 +1175,17 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac
}
}
+ // if we emit a signal here in synchronous mode, the user might spin
+ // an event loop, which might recurse and lead to problems
+ if (backend->isSynchronous())
+ return;
+
backend->reply->lastProxyAuthentication = proxy;
emit q->proxyAuthenticationRequired(proxy, authenticator);
- addCredentials(proxy, authenticator);
+ cacheProxyCredentials(proxy, authenticator);
}
-void QNetworkAccessManagerPrivate::addCredentials(const QNetworkProxy &p,
+void QNetworkAccessManagerPrivate::cacheProxyCredentials(const QNetworkProxy &p,
const QAuthenticator *authenticator)
{
Q_ASSERT(authenticator);
@@ -1179,7 +1222,7 @@ void QNetworkAccessManagerPrivate::addCredentials(const QNetworkProxy &p,
}
QNetworkAuthenticationCredential *
-QNetworkAccessManagerPrivate::fetchCachedCredentials(const QNetworkProxy &p,
+QNetworkAccessManagerPrivate::fetchCachedProxyCredentials(const QNetworkProxy &p,
const QAuthenticator *authenticator)
{
QNetworkProxy proxy = p;
@@ -1231,7 +1274,7 @@ QList<QNetworkProxy> QNetworkAccessManagerPrivate::queryProxy(const QNetworkProx
}
#endif
-void QNetworkAccessManagerPrivate::addCredentials(const QUrl &url,
+void QNetworkAccessManagerPrivate::cacheCredentials(const QUrl &url,
const QAuthenticator *authenticator)
{
Q_ASSERT(authenticator);