diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-10-29 16:06:48 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-10-29 16:06:48 (GMT) |
commit | 7db218d6860a04df238735ff692010f0910d0c92 (patch) | |
tree | ad8033623855b3afb17752552ca56b096c1b9159 /src/network/access | |
parent | 8943b44c38ee6244c4a5b190c2b35879b1921843 (diff) | |
parent | c02ef9eb331f03dbd59d2fd938c53b54f5c65cea (diff) | |
download | Qt-7db218d6860a04df238735ff692010f0910d0c92.zip Qt-7db218d6860a04df238735ff692010f0910d0c92.tar.gz Qt-7db218d6860a04df238735ff692010f0910d0c92.tar.bz2 |
Merge branch 4.7 into qt-master-from-4.7
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qhttp.cpp | 2 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 157 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection_p.h | 36 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 36 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel_p.h | 7 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply.cpp | 5 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply_p.h | 8 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessbackend.cpp | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkaccesshttpbackend.cpp | 52 | ||||
-rw-r--r-- | src/network/access/qnetworkaccesshttpbackend_p.h | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 28 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager_p.h | 6 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.cpp | 10 |
13 files changed, 144 insertions, 206 deletions
diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index 13375f8..9c2f79a 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -2442,7 +2442,7 @@ void QHttpPrivate::_q_slotSendRequest() if (proxy.hostName().isEmpty()) { proxy.setType(QNetworkProxy::NoProxy); } else if (sslInUse) { - // Disallow use of cacheing proxy with HTTPS; instead fall back to + // Disallow use of caching proxy with HTTPS; instead fall back to // transparent HTTP CONNECT proxying. transparentProxyInUse = true; } else { diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 2ab28c7..1ef58d8 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include <private/qabstractsocket_p.h> #include "qhttpnetworkconnection_p.h" #include "qhttpnetworkconnectionchannel_p.h" #include "private/qnoncontiguousbytedevice_p.h" @@ -56,6 +57,7 @@ #ifndef QT_NO_HTTP #ifndef QT_NO_OPENSSL +# include <private/qsslsocket_p.h> # include <QtNetwork/qsslkey.h> # include <QtNetwork/qsslcipher.h> # include <QtNetwork/qsslconfiguration.h> @@ -79,9 +81,9 @@ const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2; QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt) -: hostName(hostName), port(port), encrypt(encrypt), - channelCount(defaultChannelCount), - pendingAuthSignal(false), pendingProxyAuthSignal(false) +: state(RunningState), + hostName(hostName), port(port), encrypt(encrypt), + channelCount(defaultChannelCount) #ifndef QT_NO_NETWORKPROXY , networkProxy(QNetworkProxy::NoProxy) #endif @@ -90,9 +92,9 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host } QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt) -: hostName(hostName), port(port), encrypt(encrypt), - channelCount(channelCount), - pendingAuthSignal(false), pendingProxyAuthSignal(false) +: state(RunningState), + hostName(hostName), port(port), encrypt(encrypt), + channelCount(channelCount) #ifndef QT_NO_NETWORKPROXY , networkProxy(QNetworkProxy::NoProxy) #endif @@ -122,6 +124,42 @@ void QHttpNetworkConnectionPrivate::init() } } +void QHttpNetworkConnectionPrivate::pauseConnection() +{ + state = PausedState; + + // Disable all socket notifiers + for (int i = 0; i < channelCount; i++) { +#ifndef QT_NO_OPENSSL + if (encrypt) + QSslSocketPrivate::pauseSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket)); + else +#endif + QAbstractSocketPrivate::pauseSocketNotifiers(channels[i].socket); + } +} + +void QHttpNetworkConnectionPrivate::resumeConnection() +{ + state = RunningState; + // Enable all socket notifiers + for (int i = 0; i < channelCount; i++) { +#ifndef QT_NO_OPENSSL + if (encrypt) + QSslSocketPrivate::resumeSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket)); + else +#endif + QAbstractSocketPrivate::resumeSocketNotifiers(channels[i].socket); + + // Resume pending upload if needed + if (channels[i].state == QHttpNetworkConnectionChannel::WritingState) + QMetaObject::invokeMethod(&channels[i], "_q_uploadDataReadyRead", Qt::QueuedConnection); + } + + // queue _q_startNextRequest + QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection); +} + int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const { for (int i = 0; i < channelCount; ++i) @@ -258,6 +296,13 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica { Q_ASSERT(auth); + // NTLM is a multi phase authentication. Copying credentials between authenticators would mess things up. + if (!isProxy && channels[fromChannel].authMethod == QAuthenticatorPrivate::Ntlm) + return; + if (isProxy && channels[fromChannel].proxyAuthMethod == QAuthenticatorPrivate::Ntlm) + return; + + // select another channel QAuthenticator* otherAuth = 0; for (int i = 0; i < channelCount; ++i) { @@ -297,10 +342,10 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket QAuthenticator* auth = 0; if (isProxy) { auth = &channels[i].proxyAuthenticator; - channels[i].proxyAuthMehtod = authMethod; + channels[i].proxyAuthMethod = authMethod; } else { auth = &channels[i].authenticator; - channels[i].authMehtod = authMethod; + channels[i].authMethod = authMethod; } //proceed with the authentication. if (auth->isNull()) @@ -309,43 +354,23 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket priv->parseHttpResponse(fields, isProxy); if (priv->phase == QAuthenticatorPrivate::Done) { - if ((isProxy && pendingProxyAuthSignal) ||(!isProxy && pendingAuthSignal)) { - // drop the request - reply->d_func()->eraseData(); - channels[i].close(); - channels[i].lastStatus = 0; - channels[i].state = QHttpNetworkConnectionChannel::Wait4AuthState; - return false; - } - // cannot use this socket until the slot returns - channels[i].state = QHttpNetworkConnectionChannel::WaitingState; - socket->blockSignals(true); + pauseConnection(); if (!isProxy) { - pendingAuthSignal = true; - emit q->authenticationRequired(reply->request(), auth, q); - pendingAuthSignal = false; + emit reply->authenticationRequired(reply->request(), auth); #ifndef QT_NO_NETWORKPROXY } else { - pendingProxyAuthSignal = true; - emit q->proxyAuthenticationRequired(networkProxy, auth, q); - pendingProxyAuthSignal = false; + emit reply->proxyAuthenticationRequired(networkProxy, auth); #endif } - socket->blockSignals(false); - // socket free to use - channels[i].state = QHttpNetworkConnectionChannel::IdleState; + resumeConnection(); + if (priv->phase != QAuthenticatorPrivate::Done) { // send any pending requests copyCredentials(i, auth, isProxy); - QMetaObject::invokeMethod(q, "_q_restartAuthPendingRequests", Qt::QueuedConnection); } - } else if (priv->phase == QAuthenticatorPrivate::Start) { - // If the url's authenticator has a 'user' set we will end up here (phase is only set to 'Done' by - // parseHttpResponse above if 'user' is empty). So if credentials were supplied with the request, - // such as in the case of an XMLHttpRequest, this is our only opportunity to cache them. - emit q->cacheCredentials(reply->request(), auth, q); } - // - Changing values in QAuthenticator will reset the 'phase'. + // - Changing values in QAuthenticator will reset the 'phase'. Therefore if it is still "Done" + // then nothing was filled in by the user or the cache // - If withCredentials has been set to false (e.g. by QtWebKit for a cross-origin XMLHttpRequest) then // we need to bail out if authentication is required. if (priv->phase == QAuthenticatorPrivate::Done || !reply->request().withCredentials()) { @@ -357,15 +382,9 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket ? QNetworkReply::ProxyAuthenticationRequiredError : QNetworkReply::AuthenticationRequiredError; reply->d_func()->errorString = errorDetail(errorCode, socket); - emit q->error(errorCode, reply->d_func()->errorString); - emit channels[i].reply->finished(); + emit reply->finishedWithError(errorCode, reply->d_func()->errorString); // ### at this point the reply could be deleted socket->close(); - // remove pending request on the other channels - for (int j = 0; j < channelCount; ++j) { - if (j != i && channels[j].state == QHttpNetworkConnectionChannel::Wait4AuthState) - channels[j].state = QHttpNetworkConnectionChannel::IdleState; - } return true; } //resend the request @@ -381,8 +400,9 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, int i = indexOf(socket); - if (channels[i].authMehtod != QAuthenticatorPrivate::None) { - if (!(channels[i].authMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) { + // Send "Authorization" header, but not if it's NTLM and the socket is already authenticated. + if (channels[i].authMethod != QAuthenticatorPrivate::None) { + if (!(channels[i].authMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) { QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator); if (priv && priv->method != QAuthenticatorPrivate::None) { QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false)); @@ -390,8 +410,10 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, } } } - if (channels[i].proxyAuthMehtod != QAuthenticatorPrivate::None) { - if (!(channels[i].proxyAuthMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) { + + // Send "Proxy-Authorization" header, but not if it's NTLM and the socket is already authenticated. + if (channels[i].proxyAuthMethod != QAuthenticatorPrivate::None) { + if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) { QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator); if (priv && priv->method != QAuthenticatorPrivate::None) { QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false)); @@ -726,6 +748,10 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) // although it is called _q_startNextRequest, it will actually start multiple requests when possible void QHttpNetworkConnectionPrivate::_q_startNextRequest() { + // If the QHttpNetworkConnection is currently paused then bail out immediately + if (state == PausedState) + return; + //resend the necessary ones. for (int i = 0; i < channelCount; ++i) { if (channels[i].resendCurrent) { @@ -776,17 +802,6 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() fillPipeline(channels[i].socket); } -void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests() -{ - // send the request using the idle socket - for (int i = 0 ; i < channelCount; ++i) { - if (channels[i].state == QHttpNetworkConnectionChannel::Wait4AuthState) { - channels[i].state = QHttpNetworkConnectionChannel::IdleState; - if (channels[i].reply) - channels[i].sendRequest(); - } - } -} void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply) { @@ -835,33 +850,12 @@ QHttpNetworkReply* QHttpNetworkConnection::sendRequest(const QHttpNetworkRequest return d->queueRequest(request); } -void QHttpNetworkConnection::enableEncryption() -{ - Q_D(QHttpNetworkConnection); - d->encrypt = true; -} - bool QHttpNetworkConnection::isEncrypted() const { Q_D(const QHttpNetworkConnection); return d->encrypt; } -void QHttpNetworkConnection::setProxyAuthentication(QAuthenticator *authenticator) -{ - Q_D(QHttpNetworkConnection); - for (int i = 0; i < d->channelCount; ++i) - d->channels[i].proxyAuthenticator = *authenticator; -} - -void QHttpNetworkConnection::setAuthentication(const QString &domain, QAuthenticator *authenticator) -{ - Q_UNUSED(domain); // ### domain ? - Q_D(QHttpNetworkConnection); - for (int i = 0; i < d->channelCount; ++i) - d->channels[i].authenticator = *authenticator; -} - #ifndef QT_NO_NETWORKPROXY void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy) { @@ -954,8 +948,11 @@ void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int // e.g. it is for SOCKS proxies which require authentication. void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth) { - Q_Q(QHttpNetworkConnection); - emit q->proxyAuthenticationRequired(proxy, auth, q); + // Also pause the connection because socket notifiers may fire while an user + // dialog is displaying + pauseConnection(); + emit chan->reply->proxyAuthenticationRequired(proxy, auth); + resumeConnection(); int i = indexOf(chan->socket); copyCredentials(i, auth, true); } diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 51666d6..8461426c 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -108,43 +108,22 @@ public: QNetworkProxy transparentProxy() const; #endif - //enable encryption - void enableEncryption(); bool isEncrypted() const; - //authentication parameters - void setProxyAuthentication(QAuthenticator *authenticator); - void setAuthentication(const QString &domain, QAuthenticator *authenticator); - #ifndef QT_NO_OPENSSL void setSslConfiguration(const QSslConfiguration &config); void ignoreSslErrors(int channel = -1); void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1); - -Q_SIGNALS: - void sslErrors(const QList<QSslError> &errors); -#endif - -Q_SIGNALS: -#ifndef QT_NO_NETWORKPROXY - //cannot be used with queued connection. - void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator, - const QHttpNetworkConnection *connection = 0); #endif - void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator, - const QHttpNetworkConnection *connection = 0); - void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator, - const QHttpNetworkConnection *connection = 0); - void error(QNetworkReply::NetworkError errorCode, const QString &detail = QString()); private: Q_DECLARE_PRIVATE(QHttpNetworkConnection) Q_DISABLE_COPY(QHttpNetworkConnection) friend class QHttpNetworkReply; + friend class QHttpNetworkReplyPrivate; friend class QHttpNetworkConnectionChannel; Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest()) - Q_PRIVATE_SLOT(d_func(), void _q_restartAuthPendingRequests()) }; @@ -160,11 +139,20 @@ public: static const int defaultPipelineLength; static const int defaultRePipelineLength; + enum ConnectionState { + RunningState = 0, + PausedState = 1, + }; + QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt); ~QHttpNetworkConnectionPrivate(); void init(); + void pauseConnection(); + void resumeConnection(); + ConnectionState state; + enum { ChunkSize = 4096 }; int indexOf(QAbstractSocket *socket) const; @@ -184,7 +172,6 @@ public: // private slots void _q_startNextRequest(); // send the next request from the queue - void _q_restartAuthPendingRequests(); // send the currently blocked request void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); @@ -203,9 +190,6 @@ public: const int channelCount; QHttpNetworkConnectionChannel *channels; // parallel connections to the server - bool pendingAuthSignal; // there is an incomplete authentication signal - bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal - qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const; qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 74c5844..d8530cc 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -69,8 +69,8 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel() , lastStatus(0) , pendingEncrypt(false) , reconnectAttempts(2) - , authMehtod(QAuthenticatorPrivate::None) - , proxyAuthMehtod(QAuthenticatorPrivate::None) + , authMethod(QAuthenticatorPrivate::None) + , proxyAuthMethod(QAuthenticatorPrivate::None) #ifndef QT_NO_OPENSSL , ignoreAllSslErrors(false) #endif @@ -189,6 +189,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() || (!url.password().isEmpty() && url.password() != auth.password())) { auth.setUser(url.userName()); auth.setPassword(url.password()); + emit reply->cacheCredentials(request, &auth); connection->d_func()->copyCredentials(connection->d_func()->indexOf(socket), &auth, false); } // clear the userinfo, since we use the same request for resending @@ -308,7 +309,6 @@ bool QHttpNetworkConnectionChannel::sendRequest() break; } case QHttpNetworkConnectionChannel::ReadingState: - case QHttpNetworkConnectionChannel::Wait4AuthState: // ignore _q_bytesWritten in these states // fall through default: @@ -795,8 +795,7 @@ void QHttpNetworkConnectionChannel::handleStatus() ? QNetworkReply::ProxyAuthenticationRequiredError : QNetworkReply::AuthenticationRequiredError; reply->d_func()->errorString = connection->d_func()->errorDetail(errorCode, socket); - emit connection->error(errorCode, reply->d_func()->errorString); - emit reply->finished(); + emit reply->finishedWithError(errorCode, reply->d_func()->errorString); } break; default: @@ -972,7 +971,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket { if (!socket) return; - bool send2Reply = false; QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; switch (socketError) { @@ -990,7 +988,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket closeAndResendCurrentRequest(); return; } else { - send2Reply = true; errorCode = QNetworkReply::RemoteHostClosedError; } } else { @@ -1003,7 +1000,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket closeAndResendCurrentRequest(); return; } - send2Reply = true; errorCode = QNetworkReply::TimeoutError; break; case QAbstractSocket::ProxyAuthenticationRequiredError: @@ -1019,18 +1015,14 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket } QPointer<QHttpNetworkConnection> that = connection; QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString()); - if (send2Reply) { - if (reply) { - reply->d_func()->errorString = errorString; - // this error matters only to this reply - emit reply->finishedWithError(errorCode, errorString); - } - // send the next request - QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); - } else { - // the failure affects all requests. - emit connection->error(errorCode, errorString); + + if (reply) { + reply->d_func()->errorString = errorString; + emit reply->finishedWithError(errorCode, errorString); } + // send the next request + QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); + if (that) //signal emission triggered event loop close(); } @@ -1061,7 +1053,11 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors) if (!socket) return; //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure; - emit connection->sslErrors(errors); + // Also pause the connection because socket notifiers may fire while an user + // dialog is displaying + connection->d_func()->pauseConnection(); + emit reply->sslErrors(errors); + connection->d_func()->resumeConnection(); } void QHttpNetworkConnectionChannel::_q_encryptedBytesWritten(qint64 bytes) diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 4f3a65c..07bb4a6 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -95,8 +95,7 @@ public: WritingState = 2, // writing the data WaitingState = 4, // waiting for reply ReadingState = 8, // reading the reply - Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done - BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState) + BusyState = (ConnectingState|WritingState|WaitingState|ReadingState) }; QAbstractSocket *socket; bool ssl; @@ -109,8 +108,8 @@ public: int lastStatus; // last status received on this channel bool pendingEncrypt; // for https (send after encrypted) int reconnectAttempts; // maximum 2 reconnection attempts - QAuthenticatorPrivate::Method authMehtod; - QAuthenticatorPrivate::Method proxyAuthMehtod; + QAuthenticatorPrivate::Method authMethod; + QAuthenticatorPrivate::Method proxyAuthMethod; QAuthenticator authenticator; QAuthenticator proxyAuthenticator; #ifndef QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 1c55482..3e98dcc 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -225,6 +225,11 @@ bool QHttpNetworkReply::isPipeliningUsed() const return d_func()->pipeliningUsed; } +QHttpNetworkConnection* QHttpNetworkReply::connection() +{ + return d_func()->connection; +} + QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) : QHttpNetworkHeaderPrivate(newUrl) diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 02ce248..65d1887 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -136,6 +136,8 @@ public: bool isPipeliningUsed() const; + QHttpNetworkConnection* connection(); + #ifndef QT_NO_OPENSSL QSslConfiguration sslConfiguration() const; void setSslConfiguration(const QSslConfiguration &config); @@ -154,7 +156,11 @@ Q_SIGNALS: // FIXME we need to change this to qint64! void dataReadProgress(int done, int total); void dataSendProgress(qint64 done, qint64 total); - + void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator); +#ifndef QT_NO_NETWORKPROXY + void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); +#endif + void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator); private: Q_DECLARE_PRIVATE(QHttpNetworkReply) friend class QHttpNetworkConnection; diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index c3d765b..86dd59b 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -340,7 +340,7 @@ void QNetworkAccessBackend::authenticationRequired(QAuthenticator *authenticator void QNetworkAccessBackend::cacheCredentials(QAuthenticator *authenticator) { - manager->addCredentials(this->reply->url, authenticator); + manager->cacheCredentials(this->reply->url, authenticator); } void QNetworkAccessBackend::metaDataChanged() diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 8b9a99f..afbb706 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -338,24 +338,6 @@ void QNetworkAccessHttpBackend::finished() QNetworkAccessBackend::finished(); } -void QNetworkAccessHttpBackend::setupConnection() -{ -#ifndef QT_NO_NETWORKPROXY - connect(http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), - SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); -#endif - connect(http, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)), - SLOT(httpAuthenticationRequired(QHttpNetworkRequest,QAuthenticator*))); - connect(http, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)), - SLOT(httpCacheCredentials(QHttpNetworkRequest,QAuthenticator*))); - connect(http, SIGNAL(error(QNetworkReply::NetworkError,QString)), - SLOT(httpError(QNetworkReply::NetworkError,QString))); -#ifndef QT_NO_OPENSSL - connect(http, SIGNAL(sslErrors(QList<QSslError>)), - SLOT(sslErrors(QList<QSslError>))); -#endif -} - /* For a given httpRequest 1) If AlwaysNetwork, return @@ -596,12 +578,22 @@ void QNetworkAccessHttpBackend::postRequest() if (pendingIgnoreAllSslErrors) httpReply->ignoreSslErrors(); httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList); + connect(httpReply, SIGNAL(sslErrors(QList<QSslError>)), + SLOT(sslErrors(QList<QSslError>))); #endif connect(httpReply, SIGNAL(finished()), SLOT(replyFinished())); connect(httpReply, SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)), SLOT(httpError(QNetworkReply::NetworkError,QString))); connect(httpReply, SIGNAL(headerChanged()), SLOT(replyHeaderChanged())); + connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)), + SLOT(httpCacheCredentials(QHttpNetworkRequest,QAuthenticator*))); +#ifndef QT_NO_NETWORKPROXY + connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); +#endif + connect(httpReply, SIGNAL(authenticationRequired(const QHttpNetworkRequest,QAuthenticator*)), + SLOT(httpAuthenticationRequired(const QHttpNetworkRequest,QAuthenticator*))); } void QNetworkAccessHttpBackend::invalidateCache() @@ -676,7 +668,6 @@ void QNetworkAccessHttpBackend::open() cache->addEntry(cacheKey, http); } - setupConnection(); postRequest(); } @@ -906,29 +897,6 @@ void QNetworkAccessHttpBackend::httpError(QNetworkReply::NetworkError errorCode, #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) qDebug() << "http error!" << errorCode << errorString; #endif -#if 0 - static const QNetworkReply::NetworkError conversionTable[] = { - QNetworkReply::ConnectionRefusedError, - QNetworkReply::RemoteHostClosedError, - QNetworkReply::HostNotFoundError, - QNetworkReply::UnknownNetworkError, // SocketAccessError - QNetworkReply::UnknownNetworkError, // SocketResourceError - QNetworkReply::TimeoutError, // SocketTimeoutError - QNetworkReply::UnknownNetworkError, // DatagramTooLargeError - QNetworkReply::UnknownNetworkError, // NetworkError - QNetworkReply::UnknownNetworkError, // AddressInUseError - QNetworkReply::UnknownNetworkError, // SocketAddressNotAvailableError - QNetworkReply::UnknownNetworkError, // UnsupportedSocketOperationError - QNetworkReply::UnknownNetworkError, // UnfinishedSocketOperationError - QNetworkReply::ProxyAuthenticationRequiredError - }; - QNetworkReply::NetworkError code; - if (int(errorCode) >= 0 && - uint(errorCode) < (sizeof conversionTable / sizeof conversionTable[0])) - code = conversionTable[errorCode]; - else - code = QNetworkReply::UnknownNetworkError; -#endif error(errorCode, errorString); finished(); } diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h index fb12781..ad0a7ba 100644 --- a/src/network/access/qnetworkaccesshttpbackend_p.h +++ b/src/network/access/qnetworkaccesshttpbackend_p.h @@ -126,7 +126,6 @@ private: quint64 resumeOffset; void disconnectFromHttp(); - void setupConnection(); void validateCache(QHttpNetworkRequest &httpRequest, bool &loadedFromCache); void invalidateCache(); void postRequest(); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 8c17916..5ae1078 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1014,16 +1014,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); @@ -1105,7 +1097,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); @@ -1117,7 +1111,7 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend backend->reply->urlForLastAuthentication = url; emit q->authenticationRequired(backend->reply->q_func(), authenticator); - addCredentials(url, authenticator); + cacheCredentials(url, authenticator); } #ifndef QT_NO_NETWORKPROXY @@ -1134,7 +1128,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); @@ -1144,10 +1138,10 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac 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); @@ -1184,7 +1178,7 @@ void QNetworkAccessManagerPrivate::addCredentials(const QNetworkProxy &p, } QNetworkAuthenticationCredential * -QNetworkAccessManagerPrivate::fetchCachedCredentials(const QNetworkProxy &p, +QNetworkAccessManagerPrivate::fetchCachedProxyCredentials(const QNetworkProxy &p, const QAuthenticator *authenticator) { QNetworkProxy proxy = p; @@ -1236,7 +1230,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); diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 695842c..2c6ee10 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -91,15 +91,15 @@ public: void createCookieJar() const; void authenticationRequired(QNetworkAccessBackend *backend, QAuthenticator *authenticator); - void addCredentials(const QUrl &url, const QAuthenticator *auth); + void cacheCredentials(const QUrl &url, const QAuthenticator *auth); QNetworkAuthenticationCredential *fetchCachedCredentials(const QUrl &url, const QAuthenticator *auth = 0); #ifndef QT_NO_NETWORKPROXY void proxyAuthenticationRequired(QNetworkAccessBackend *backend, const QNetworkProxy &proxy, QAuthenticator *authenticator); - void addCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth); - QNetworkAuthenticationCredential *fetchCachedCredentials(const QNetworkProxy &proxy, + void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth); + QNetworkAuthenticationCredential *fetchCachedProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth = 0); QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query); #endif diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 09ec4c2..deb678a 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -194,16 +194,12 @@ QT_BEGIN_NAMESPACE \value CookieLoadControlAttribute Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) Indicates whether to send 'Cookie' headers in the request. - This attribute is set to false by QtWebKit when creating a cross-origin XMLHttpRequest where withCredentials has not been set explicitly to true by the Javascript that created the request. - See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag}{here} for more information. - (This value was introduced in 4.7.) - \value CookieSaveControlAttribute Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) Indicates whether to save 'Cookie' headers received from the server in reply @@ -211,9 +207,7 @@ QT_BEGIN_NAMESPACE This attribute is set to false by QtWebKit when creating a cross-origin XMLHttpRequest where withCredentials has not been set explicitly to true by the Javascript that created the request. - See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information. - (This value was introduced in 4.7.) \value AuthenticationReuseAttribute @@ -225,16 +219,12 @@ QT_BEGIN_NAMESPACE This attribute is set to QNetworkRequest::Manual by QtWebKit when creating a cross-origin XMLHttpRequest where withCredentials has not been set explicitly to true by the Javascript that created the request. - See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information. - (This value was introduced in 4.7.) \omitvalue MaximumDownloadBufferSizeAttribute - (This value was introduced in 4.7.) \omitvalue DownloadBufferAttribute - (This value was introduced in 4.7.) \value User Special type. Additional information can be passed in |