Changeset 846 for trunk/src/network/access
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 57 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/network/access/access.pri
r561 r846 1 1 # Qt network access module 2 2 3 HEADERS += access/qftp.h \ 4 access/qhttp.h \ 5 access/qhttpnetworkheader_p.h \ 6 access/qhttpnetworkrequest_p.h \ 7 access/qhttpnetworkreply_p.h \ 8 access/qhttpnetworkconnection_p.h \ 9 access/qhttpnetworkconnectionchannel_p.h \ 10 access/qfilenetworkreply_p.h \ 11 access/qnetworkaccessmanager.h \ 12 access/qnetworkaccessmanager_p.h \ 13 access/qnetworkaccesscache_p.h \ 14 access/qnetworkaccessbackend_p.h \ 15 access/qnetworkaccessdatabackend_p.h \ 16 access/qnetworkaccessdebugpipebackend_p.h \ 17 access/qnetworkaccesshttpbackend_p.h \ 18 access/qnetworkaccessfilebackend_p.h \ 19 access/qnetworkaccesscachebackend_p.h \ 20 access/qnetworkaccessftpbackend_p.h \ 21 access/qnetworkcookie.h \ 22 access/qnetworkcookie_p.h \ 23 access/qnetworkcookiejar.h \ 24 access/qnetworkcookiejar_p.h \ 25 access/qnetworkrequest.h \ 26 access/qnetworkrequest_p.h \ 27 access/qnetworkreply.h \ 28 access/qnetworkreply_p.h \ 29 access/qnetworkreplyimpl_p.h \ 30 access/qabstractnetworkcache_p.h \ 31 access/qabstractnetworkcache.h \ 32 access/qnetworkdiskcache_p.h \ 33 access/qnetworkdiskcache.h 3 HEADERS += \ 4 access/qftp.h \ 5 access/qhttp.h \ 6 access/qhttpnetworkheader_p.h \ 7 access/qhttpnetworkrequest_p.h \ 8 access/qhttpnetworkreply_p.h \ 9 access/qhttpnetworkconnection_p.h \ 10 access/qhttpnetworkconnectionchannel_p.h \ 11 access/qfilenetworkreply_p.h \ 12 access/qnetworkaccessmanager.h \ 13 access/qnetworkaccessmanager_p.h \ 14 access/qnetworkaccesscache_p.h \ 15 access/qnetworkaccessbackend_p.h \ 16 access/qnetworkaccessdatabackend_p.h \ 17 access/qnetworkaccessdebugpipebackend_p.h \ 18 access/qnetworkaccesshttpbackend_p.h \ 19 access/qnetworkaccessfilebackend_p.h \ 20 access/qnetworkaccesscachebackend_p.h \ 21 access/qnetworkaccessftpbackend_p.h \ 22 access/qnetworkcookie.h \ 23 access/qnetworkcookie_p.h \ 24 access/qnetworkcookiejar.h \ 25 access/qnetworkcookiejar_p.h \ 26 access/qnetworkcookiejartlds_p.h \ 27 access/qnetworkrequest.h \ 28 access/qnetworkrequest_p.h \ 29 access/qnetworkreply.h \ 30 access/qnetworkreply_p.h \ 31 access/qnetworkreplyimpl_p.h \ 32 access/qabstractnetworkcache_p.h \ 33 access/qabstractnetworkcache.h \ 34 access/qnetworkdiskcache_p.h \ 35 access/qnetworkdiskcache.h 34 36 35 SOURCES += access/qftp.cpp \ 36 access/qhttp.cpp \ 37 access/qhttpnetworkheader.cpp \ 38 access/qhttpnetworkrequest.cpp \ 39 access/qhttpnetworkreply.cpp \ 40 access/qhttpnetworkconnection.cpp \ 41 access/qhttpnetworkconnectionchannel.cpp \ 42 access/qfilenetworkreply.cpp \ 43 access/qnetworkaccessmanager.cpp \ 44 access/qnetworkaccesscache.cpp \ 45 access/qnetworkaccessbackend.cpp \ 46 access/qnetworkaccessdatabackend.cpp \ 47 access/qnetworkaccessdebugpipebackend.cpp \ 48 access/qnetworkaccessfilebackend.cpp \ 49 access/qnetworkaccesscachebackend.cpp \ 50 access/qnetworkaccessftpbackend.cpp \ 51 access/qnetworkaccesshttpbackend.cpp \ 52 access/qnetworkcookie.cpp \ 53 access/qnetworkcookiejar.cpp \ 54 access/qnetworkrequest.cpp \ 55 access/qnetworkreply.cpp \ 56 access/qnetworkreplyimpl.cpp \ 57 access/qabstractnetworkcache.cpp \ 58 access/qnetworkdiskcache.cpp 37 SOURCES += \ 38 access/qftp.cpp \ 39 access/qhttp.cpp \ 40 access/qhttpnetworkheader.cpp \ 41 access/qhttpnetworkrequest.cpp \ 42 access/qhttpnetworkreply.cpp \ 43 access/qhttpnetworkconnection.cpp \ 44 access/qhttpnetworkconnectionchannel.cpp \ 45 access/qfilenetworkreply.cpp \ 46 access/qnetworkaccessmanager.cpp \ 47 access/qnetworkaccesscache.cpp \ 48 access/qnetworkaccessbackend.cpp \ 49 access/qnetworkaccessdatabackend.cpp \ 50 access/qnetworkaccessdebugpipebackend.cpp \ 51 access/qnetworkaccessfilebackend.cpp \ 52 access/qnetworkaccesscachebackend.cpp \ 53 access/qnetworkaccessftpbackend.cpp \ 54 access/qnetworkaccesshttpbackend.cpp \ 55 access/qnetworkcookie.cpp \ 56 access/qnetworkcookiejar.cpp \ 57 access/qnetworkrequest.cpp \ 58 access/qnetworkreply.cpp \ 59 access/qnetworkreplyimpl.cpp \ 60 access/qabstractnetworkcache.cpp \ 61 access/qnetworkdiskcache.cpp 59 62 60 #zlib support 61 contains(QT_CONFIG, zlib) { 62 INCLUDEPATH += ../3rdparty/zlib 63 } else:!contains(QT_CONFIG, no-zlib) { 64 unix:LIBS_PRIVATE += -lz 65 # win32:LIBS += libz.lib 66 } 63 include($$PWD/../../3rdparty/zlib_dependency.pri) -
trunk/src/network/access/qabstractnetworkcache.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 313 313 Writes \a metaData to the \a out stream. 314 314 315 \sa { Format of the QDataStream operators}315 \sa {Serializing Qt Data Types} 316 316 */ 317 317 QDataStream &operator<<(QDataStream &out, const QNetworkCacheMetaData &metaData) … … 351 351 Reads a QNetworkCacheMetaData from the stream \a in into \a metaData. 352 352 353 \sa { Format of the QDataStream operators}353 \sa {Serializing Qt Data Types} 354 354 */ 355 355 QDataStream &operator>>(QDataStream &in, QNetworkCacheMetaData &metaData) -
trunk/src/network/access/qabstractnetworkcache.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qabstractnetworkcache_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qfilenetworkreply.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 98 98 QString fileName = url.toLocalFile(); 99 99 if (fileName.isEmpty()) { 100 fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); 100 if (url.scheme() == QLatin1String("qrc")) 101 fileName = QLatin1Char(':') + url.path(); 102 else 103 fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); 101 104 } 102 105 -
trunk/src/network/access/qfilenetworkreply_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qftp.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 2312 2312 2313 2313 if (pending.isEmpty()) { 2314 qWarning( ) << "QFtpPrivate::_q_piError was called without pending command!";2314 qWarning("QFtpPrivate::_q_piError was called without pending command!"); 2315 2315 return; 2316 2316 } -
trunk/src/network/access/qftp.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qhttp.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 2443 2443 proxy.setType(QNetworkProxy::NoProxy); 2444 2444 } else if (sslInUse) { 2445 // Disallow use of cach eing proxy with HTTPS; instead fall back to2445 // Disallow use of caching proxy with HTTPS; instead fall back to 2446 2446 // transparent HTTP CONNECT proxying. 2447 2447 transparentProxyInUse = true; -
trunk/src/network/access/qhttp.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qhttpnetworkconnection.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 40 40 ****************************************************************************/ 41 41 42 #include <private/qabstractsocket_p.h> 42 43 #include "qhttpnetworkconnection_p.h" 43 44 #include "qhttpnetworkconnectionchannel_p.h" … … 57 58 58 59 #ifndef QT_NO_OPENSSL 60 # include <private/qsslsocket_p.h> 59 61 # include <QtNetwork/qsslkey.h> 60 62 # include <QtNetwork/qsslcipher.h> … … 80 82 81 83 QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt) 82 : hostName(hostName), port(port), encrypt(encrypt),83 channelCount(defaultChannelCount),84 pendingAuthSignal(false), pendingProxyAuthSignal(false)84 : state(RunningState), 85 hostName(hostName), port(port), encrypt(encrypt), 86 channelCount(defaultChannelCount) 85 87 #ifndef QT_NO_NETWORKPROXY 86 88 , networkProxy(QNetworkProxy::NoProxy) … … 91 93 92 94 QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt) 93 : hostName(hostName), port(port), encrypt(encrypt),94 channelCount(channelCount),95 pendingAuthSignal(false), pendingProxyAuthSignal(false)95 : state(RunningState), 96 hostName(hostName), port(port), encrypt(encrypt), 97 channelCount(channelCount) 96 98 #ifndef QT_NO_NETWORKPROXY 97 99 , networkProxy(QNetworkProxy::NoProxy) … … 120 122 channels[i].init(); 121 123 } 124 } 125 126 void QHttpNetworkConnectionPrivate::pauseConnection() 127 { 128 state = PausedState; 129 130 // Disable all socket notifiers 131 for (int i = 0; i < channelCount; i++) { 132 #ifndef QT_NO_OPENSSL 133 if (encrypt) 134 QSslSocketPrivate::pauseSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket)); 135 else 136 #endif 137 QAbstractSocketPrivate::pauseSocketNotifiers(channels[i].socket); 138 } 139 } 140 141 void QHttpNetworkConnectionPrivate::resumeConnection() 142 { 143 state = RunningState; 144 // Enable all socket notifiers 145 for (int i = 0; i < channelCount; i++) { 146 #ifndef QT_NO_OPENSSL 147 if (encrypt) 148 QSslSocketPrivate::resumeSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket)); 149 else 150 #endif 151 QAbstractSocketPrivate::resumeSocketNotifiers(channels[i].socket); 152 153 // Resume pending upload if needed 154 if (channels[i].state == QHttpNetworkConnectionChannel::WritingState) 155 QMetaObject::invokeMethod(&channels[i], "_q_uploadDataReadyRead", Qt::QueuedConnection); 156 } 157 158 // queue _q_startNextRequest 159 QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection); 122 160 } 123 161 … … 258 296 Q_ASSERT(auth); 259 297 298 // NTLM is a multi phase authentication. Copying credentials between authenticators would mess things up. 299 if (!isProxy && channels[fromChannel].authMethod == QAuthenticatorPrivate::Ntlm) 300 return; 301 if (isProxy && channels[fromChannel].proxyAuthMethod == QAuthenticatorPrivate::Ntlm) 302 return; 303 304 260 305 // select another channel 261 306 QAuthenticator* otherAuth = 0; … … 283 328 Q_ASSERT(reply); 284 329 285 Q_Q(QHttpNetworkConnection);286 287 330 resend = false; 288 331 //create the response header to be used with QAuthenticatorPrivate. 289 QHttpResponseHeader responseHeader;290 332 QList<QPair<QByteArray, QByteArray> > fields = reply->header(); 291 QList<QPair<QByteArray, QByteArray> >::const_iterator it = fields.constBegin(); 292 while (it != fields.constEnd()) { 293 responseHeader.addValue(QString::fromLatin1(it->first), QString::fromUtf8(it->second)); 294 it++; 295 } 333 296 334 //find out the type of authentication protocol requested. 297 335 QAuthenticatorPrivate::Method authMethod = reply->d_func()->authenticationMethod(isProxy); … … 302 340 if (isProxy) { 303 341 auth = &channels[i].proxyAuthenticator; 304 channels[i].proxyAuthMe htod = authMethod;342 channels[i].proxyAuthMethod = authMethod; 305 343 } else { 306 344 auth = &channels[i].authenticator; 307 channels[i].authMe htod = authMethod;345 channels[i].authMethod = authMethod; 308 346 } 309 347 //proceed with the authentication. … … 311 349 auth->detach(); 312 350 QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*auth); 313 priv->parseHttpResponse( responseHeader, isProxy);351 priv->parseHttpResponse(fields, isProxy); 314 352 315 353 if (priv->phase == QAuthenticatorPrivate::Done) { 316 if ((isProxy && pendingProxyAuthSignal) ||(!isProxy && pendingAuthSignal)) { 317 // drop the request 318 reply->d_func()->eraseData(); 319 channels[i].close(); 320 channels[i].lastStatus = 0; 321 channels[i].state = QHttpNetworkConnectionChannel::Wait4AuthState; 322 return false; 323 } 324 // cannot use this socket until the slot returns 325 channels[i].state = QHttpNetworkConnectionChannel::WaitingState; 326 socket->blockSignals(true); 354 pauseConnection(); 327 355 if (!isProxy) { 328 pendingAuthSignal = true; 329 emit q->authenticationRequired(reply->request(), auth, q); 330 pendingAuthSignal = false; 356 emit reply->authenticationRequired(reply->request(), auth); 331 357 #ifndef QT_NO_NETWORKPROXY 332 358 } else { 333 pendingProxyAuthSignal = true; 334 emit q->proxyAuthenticationRequired(networkProxy, auth, q); 335 pendingProxyAuthSignal = false; 359 emit reply->proxyAuthenticationRequired(networkProxy, auth); 336 360 #endif 337 361 } 338 socket->blockSignals(false); 339 // socket free to use 340 channels[i].state = QHttpNetworkConnectionChannel::IdleState; 362 resumeConnection(); 363 341 364 if (priv->phase != QAuthenticatorPrivate::Done) { 342 365 // send any pending requests 343 366 copyCredentials(i, auth, isProxy); 344 QMetaObject::invokeMethod(q, "_q_restartAuthPendingRequests", Qt::QueuedConnection);345 367 } 346 368 } 347 // changing values in QAuthenticator will reset the 'phase' 348 if (priv->phase == QAuthenticatorPrivate::Done) { 369 // - Changing values in QAuthenticator will reset the 'phase'. Therefore if it is still "Done" 370 // then nothing was filled in by the user or the cache 371 // - If withCredentials has been set to false (e.g. by QtWebKit for a cross-origin XMLHttpRequest) then 372 // we need to bail out if authentication is required. 373 if (priv->phase == QAuthenticatorPrivate::Done || !reply->request().withCredentials()) { 374 // Reset authenticator so the next request on that channel does not get messed up 375 auth = 0; 376 if (isProxy) 377 channels[i].proxyAuthenticator = QAuthenticator(); 378 else 379 channels[i].authenticator = QAuthenticator(); 380 349 381 // authentication is cancelled, send the current contents to the user. 350 382 emit channels[i].reply->headerChanged(); … … 355 387 : QNetworkReply::AuthenticationRequiredError; 356 388 reply->d_func()->errorString = errorDetail(errorCode, socket); 357 emit q->error(errorCode, reply->d_func()->errorString); 358 emit channels[i].reply->finished(); 389 emit reply->finishedWithError(errorCode, reply->d_func()->errorString); 359 390 // ### at this point the reply could be deleted 360 391 socket->close(); 361 // remove pending request on the other channels362 for (int j = 0; j < channelCount; ++j) {363 if (j != i && channels[j].state == QHttpNetworkConnectionChannel::Wait4AuthState)364 channels[j].state = QHttpNetworkConnectionChannel::IdleState;365 }366 392 return true; 367 393 } … … 379 405 int i = indexOf(socket); 380 406 381 if (channels[i].authMehtod != QAuthenticatorPrivate::None) { 382 if (!(channels[i].authMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) { 407 // Send "Authorization" header, but not if it's NTLM and the socket is already authenticated. 408 if (channels[i].authMethod != QAuthenticatorPrivate::None) { 409 if (!(channels[i].authMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) { 383 410 QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator); 384 411 if (priv && priv->method != QAuthenticatorPrivate::None) { … … 388 415 } 389 416 } 390 if (channels[i].proxyAuthMehtod != QAuthenticatorPrivate::None) { 391 if (!(channels[i].proxyAuthMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) { 417 418 // Send "Proxy-Authorization" header, but not if it's NTLM and the socket is already authenticated. 419 if (channels[i].proxyAuthMethod != QAuthenticatorPrivate::None) { 420 if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) { 392 421 QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator); 393 422 if (priv && priv->method != QAuthenticatorPrivate::None) { … … 652 681 if (channels[i].reply == reply) { 653 682 channels[i].reply = 0; 683 channels[i].request = QHttpNetworkRequest(); 684 channels[i].resendCurrent = false; 654 685 655 686 if (!reply->isFinished() && !channels[i].alreadyPipelinedRequests.isEmpty()) { … … 720 751 void QHttpNetworkConnectionPrivate::_q_startNextRequest() 721 752 { 753 // If the QHttpNetworkConnection is currently paused then bail out immediately 754 if (state == PausedState) 755 return; 756 722 757 //resend the necessary ones. 723 758 for (int i = 0; i < channelCount; ++i) { … … 740 775 // try to get a free AND connected socket 741 776 for (int i = 0; i < channelCount; ++i) { 742 if (!channels[i]. isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) {777 if (!channels[i].reply && !channels[i].isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) { 743 778 dequeueAndSendRequest(channels[i].socket); 744 779 } … … 750 785 // try to get a free unconnected socket 751 786 for (int i = 0; i < channelCount; ++i) { 752 if (!channels[i]. isSocketBusy()) {787 if (!channels[i].reply && !channels[i].isSocketBusy()) { 753 788 dequeueAndSendRequest(channels[i].socket); 754 789 } … … 770 805 } 771 806 772 void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests()773 {774 // send the request using the idle socket775 for (int i = 0 ; i < channelCount; ++i) {776 if (channels[i].state == QHttpNetworkConnectionChannel::Wait4AuthState) {777 channels[i].state = QHttpNetworkConnectionChannel::IdleState;778 if (channels[i].reply)779 channels[i].sendRequest();780 }781 }782 }783 807 784 808 void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply) … … 829 853 } 830 854 831 void QHttpNetworkConnection::enableEncryption() 832 { 833 Q_D(QHttpNetworkConnection); 834 d->encrypt = true; 835 } 836 837 bool QHttpNetworkConnection::isEncrypted() const 855 bool QHttpNetworkConnection::isSsl() const 838 856 { 839 857 Q_D(const QHttpNetworkConnection); … … 841 859 } 842 860 843 void QHttpNetworkConnection::setProxyAuthentication(QAuthenticator *authenticator) 844 { 845 Q_D(QHttpNetworkConnection); 846 for (int i = 0; i < d->channelCount; ++i) 847 d->channels[i].proxyAuthenticator = *authenticator; 848 } 849 850 void QHttpNetworkConnection::setAuthentication(const QString &domain, QAuthenticator *authenticator) 851 { 852 Q_UNUSED(domain); // ### domain ? 853 Q_D(QHttpNetworkConnection); 854 for (int i = 0; i < d->channelCount; ++i) 855 d->channels[i].authenticator = *authenticator; 861 QHttpNetworkConnectionChannel *QHttpNetworkConnection::channels() const 862 { 863 return d_func()->channels; 856 864 } 857 865 … … 948 956 void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth) 949 957 { 950 Q_Q(QHttpNetworkConnection); 951 emit q->proxyAuthenticationRequired(proxy, auth, q); 958 // Also pause the connection because socket notifiers may fire while an user 959 // dialog is displaying 960 pauseConnection(); 961 emit chan->reply->proxyAuthenticationRequired(proxy, auth); 962 resumeConnection(); 952 963 int i = indexOf(chan->socket); 953 964 copyCredentials(i, auth, true); -
trunk/src/network/access/qhttpnetworkconnection_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 109 109 #endif 110 110 111 //enable encryption 112 void enableEncryption(); 113 bool isEncrypted() const; 114 115 //authentication parameters 116 void setProxyAuthentication(QAuthenticator *authenticator); 117 void setAuthentication(const QString &domain, QAuthenticator *authenticator); 111 bool isSsl() const; 112 113 QHttpNetworkConnectionChannel *channels() const; 118 114 119 115 #ifndef QT_NO_OPENSSL … … 121 117 void ignoreSslErrors(int channel = -1); 122 118 void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1); 123 124 Q_SIGNALS: 125 void sslErrors(const QList<QSslError> &errors); 126 #endif 127 128 Q_SIGNALS: 129 #ifndef QT_NO_NETWORKPROXY 130 //cannot be used with queued connection. 131 void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator, 132 const QHttpNetworkConnection *connection = 0); 133 #endif 134 void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator, 135 const QHttpNetworkConnection *connection = 0); 136 void error(QNetworkReply::NetworkError errorCode, const QString &detail = QString()); 119 #endif 137 120 138 121 private: … … 140 123 Q_DISABLE_COPY(QHttpNetworkConnection) 141 124 friend class QHttpNetworkReply; 125 friend class QHttpNetworkReplyPrivate; 142 126 friend class QHttpNetworkConnectionChannel; 143 127 144 128 Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest()) 145 Q_PRIVATE_SLOT(d_func(), void _q_restartAuthPendingRequests())146 129 }; 147 130 … … 159 142 static const int defaultRePipelineLength; 160 143 144 enum ConnectionState { 145 RunningState = 0, 146 PausedState = 1, 147 }; 148 161 149 QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); 162 150 QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt); … … 164 152 void init(); 165 153 154 void pauseConnection(); 155 void resumeConnection(); 156 ConnectionState state; 157 166 158 enum { ChunkSize = 4096 }; 167 159 … … 183 175 // private slots 184 176 void _q_startNextRequest(); // send the next request from the queue 185 void _q_restartAuthPendingRequests(); // send the currently blocked request186 177 187 178 void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); … … 202 193 QHttpNetworkConnectionChannel *channels; // parallel connections to the server 203 194 204 bool pendingAuthSignal; // there is an incomplete authentication signal205 bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal206 207 195 qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const; 208 196 qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const; -
trunk/src/network/access/qhttpnetworkconnectionchannel.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 69 69 , pendingEncrypt(false) 70 70 , reconnectAttempts(2) 71 , authMe htod(QAuthenticatorPrivate::None)72 , proxyAuthMe htod(QAuthenticatorPrivate::None)71 , authMethod(QAuthenticatorPrivate::None) 72 , proxyAuthMethod(QAuthenticatorPrivate::None) 73 73 #ifndef QT_NO_OPENSSL 74 74 , ignoreAllSslErrors(false) … … 106 106 this, SLOT(_q_readyRead()), 107 107 Qt::DirectConnection); 108 109 // The disconnected() and error() signals may already come 110 // while calling connectToHost(). 111 // In case of a cached hostname or an IP this 112 // will then emit a signal to the user of QNetworkReply 113 // but cannot be caught because the user did not have a chance yet 114 // to connect to QNetworkReply's signals. 115 qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); 108 116 QObject::connect(socket, SIGNAL(disconnected()), 109 117 this, SLOT(_q_disconnected()), 110 Qt:: DirectConnection);118 Qt::QueuedConnection); 111 119 QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), 112 120 this, SLOT(_q_error(QAbstractSocket::SocketError)), 113 Qt::DirectConnection); 121 Qt::QueuedConnection); 122 123 114 124 #ifndef QT_NO_NETWORKPROXY 115 125 QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), … … 171 181 reply->d_func()->pipeliningUsed = false; 172 182 173 pendingEncrypt = false;174 183 // if the url contains authentication parameters, use the new ones 175 184 // both channels will use the new authentication parameters 176 if (!request.url().userInfo().isEmpty() ) {185 if (!request.url().userInfo().isEmpty() && request.withCredentials()) { 177 186 QUrl url = request.url(); 178 187 QAuthenticator &auth = authenticator; … … 181 190 auth.setUser(url.userName()); 182 191 auth.setPassword(url.password()); 192 emit reply->cacheCredentials(request, &auth); 183 193 connection->d_func()->copyCredentials(connection->d_func()->indexOf(socket), &auth, false); 184 194 } … … 188 198 request.setUrl(url); 189 199 } 190 connection->d_func()->createAuthorization(socket, request); 200 // Will only be false if QtWebKit is performing a cross-origin XMLHttpRequest 201 // and withCredentials has not been set to true. 202 if (request.withCredentials()) 203 connection->d_func()->createAuthorization(socket, request); 191 204 #ifndef QT_NO_NETWORKPROXY 192 205 QByteArray header = QHttpNetworkRequestPrivate::header(request, … … 297 310 } 298 311 case QHttpNetworkConnectionChannel::ReadingState: 299 case QHttpNetworkConnectionChannel::Wait4AuthState:300 312 // ignore _q_bytesWritten in these states 301 313 // fall through … … 400 412 case QHttpNetworkReplyPrivate::ReadingDataState: { 401 413 QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); 402 if (replyPrivate->downstreamLimited && !replyPrivate->responseData.isEmpty() && replyPrivate->shouldEmitSignals()) { 414 if (socket->state() == QAbstractSocket::ConnectedState && 415 replyPrivate->downstreamLimited && !replyPrivate->responseData.isEmpty() && replyPrivate->shouldEmitSignals()) { 416 // (only do the following when still connected, not when we have already been disconnected and there is still data) 403 417 // We already have some HTTP body data. We don't read more from the socket until 404 418 // this is fetched by QHttpNetworkAccessHttpBackend. If we would read more, … … 409 423 return; 410 424 } 411 412 425 if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress 413 426 && replyPrivate->bodyLength > 0) { … … 645 658 // Note that this may trigger a segfault at some other point. But then we can fix the underlying 646 659 // problem. 647 if (!resendCurrent) 660 if (!resendCurrent) { 661 request = QHttpNetworkRequest(); 648 662 reply = 0; 663 } 649 664 650 665 // move next from pipeline to current request … … 680 695 QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); 681 696 } else if (alreadyPipelinedRequests.isEmpty()) { 682 QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); 697 if (qobject_cast<QHttpNetworkConnection*>(connection)) 698 QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); 683 699 } 684 700 } … … 782 798 : QNetworkReply::AuthenticationRequiredError; 783 799 reply->d_func()->errorString = connection->d_func()->errorDetail(errorCode, socket); 784 emit connection->error(errorCode, reply->d_func()->errorString); 785 emit reply->finished(); 800 emit reply->finishedWithError(errorCode, reply->d_func()->errorString); 786 801 } 787 802 break; 788 803 default: 789 QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); 804 if (qobject_cast<QHttpNetworkConnection*>(connection)) 805 QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); 790 806 } 791 807 } … … 835 851 close(); 836 852 resendCurrent = true; 837 QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); 853 if (qobject_cast<QHttpNetworkConnection*>(connection)) 854 QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); 838 855 } 839 856 … … 928 945 if (!socket) 929 946 return; 930 bool send2Reply = false;931 947 QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; 932 948 … … 946 962 return; 947 963 } else { 948 send2Reply = true;949 964 errorCode = QNetworkReply::RemoteHostClosedError; 950 965 } … … 959 974 return; 960 975 } 961 send2Reply = true;962 976 errorCode = QNetworkReply::TimeoutError; 963 977 break; … … 975 989 QPointer<QHttpNetworkConnection> that = connection; 976 990 QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString()); 977 if (send2Reply) { 978 if (reply) { 979 reply->d_func()->errorString = errorString; 980 // this error matters only to this reply 981 emit reply->finishedWithError(errorCode, errorString); 982 } 983 // send the next request 984 QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); 985 } else { 986 // the failure affects all requests. 987 emit connection->error(errorCode, errorString); 988 } 991 992 if (reply) { 993 reply->d_func()->errorString = errorString; 994 emit reply->finishedWithError(errorCode, errorString); 995 } 996 // send the next request 997 QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); 998 989 999 if (that) //signal emission triggered event loop 990 1000 close(); … … 1009 1019 return; // ### error 1010 1020 state = QHttpNetworkConnectionChannel::IdleState; 1021 pendingEncrypt = false; 1011 1022 sendRequest(); 1012 1023 } … … 1017 1028 return; 1018 1029 //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure; 1019 emit connection->sslErrors(errors); 1030 // Also pause the connection because socket notifiers may fire while an user 1031 // dialog is displaying 1032 connection->d_func()->pauseConnection(); 1033 emit reply->sslErrors(errors); 1034 connection->d_func()->resumeConnection(); 1020 1035 } 1021 1036 -
trunk/src/network/access/qhttpnetworkconnectionchannel_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 96 96 WaitingState = 4, // waiting for reply 97 97 ReadingState = 8, // reading the reply 98 Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done 99 BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState) 98 BusyState = (ConnectingState|WritingState|WaitingState|ReadingState) 100 99 }; 101 100 QAbstractSocket *socket; … … 109 108 bool pendingEncrypt; // for https (send after encrypted) 110 109 int reconnectAttempts; // maximum 2 reconnection attempts 111 QAuthenticatorPrivate::Method authMe htod;112 QAuthenticatorPrivate::Method proxyAuthMe htod;110 QAuthenticatorPrivate::Method authMethod; 111 QAuthenticatorPrivate::Method proxyAuthMethod; 113 112 QAuthenticator authenticator; 114 113 QAuthenticator proxyAuthenticator; … … 160 159 bool isSocketReading() const; 161 160 161 friend class QNetworkAccessHttpBackend; 162 162 163 protected slots: 163 164 void _q_receiveReply(); -
trunk/src/network/access/qhttpnetworkheader.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 61 61 { 62 62 bool ok = false; 63 QByteArray value = headerField("content-length"); 63 // We are not using the headerField() method here because servers might send us multiple content-length 64 // headers which is crap (see QTBUG-15311). Therefore just take the first content-length header field. 65 QByteArray value; 66 QList<QPair<QByteArray, QByteArray> >::ConstIterator it = fields.constBegin(), 67 end = fields.constEnd(); 68 for ( ; it != end; ++it) 69 if (qstricmp("content-length", it->first) == 0) { 70 value = it->second; 71 break; 72 } 73 64 74 qint64 length = value.toULongLong(&ok); 65 75 if (ok) -
trunk/src/network/access/qhttpnetworkheader_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qhttpnetworkreply.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 189 189 } 190 190 191 QByteArray QHttpNetworkReply::readAll() 192 { 193 Q_D(QHttpNetworkReply); 194 return d->responseData.readAll(); 195 } 196 191 197 void QHttpNetworkReply::setDownstreamLimited(bool dsl) 192 198 { … … 204 210 { 205 211 return d_func()->pipeliningUsed; 212 } 213 214 QHttpNetworkConnection* QHttpNetworkReply::connection() 215 { 216 return d_func()->connection; 206 217 } 207 218 -
trunk/src/network/access/qhttpnetworkreply_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 127 127 qint64 bytesAvailableNextBlock() const; 128 128 QByteArray readAny(); 129 QByteArray readAll(); 129 130 void setDownstreamLimited(bool t); 130 131 … … 132 133 133 134 bool isPipeliningUsed() const; 135 136 QHttpNetworkConnection* connection(); 134 137 135 138 #ifndef QT_NO_OPENSSL … … 150 153 void dataReadProgress(int done, int total); 151 154 void dataSendProgress(qint64 done, qint64 total); 152 155 void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator); 156 #ifndef QT_NO_NETWORKPROXY 157 void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); 158 #endif 159 void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator); 153 160 private: 154 161 Q_DECLARE_PRIVATE(QHttpNetworkReply) -
trunk/src/network/access/qhttpnetworkrequest.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 50 50 QHttpNetworkRequest::Priority pri, const QUrl &newUrl) 51 51 : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(0), 52 autoDecompress(false), pipeliningAllowed(false) 52 autoDecompress(false), pipeliningAllowed(false), withCredentials(true) 53 53 { 54 54 } … … 62 62 autoDecompress = other.autoDecompress; 63 63 pipeliningAllowed = other.pipeliningAllowed; 64 customVerb = other.customVerb; 65 withCredentials = other.withCredentials; 64 66 } 65 67 … … 77 79 QByteArray QHttpNetworkRequestPrivate::methodName() const 78 80 { 79 QByteArray ba;80 81 switch (operation) { 82 case QHttpNetworkRequest::Get: 83 return "GET"; 84 break; 85 case QHttpNetworkRequest::Head: 86 return "HEAD"; 87 break; 88 case QHttpNetworkRequest::Post: 89 return "POST"; 90 break; 81 91 case QHttpNetworkRequest::Options: 82 ba += "OPTIONS"; 83 break; 84 case QHttpNetworkRequest::Get: 85 ba += "GET"; 86 break; 87 case QHttpNetworkRequest::Head: 88 ba += "HEAD"; 89 break; 90 case QHttpNetworkRequest::Post: 91 ba += "POST"; 92 return "OPTIONS"; 92 93 break; 93 94 case QHttpNetworkRequest::Put: 94 ba +="PUT";95 return "PUT"; 95 96 break; 96 97 case QHttpNetworkRequest::Delete: 97 ba +="DELETE";98 return "DELETE"; 98 99 break; 99 100 case QHttpNetworkRequest::Trace: 100 ba +="TRACE";101 return "TRACE"; 101 102 break; 102 103 case QHttpNetworkRequest::Connect: 103 ba += "CONNECT"; 104 return "CONNECT"; 105 break; 106 case QHttpNetworkRequest::Custom: 107 return customVerb; 104 108 break; 105 109 default: 106 110 break; 107 111 } 108 return ba;112 return QByteArray(); 109 113 } 110 114 … … 129 133 QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy) 130 134 { 131 QByteArray ba = request.d->methodName();132 QByteArray uri = request.d->uri(throughProxy);133 ba += ' ' + uri;134 135 QString majorVersion = QString::number(request.majorVersion());136 QString minorVersion = QString::number(request.minorVersion());137 ba += " HTTP/" + majorVersion.toLatin1() + '.' + minorVersion.toLatin1() + "\r\n";138 139 135 QList<QPair<QByteArray, QByteArray> > fields = request.header(); 136 QByteArray ba; 137 ba.reserve(40 + fields.length()*25); // very rough lower bound estimation 138 139 ba += request.d->methodName(); 140 ba += ' '; 141 ba += request.d->uri(throughProxy); 142 143 ba += " HTTP/"; 144 ba += QByteArray::number(request.majorVersion()); 145 ba += '.'; 146 ba += QByteArray::number(request.minorVersion()); 147 ba += "\r\n"; 148 140 149 QList<QPair<QByteArray, QByteArray> >::const_iterator it = fields.constBegin(); 141 for (; it != fields.constEnd(); ++it) 142 ba += it->first + ": " + it->second + "\r\n"; 150 QList<QPair<QByteArray, QByteArray> >::const_iterator endIt = fields.constEnd(); 151 for (; it != endIt; ++it) { 152 ba += it->first; 153 ba += ": "; 154 ba += it->second; 155 ba += "\r\n"; 156 } 143 157 if (request.d->operation == QHttpNetworkRequest::Post) { 144 158 // add content type, if not set in the request … … 147 161 if (!request.d->uploadByteDevice && request.d->url.hasQuery()) { 148 162 QByteArray query = request.d->url.encodedQuery(); 149 ba += "Content-Length: "+ QByteArray::number(query.size()) + "\r\n"; 150 ba += "\r\n"; 163 ba += "Content-Length: "; 164 ba += QByteArray::number(query.size()); 165 ba += "\r\n\r\n"; 151 166 ba += query; 152 167 } else { … … 231 246 } 232 247 248 QByteArray QHttpNetworkRequest::customVerb() const 249 { 250 return d->customVerb; 251 } 252 253 void QHttpNetworkRequest::setCustomVerb(const QByteArray &customVerb) 254 { 255 d->customVerb = customVerb; 256 } 257 233 258 QHttpNetworkRequest::Priority QHttpNetworkRequest::priority() const 234 259 { … … 251 276 } 252 277 278 bool QHttpNetworkRequest::withCredentials() const 279 { 280 return d->withCredentials; 281 } 282 283 void QHttpNetworkRequest::setWithCredentials(bool b) 284 { 285 d->withCredentials = b; 286 } 287 253 288 void QHttpNetworkRequest::setUploadByteDevice(QNonContiguousByteDevice *bd) 254 289 { -
trunk/src/network/access/qhttpnetworkrequest_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 73 73 Delete, 74 74 Trace, 75 Connect 75 Connect, 76 Custom 76 77 }; 77 78 … … 104 105 void setOperation(Operation operation); 105 106 107 QByteArray customVerb() const; 108 void setCustomVerb(const QByteArray &customOperation); 109 106 110 Priority priority() const; 107 111 void setPriority(Priority priority); … … 109 113 bool isPipeliningAllowed() const; 110 114 void setPipeliningAllowed(bool b); 115 116 bool withCredentials() const; 117 void setWithCredentials(bool b); 111 118 112 119 void setUploadByteDevice(QNonContiguousByteDevice *bd); … … 134 141 135 142 QHttpNetworkRequest::Operation operation; 143 QByteArray customVerb; 136 144 QHttpNetworkRequest::Priority priority; 137 145 mutable QNonContiguousByteDevice* uploadByteDevice; 138 146 bool autoDecompress; 139 147 bool pipeliningAllowed; 148 bool withCredentials; 140 149 }; 141 150 -
trunk/src/network/access/qnetworkaccessbackend.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 47 47 #include "QtCore/qhash.h" 48 48 #include "QtCore/qmutex.h" 49 #include "QtNetwork/qnetworksession.h" 49 50 50 51 #include "qnetworkaccesscachebackend_p.h" 51 52 #include "qabstractnetworkcache.h" 53 #include "qhostinfo.h" 52 54 53 55 #include "private/qnoncontiguousbytedevice_p.h" … … 87 89 const QNetworkRequest &request) 88 90 { 89 QNetworkRequest::CacheLoadControl mode =90 static_cast<QNetworkRequest::CacheLoadControl>(91 request.attribute(QNetworkRequest::CacheLoadControlAttribute,92 QNetworkRequest::PreferNetwork).toInt());93 if (mode == QNetworkRequest::AlwaysCache94 && (op == QNetworkAccessManager::GetOperation95 || op == QNetworkAccessManager::HeadOperation)) {96 QNetworkAccessBackend *backend = new QNetworkAccessCacheBackend;97 backend->manager = this;98 return backend;99 }100 101 91 if (!factoryDataShutdown) { 102 92 QMutexLocker locker(&factoryData()->mutex); … … 121 111 if (reply->outgoingDataBuffer) 122 112 device = QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer); 123 else 113 else if (reply->outgoingData) { 124 114 device = QNonContiguousByteDeviceFactory::create(reply->outgoingData); 115 } else { 116 return 0; 117 } 125 118 126 119 bool bufferDisallowed = … … 150 143 : manager(0) 151 144 , reply(0) 145 , synchronous(false) 152 146 { 153 147 } … … 321 315 { 322 316 manager->authenticationRequired(this, authenticator); 317 } 318 319 void QNetworkAccessBackend::cacheCredentials(QAuthenticator *authenticator) 320 { 321 manager->cacheCredentials(this->reply->url, authenticator); 323 322 } 324 323 … … 342 341 } 343 342 343 #ifndef QT_NO_BEARERMANAGEMENT 344 345 /*! 346 Starts the backend. Returns true if the backend is started. Returns false if the backend 347 could not be started due to an unopened or roaming session. The caller should recall this 348 function once the session has been opened or the roaming process has finished. 349 */ 350 bool QNetworkAccessBackend::start() 351 { 352 if (!manager->networkSession) { 353 open(); 354 return true; 355 } 356 357 // This is not ideal. 358 const QString host = reply->url.host(); 359 if (host == QLatin1String("localhost") || 360 QHostAddress(host) == QHostAddress::LocalHost || 361 QHostAddress(host) == QHostAddress::LocalHostIPv6) { 362 // Don't need an open session for localhost access. 363 open(); 364 return true; 365 } 366 367 if (manager->networkSession->isOpen() && 368 manager->networkSession->state() == QNetworkSession::Connected) { 369 open(); 370 return true; 371 } 372 373 return false; 374 } 375 #endif 376 344 377 QT_END_NAMESPACE -
trunk/src/network/access/qnetworkaccessbackend_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 112 112 113 113 virtual void open() = 0; 114 #ifndef QT_NO_BEARERMANAGEMENT 115 virtual bool start(); 116 #endif 114 117 virtual void closeDownstreamChannel() = 0; 115 virtual bool waitForDownstreamReadyRead(int msecs) = 0;116 118 117 119 // slot-like: … … 156 158 void setAttribute(QNetworkRequest::Attribute code, const QVariant &value); 157 159 160 bool isSynchronous() { return synchronous; } 161 void setSynchronous(bool sync) { synchronous = sync; } 162 158 163 // return true if the QNonContiguousByteDevice of the upload 159 164 // data needs to support reset(). Currently needed for HTTP. 160 165 // This will possibly enable buffering of the upload data. 161 166 virtual bool needsResetableUploadData() { return false; } 167 168 // Returns true if backend is able to resume downloads. 169 virtual bool canResume() const { return false; } 170 virtual void setResumeOffset(quint64 offset) { Q_UNUSED(offset); } 171 172 virtual bool processRequestSynchronously() { return false; } 162 173 163 174 protected: … … 182 193 #endif 183 194 void authenticationRequired(QAuthenticator *auth); 195 void cacheCredentials(QAuthenticator *auth); 184 196 void metaDataChanged(); 185 197 void redirectionRequested(const QUrl &destination); … … 191 203 friend class QNetworkAccessManagerPrivate; 192 204 friend class QNetworkAccessBackendUploadIODevice; 205 friend class QNetworkReplyImplPrivate; 193 206 QNetworkAccessManagerPrivate *manager; 194 207 QNetworkReplyImplPrivate *reply; 208 bool synchronous; 195 209 }; 196 210 -
trunk/src/network/access/qnetworkaccesscache.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qnetworkaccesscache_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qnetworkaccesscachebackend.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 133 133 } 134 134 135 bool QNetworkAccessCacheBackend::waitForDownstreamReadyRead(int)136 {137 Q_ASSERT_X(false, Q_FUNC_INFO , "This function show not have been called!");138 return false;139 }140 141 bool QNetworkAccessCacheBackend::waitForUpstreamBytesWritten(int)142 {143 Q_ASSERT_X(false, Q_FUNC_INFO, "This function show not have been called!");144 return false;145 }146 147 135 void QNetworkAccessCacheBackend::upstreamReadyRead() 148 136 { -
trunk/src/network/access/qnetworkaccesscachebackend_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 70 70 void closeDownstreamChannel(); 71 71 void closeUpstreamChannel(); 72 bool waitForDownstreamReadyRead(int msecs);73 bool waitForUpstreamBytesWritten(int msecs);74 72 75 73 void upstreamReadyRead(); -
trunk/src/network/access/qnetworkaccessdatabackend.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #include "qnetworkreply.h" 45 45 #include "qurlinfo.h" 46 #include "private/qdataurl_p.h" 47 #include <qcoreapplication.h> 46 48 47 49 QT_BEGIN_NAMESPACE … … 72 74 operation() != QNetworkAccessManager::HeadOperation) { 73 75 // data: doesn't support anything but GET 74 QString msg = QObject::tr("Operation not supported on %1") 76 const QString msg = QCoreApplication::translate("QNetworkAccessDataBackend", 77 "Operation not supported on %1") 75 78 .arg(uri.toString()); 76 79 error(QNetworkReply::ContentOperationNotPermittedError, msg); … … 79 82 } 80 83 81 if (uri.host().isEmpty()) { 82 setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("text/plain;charset=US-ASCII")); 84 QPair<QString, QByteArray> decoded = qDecodeDataUrl(uri); 83 85 84 // the following would have been the correct thing, but 85 // reality often differs from the specification. People have 86 // data: URIs with ? and # 87 //QByteArray data = QByteArray::fromPercentEncoding(uri.encodedPath()); 88 QByteArray data = QByteArray::fromPercentEncoding(uri.toEncoded()); 86 if (! decoded.first.isNull()) { 87 setHeader(QNetworkRequest::ContentTypeHeader, decoded.first); 88 setHeader(QNetworkRequest::ContentLengthHeader, decoded.second.size()); 89 emit metaDataChanged(); 89 90 90 // remove the data: scheme 91 data.remove(0, 5); 91 QByteDataBuffer list; 92 list.append(decoded.second); 93 decoded.second.clear(); // important because of implicit sharing! 94 writeDownstreamData(list); 92 95 93 // parse it: 94 int pos = data.indexOf(','); 95 if (pos != -1) { 96 QByteArray payload = data.mid(pos + 1); 97 data.truncate(pos); 98 data = data.trimmed(); 99 100 // find out if the payload is encoded in Base64 101 if (data.endsWith(";base64")) { 102 payload = QByteArray::fromBase64(payload); 103 data.chop(7); 104 } 105 106 if (data.toLower().startsWith("charset")) { 107 int i = 7; // strlen("charset") 108 while (data.at(i) == ' ') 109 ++i; 110 if (data.at(i) == '=') 111 data.prepend("text/plain;"); 112 } 113 114 if (!data.isEmpty()) 115 setHeader(QNetworkRequest::ContentTypeHeader, data.trimmed()); 116 117 setHeader(QNetworkRequest::ContentLengthHeader, payload.size()); 118 emit metaDataChanged(); 119 120 QByteDataBuffer list; 121 list.append(payload); 122 payload.clear(); // important because of implicit sharing! 123 writeDownstreamData(list); 124 125 finished(); 126 return; 127 } 96 finished(); 97 return; 128 98 } 129 99 130 100 // something wrong with this URI 131 QString msg = QObject::tr("Invalid URI: %1").arg(uri.toString()); 101 const QString msg = QCoreApplication::translate("QNetworkAccessDataBackend", 102 "Invalid URI: %1").arg(uri.toString()); 132 103 error(QNetworkReply::ProtocolFailure, msg); 133 104 finished(); … … 152 123 } 153 124 125 bool QNetworkAccessDataBackend::processRequestSynchronously() 126 { 127 #ifndef QT_NO_BEARERMANAGEMENT 128 start(); 129 #else 130 open(); 131 #endif 132 return true; 133 } 134 154 135 QT_END_NAMESPACE -
trunk/src/network/access/qnetworkaccessdatabackend_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 69 69 virtual bool waitForDownstreamReadyRead(int msecs); 70 70 virtual bool waitForUpstreamBytesWritten(int msecs); 71 72 virtual bool processRequestSynchronously(); 71 73 }; 72 74 -
trunk/src/network/access/qnetworkaccessdebugpipebackend.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 253 253 } 254 254 255 error(code, Q Object::tr("Socket error on %1: %2")255 error(code, QNetworkAccessDebugPipeBackend::tr("Socket error on %1: %2") 256 256 .arg(url().toString(), socket.errorString())); 257 257 finished(); … … 268 268 } else { 269 269 // abnormal close 270 QString msg = Q Object::tr("Remote host closed the connection prematurely on %1")270 QString msg = QNetworkAccessDebugPipeBackend::tr("Remote host closed the connection prematurely on %1") 271 271 .arg(url().toString()); 272 272 error(QNetworkReply::RemoteHostClosedError, msg); … … 279 279 } 280 280 281 bool QNetworkAccessDebugPipeBackend::waitForDownstreamReadyRead(int ms)282 {283 Q_UNUSED(ms);284 qCritical("QNetworkAccess: Debug pipe backend does not support waitForReadyRead()");285 return false;286 }287 281 288 282 #endif -
trunk/src/network/access/qnetworkaccessdebugpipebackend_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 72 72 virtual void open(); 73 73 virtual void closeDownstreamChannel(); 74 virtual bool waitForDownstreamReadyRead(int msecs);75 74 76 75 virtual void downstreamReadyWrite(); -
trunk/src/network/access/qnetworkaccessfilebackend.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 204 204 } 205 205 206 bool QNetworkAccessFileBackend::waitForDownstreamReadyRead(int)207 {208 Q_ASSERT(operation() == QNetworkAccessManager::GetOperation);209 return readMoreFromFile();210 }211 212 206 void QNetworkAccessFileBackend::downstreamReadyWrite() 213 207 { -
trunk/src/network/access/qnetworkaccessfilebackend_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 70 70 virtual void open(); 71 71 virtual void closeDownstreamChannel(); 72 virtual bool waitForDownstreamReadyRead(int msecs);73 72 74 73 virtual void downstreamReadyWrite(); -
trunk/src/network/access/qnetworkaccessftpbackend.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 181 181 exit(3); 182 182 #endif 183 }184 185 bool QNetworkAccessFtpBackend::waitForDownstreamReadyRead(int ms)186 {187 if (!ftp)188 return false;189 190 if (ftp->bytesAvailable()) {191 ftpReadyRead();192 return true;193 }194 195 if (ms == 0)196 return false;197 198 qCritical("QNetworkAccess: FTP backend does not support waitForReadyRead()");199 return false;200 183 } 201 184 -
trunk/src/network/access/qnetworkaccessftpbackend_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 88 88 virtual void open(); 89 89 virtual void closeDownstreamChannel(); 90 virtual bool waitForDownstreamReadyRead(int msecs);91 90 92 91 virtual void downstreamReadyWrite(); -
trunk/src/network/access/qnetworkaccesshttpbackend.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 51 51 #include "qnetworkcookie_p.h" 52 52 #include "QtCore/qdatetime.h" 53 #include "QtCore/qelapsedtimer.h" 53 54 #include "QtNetwork/qsslconfiguration.h" 54 55 … … 214 215 case QNetworkAccessManager::PutOperation: 215 216 case QNetworkAccessManager::DeleteOperation: 217 case QNetworkAccessManager::CustomOperation: 216 218 break; 217 219 … … 297 299 , pendingSslConfiguration(0), pendingIgnoreAllSslErrors(false) 298 300 #endif 301 , resumeOffset(0) 299 302 { 300 303 } … … 317 320 // Get the object cache that stores our QHttpNetworkConnection objects 318 321 QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); 319 cache->releaseEntry(cacheKey); 322 323 // synchronous calls are not put into the cache, so for them the key is empty 324 if (!cacheKey.isEmpty()) 325 cache->releaseEntry(cacheKey); 320 326 } 321 327 … … 335 341 // call parent 336 342 QNetworkAccessBackend::finished(); 337 }338 339 void QNetworkAccessHttpBackend::setupConnection()340 {341 #ifndef QT_NO_NETWORKPROXY342 connect(http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),343 SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));344 #endif345 connect(http, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),346 SLOT(httpAuthenticationRequired(QHttpNetworkRequest,QAuthenticator*)));347 connect(http, SIGNAL(error(QNetworkReply::NetworkError,QString)),348 SLOT(httpError(QNetworkReply::NetworkError,QString)));349 #ifndef QT_NO_OPENSSL350 connect(http, SIGNAL(sslErrors(QList<QSslError>)),351 SLOT(sslErrors(QList<QSslError>)));352 #endif353 343 } 354 344 … … 481 471 } 482 472 473 static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio) 474 { 475 switch (prio) { 476 case QNetworkRequest::LowPriority: 477 return QHttpNetworkRequest::LowPriority; 478 case QNetworkRequest::HighPriority: 479 return QHttpNetworkRequest::HighPriority; 480 case QNetworkRequest::NormalPriority: 481 default: 482 return QHttpNetworkRequest::NormalPriority; 483 } 484 } 485 483 486 void QNetworkAccessHttpBackend::postRequest() 484 487 { 485 488 bool loadedFromCache = false; 486 489 QHttpNetworkRequest httpRequest; 490 httpRequest.setPriority(convert(request().priority())); 487 491 switch (operation()) { 488 492 case QNetworkAccessManager::GetOperation: … … 513 517 break; 514 518 519 case QNetworkAccessManager::CustomOperation: 520 invalidateCache(); // for safety reasons, we don't know what the operation does 521 httpRequest.setOperation(QHttpNetworkRequest::Custom); 522 httpRequest.setUploadByteDevice(createUploadByteDevice()); 523 httpRequest.setCustomVerb(request().attribute( 524 QNetworkRequest::CustomVerbAttribute).toByteArray()); 525 break; 526 515 527 default: 516 528 break; // can't happen … … 520 532 521 533 QList<QByteArray> headers = request().rawHeaderList(); 534 if (resumeOffset != 0) { 535 if (headers.contains("Range")) { 536 // Need to adjust resume offset for user specified range 537 538 headers.removeOne("Range"); 539 540 // We've already verified that requestRange starts with "bytes=", see canResume. 541 QByteArray requestRange = request().rawHeader("Range").mid(6); 542 543 int index = requestRange.indexOf('-'); 544 545 quint64 requestStartOffset = requestRange.left(index).toULongLong(); 546 quint64 requestEndOffset = requestRange.mid(index + 1).toULongLong(); 547 548 requestRange = "bytes=" + QByteArray::number(resumeOffset + requestStartOffset) + 549 '-' + QByteArray::number(requestEndOffset); 550 551 httpRequest.setHeaderField("Range", requestRange); 552 } else { 553 httpRequest.setHeaderField("Range", "bytes=" + QByteArray::number(resumeOffset) + '-'); 554 } 555 } 522 556 foreach (const QByteArray &header, headers) 523 557 httpRequest.setHeaderField(header, request().rawHeader(header)); … … 532 566 if (request().attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool() == true) 533 567 httpRequest.setPipeliningAllowed(true); 568 569 if (static_cast<QNetworkRequest::LoadControl> 570 (request().attribute(QNetworkRequest::AuthenticationReuseAttribute, 571 QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Manual) 572 httpRequest.setWithCredentials(false); 534 573 535 574 httpReply = http->sendRequest(httpRequest); … … 541 580 httpReply->ignoreSslErrors(); 542 581 httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList); 582 connect(httpReply, SIGNAL(sslErrors(QList<QSslError>)), 583 SLOT(sslErrors(QList<QSslError>))); 543 584 #endif 544 585 … … 548 589 SLOT(httpError(QNetworkReply::NetworkError,QString))); 549 590 connect(httpReply, SIGNAL(headerChanged()), SLOT(replyHeaderChanged())); 591 connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)), 592 SLOT(httpCacheCredentials(QHttpNetworkRequest,QAuthenticator*))); 593 #ifndef QT_NO_NETWORKPROXY 594 connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), 595 SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); 596 #endif 597 connect(httpReply, SIGNAL(authenticationRequired(const QHttpNetworkRequest,QAuthenticator*)), 598 SLOT(httpAuthenticationRequired(const QHttpNetworkRequest,QAuthenticator*))); 550 599 } 551 600 … … 595 644 cacheProxy.type() == QNetworkProxy::DefaultProxy) { 596 645 // unsuitable proxies 597 QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, 598 Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), 599 Q_ARG(QString, tr("No suitable proxy found"))); 600 QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); 601 return; 602 } 603 #endif 604 605 // check if we have an open connection to this host 606 cacheKey = makeCacheKey(this, theProxy); 607 QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); 608 // the http object is actually a QHttpNetworkConnection 609 http = static_cast<QNetworkAccessCachedHttpConnection *>(cache->requestEntryNow(cacheKey)); 610 if (http == 0) { 611 // no entry in cache; create an object 612 // the http object is actually a QHttpNetworkConnection 613 http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt); 614 646 if (isSynchronous()) { 647 error(QNetworkReply::ProxyNotFoundError, tr("No suitable proxy found")); 648 finished(); 649 } else { 650 QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, 651 Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), 652 Q_ARG(QString, tr("No suitable proxy found"))); 653 QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); 654 } 655 return; 656 } 657 #endif 658 659 if (isSynchronous()) { 660 // for synchronous requests, we just create a new connection 661 http = new QHttpNetworkConnection(1, url.host(), url.port(), encrypt, this); 615 662 #ifndef QT_NO_NETWORKPROXY 616 663 http->setTransparentProxy(transparentProxy); 617 664 http->setCacheProxy(cacheProxy); 618 665 #endif 619 620 // cache the QHttpNetworkConnection corresponding to this cache key 621 cache->addEntry(cacheKey, http); 622 } 623 624 setupConnection(); 625 postRequest(); 666 postRequest(); 667 processRequestSynchronously(); 668 } else { 669 // check if we have an open connection to this host 670 cacheKey = makeCacheKey(this, theProxy); 671 QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); 672 // the http object is actually a QHttpNetworkConnection 673 http = static_cast<QNetworkAccessCachedHttpConnection *>(cache->requestEntryNow(cacheKey)); 674 if (http == 0) { 675 // no entry in cache; create an object 676 // the http object is actually a QHttpNetworkConnection 677 http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt); 678 679 #ifndef QT_NO_NETWORKPROXY 680 http->setTransparentProxy(transparentProxy); 681 http->setCacheProxy(cacheProxy); 682 #endif 683 684 // cache the QHttpNetworkConnection corresponding to this cache key 685 cache->addEntry(cacheKey, static_cast<QNetworkAccessCachedHttpConnection *>(http.data())); 686 } 687 postRequest(); 688 } 626 689 } 627 690 … … 630 693 // this indicates that the user closed the stream while the reply isn't finished yet 631 694 } 632 633 bool QNetworkAccessHttpBackend::waitForDownstreamReadyRead(int msecs)634 {635 Q_ASSERT(http);636 637 if (httpReply->bytesAvailable()) {638 readFromHttp();639 return true;640 }641 642 if (msecs == 0) {643 // no bytes available in the socket and no waiting644 return false;645 }646 647 // ### FIXME648 qCritical("QNetworkAccess: HTTP backend does not support waitForReadyRead()");649 return false;650 }651 652 695 653 696 void QNetworkAccessHttpBackend::downstreamReadyWrite() … … 816 859 } 817 860 861 void QNetworkAccessHttpBackend::httpCacheCredentials(const QHttpNetworkRequest &, 862 QAuthenticator *auth) 863 { 864 cacheCredentials(auth); 865 } 866 818 867 void QNetworkAccessHttpBackend::httpError(QNetworkReply::NetworkError errorCode, 819 868 const QString &errorString) … … 821 870 #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) 822 871 qDebug() << "http error!" << errorCode << errorString; 823 #endif824 #if 0825 static const QNetworkReply::NetworkError conversionTable[] = {826 QNetworkReply::ConnectionRefusedError,827 QNetworkReply::RemoteHostClosedError,828 QNetworkReply::HostNotFoundError,829 QNetworkReply::UnknownNetworkError, // SocketAccessError830 QNetworkReply::UnknownNetworkError, // SocketResourceError831 QNetworkReply::TimeoutError, // SocketTimeoutError832 QNetworkReply::UnknownNetworkError, // DatagramTooLargeError833 QNetworkReply::UnknownNetworkError, // NetworkError834 QNetworkReply::UnknownNetworkError, // AddressInUseError835 QNetworkReply::UnknownNetworkError, // SocketAddressNotAvailableError836 QNetworkReply::UnknownNetworkError, // UnsupportedSocketOperationError837 QNetworkReply::UnknownNetworkError, // UnfinishedSocketOperationError838 QNetworkReply::ProxyAuthenticationRequiredError839 };840 QNetworkReply::NetworkError code;841 if (int(errorCode) >= 0 &&842 uint(errorCode) < (sizeof conversionTable / sizeof conversionTable[0]))843 code = conversionTable[errorCode];844 else845 code = QNetworkReply::UnknownNetworkError;846 872 #endif 847 873 error(errorCode, errorString); … … 886 912 checkForRedirect(status); 887 913 888 emit metaDataChanged();889 890 // invoke this asynchronously, else Arora/QtDemoBrowser don't like cached downloads891 // see task 250221 / 251801914 // This needs to be emitted in the event loop because it can be reached at 915 // the direct code path of qnam.get(...) before the user has a chance 916 // to connect any signals. 917 QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection); 892 918 qRegisterMetaType<QIODevice*>("QIODevice*"); 893 919 QMetaObject::invokeMethod(this, "writeDownstreamData", Qt::QueuedConnection, Q_ARG(QIODevice*, contents)); … … 1094 1120 } 1095 1121 1122 bool QNetworkAccessHttpBackend::canResume() const 1123 { 1124 // Only GET operation supports resuming. 1125 if (operation() != QNetworkAccessManager::GetOperation) 1126 return false; 1127 1128 // Can only resume if server/resource supports Range header. 1129 if (httpReply->headerField("Accept-Ranges", "none") == "none") 1130 return false; 1131 1132 // We only support resuming for byte ranges. 1133 if (request().hasRawHeader("Range")) { 1134 QByteArray range = request().rawHeader("Range"); 1135 if (!range.startsWith("bytes=")) 1136 return false; 1137 } 1138 1139 return true; 1140 } 1141 1142 void QNetworkAccessHttpBackend::setResumeOffset(quint64 offset) 1143 { 1144 resumeOffset = offset; 1145 } 1146 1147 bool QNetworkAccessHttpBackend::processRequestSynchronously() 1148 { 1149 QHttpNetworkConnectionChannel *channel = &http->channels()[0]; 1150 1151 // Disconnect all socket signals. They will only confuse us when using waitFor* 1152 QObject::disconnect(channel->socket, 0, 0, 0); 1153 1154 qint64 timeout = 20*1000; // 20 sec 1155 QElapsedTimer timeoutTimer; 1156 1157 bool waitResult = channel->socket->waitForConnected(timeout); 1158 timeoutTimer.start(); 1159 1160 if (!waitResult || channel->socket->state() != QAbstractSocket::ConnectedState) { 1161 error(QNetworkReply::UnknownNetworkError, QLatin1String("could not connect")); 1162 return false; 1163 } 1164 channel->_q_connected(); // this will send the request (via sendRequest()) 1165 1166 #ifndef QT_NO_OPENSSL 1167 if (http->isSsl()) { 1168 qint64 remainingTimeEncrypted = timeout - timeoutTimer.elapsed(); 1169 if (!static_cast<QSslSocket *>(channel->socket)->waitForEncrypted(remainingTimeEncrypted)) { 1170 error(QNetworkReply::SslHandshakeFailedError, 1171 QLatin1String("could not encrypt or timeout while encrypting")); 1172 return false; 1173 } 1174 channel->_q_encrypted(); 1175 } 1176 #endif 1177 1178 // if we get a 401 or 407, we might need to send the request twice, see below 1179 bool authenticating = false; 1180 1181 do { 1182 channel->sendRequest(); 1183 1184 qint64 remainingTimeBytesWritten; 1185 while(channel->socket->bytesToWrite() > 0 || 1186 channel->state == QHttpNetworkConnectionChannel::WritingState) { 1187 remainingTimeBytesWritten = timeout - timeoutTimer.elapsed(); 1188 channel->sendRequest(); // triggers channel->socket->write() 1189 if (!channel->socket->waitForBytesWritten(remainingTimeBytesWritten)) { 1190 error(QNetworkReply::TimeoutError, 1191 QLatin1String("could not write bytes to socket or timeout while writing")); 1192 return false; 1193 } 1194 } 1195 1196 qint64 remainingTimeBytesRead = timeout - timeoutTimer.elapsed(); 1197 // Loop for at most remainingTime until either the socket disconnects 1198 // or the reply is finished 1199 do { 1200 waitResult = channel->socket->waitForReadyRead(remainingTimeBytesRead); 1201 remainingTimeBytesRead = timeout - timeoutTimer.elapsed(); 1202 if (!waitResult || remainingTimeBytesRead <= 0 1203 || channel->socket->state() != QAbstractSocket::ConnectedState) { 1204 error(QNetworkReply::TimeoutError, 1205 QLatin1String("could not read from socket or timeout while reading")); 1206 return false; 1207 } 1208 1209 if (channel->socket->bytesAvailable()) 1210 channel->_q_readyRead(); 1211 1212 if (!httpReply) 1213 return false; // we got a 401 or 407 and cannot handle it (it might happen that 1214 // disconnectFromHttp() was called, in that case the reply is zero) 1215 // ### I am quite sure this does not work for NTLM 1216 // ### how about uploading to an auth / proxyAuth site? 1217 1218 authenticating = (httpReply->statusCode() == 401 || httpReply->statusCode() == 407); 1219 1220 if (httpReply->isFinished()) 1221 break; 1222 } while (remainingTimeBytesRead > 0); 1223 } while (authenticating); 1224 1225 return true; 1226 } 1227 1096 1228 QT_END_NAMESPACE 1097 1229 -
trunk/src/network/access/qnetworkaccesshttpbackend_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 80 80 virtual void open(); 81 81 virtual void closeDownstreamChannel(); 82 virtual bool waitForDownstreamReadyRead(int msecs);83 82 84 83 virtual void downstreamReadyWrite(); … … 98 97 bool needsResetableUploadData() { return true; } 99 98 99 bool canResume() const; 100 void setResumeOffset(quint64 offset); 101 102 virtual bool processRequestSynchronously(); 103 100 104 private slots: 101 105 void replyReadyRead(); … … 103 107 void replyHeaderChanged(); 104 108 void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth); 109 void httpCacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *auth); 105 110 void httpError(QNetworkReply::NetworkError error, const QString &errorString); 106 111 bool sendCacheContents(const QNetworkCacheMetaData &metaData); … … 109 114 private: 110 115 QHttpNetworkReply *httpReply; 111 QPointer<Q NetworkAccessCachedHttpConnection> http;116 QPointer<QHttpNetworkConnection> http; 112 117 QByteArray cacheKey; 113 118 QNetworkAccessBackendUploadIODevice *uploadDevice; … … 119 124 #endif 120 125 126 quint64 resumeOffset; 127 121 128 void disconnectFromHttp(); 122 void setupConnection();123 129 void validateCache(QHttpNetworkRequest &httpRequest, bool &loadedFromCache); 124 130 void invalidateCache(); -
trunk/src/network/access/qnetworkaccessmanager.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 48 48 #include "qabstractnetworkcache.h" 49 49 50 #include "QtNetwork/qnetworksession.h" 51 #include "QtNetwork/private/qsharednetworksession_p.h" 52 50 53 #include "qnetworkaccesshttpbackend_p.h" 51 54 #include "qnetworkaccessftpbackend_p.h" … … 53 56 #include "qnetworkaccessdatabackend_p.h" 54 57 #include "qnetworkaccessdebugpipebackend_p.h" 58 #include "qnetworkaccesscachebackend_p.h" 55 59 #include "qfilenetworkreply_p.h" 56 60 … … 60 64 #include "QtNetwork/qauthenticator.h" 61 65 #include "QtNetwork/qsslconfiguration.h" 66 #include "QtNetwork/qnetworkconfigmanager.h" 62 67 63 68 QT_BEGIN_NAMESPACE … … 139 144 \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 1 140 145 146 \section1 Network and Roaming support 147 148 With the addition of the \l {Bearer Management} API to Qt 4.7 149 QNetworkAccessManager gained the ability to manage network connections. 150 QNetworkAccessManager can start the network interface if the device is 151 offline and terminates the interface if the current process is the last 152 one to use the uplink. Note that some platform utilize grace periods from 153 when the last application stops using a uplink until the system actually 154 terminates the connectivity link. Roaming is equally transparent. Any 155 queued/pending network requests are automatically transferred to new 156 access point. 157 158 Clients wanting to utilize this feature should not require any changes. In fact 159 it is likely that existing platform specific connection code can simply be 160 removed from the application. 161 162 \note The network and roaming support in QNetworkAccessManager is conditional 163 upon the platform supporting connection management. The 164 \l QNetworkConfigurationManager::NetworkSessionRequired can be used to 165 detect whether QNetworkAccessManager utilizes this feature. Currently only 166 Meego/Harmattan and Symbian platforms provide connection management support. 167 168 \note This feature cannot be used in combination with the Bearer Management 169 API as provided by QtMobility. Applications have to migrate to the Qt version 170 of Bearer Management. 171 141 172 \section1 Symbian Platform Security Requirements 142 173 … … 172 203 deleteResource()) 173 204 205 \value CustomOperation custom operation (created with 206 sendCustomRequest()) \since 4.7 207 174 208 \omitvalue UnknownOperation 175 209 176 210 \sa QNetworkReply::operation() 211 */ 212 213 /*! 214 \enum QNetworkAccessManager::NetworkAccessibility 215 216 Indicates whether the network is accessible via this network access manager. 217 218 \value UnknownAccessibility The network accessibility cannot be determined. 219 \value NotAccessible The network is not currently accessible, either because there 220 is currently no network coverage or network access has been 221 explicitly disabled by a call to setNetworkAccessible(). 222 \value Accessible The network is accessible. 223 224 \sa networkAccessible 225 */ 226 227 /*! 228 \property QNetworkAccessManager::networkAccessible 229 \brief whether the network is currently accessible via this network access manager. 230 231 \since 4.7 232 233 If the network is \l {NotAccessible}{not accessible} the network access manager will not 234 process any new network requests, all such requests will fail with an error. Requests with 235 URLs with the file:// scheme will still be processed. 236 237 By default the value of this property reflects the physical state of the device. Applications 238 may override it to disable all network requests via this network access manager by calling 239 240 \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 4 241 242 Network requests can be reenabled again by calling 243 244 \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 5 245 246 \note Calling setNetworkAccessible() does not change the network state. 247 */ 248 249 /*! 250 \fn void QNetworkAccessManager::networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible) 251 252 This signal is emitted when the value of the \l networkAccessible property changes. 253 \a accessible is the new network accessibility. 254 */ 255 256 /*! 257 \fn void QNetworkAccessManager::networkSessionConnected() 258 259 \since 4.7 260 261 \internal 262 263 This signal is emitted when the status of the network session changes into a usable (Connected) 264 state. It is used to signal to QNetworkReplys to start or migrate their network operation once 265 the network session has been opened or finished roaming. 177 266 */ 178 267 … … 378 467 delete d_func()->proxyFactory; 379 468 #endif 469 470 // Delete the QNetworkReply children first. 471 // Else a QAbstractNetworkCache might get deleted in ~QObject 472 // before a QNetworkReply that accesses the QAbstractNetworkCache 473 // object in its destructor. 474 qDeleteAll(findChildren<QNetworkReply *>()); 475 // The other children will be deleted in this ~QObject 476 // FIXME instead of this "hack" make the QNetworkReplyImpl 477 // properly watch the cache deletion, e.g. via a QWeakPointer. 380 478 } 381 479 … … 535 633 \note QNetworkAccessManager takes ownership of the \a cookieJar object. 536 634 537 QNetworkAccessManager will set the parent of the \a cookieJar 538 passed to itself, so that the cookie jar is deleted when this 635 If \a cookieJar is in the same thread as this QNetworkAccessManager, 636 it will set the parent of the \a cookieJar 637 so that the cookie jar is deleted when this 539 638 object is deleted as well. If you want to share cookie jars 540 639 between different QNetworkAccessManager objects, you may want to … … 561 660 delete d->cookieJar; 562 661 d->cookieJar = cookieJar; 563 d->cookieJar->setParent(this); 662 if (thread() == cookieJar->thread()) 663 d->cookieJar->setParent(this); 564 664 } 565 665 } … … 584 684 The contents as well as associated headers will be downloaded. 585 685 586 \sa post(), put(), deleteResource() 686 \sa post(), put(), deleteResource(), sendCustomRequest() 587 687 */ 588 688 QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request) … … 603 703 HTTPS is undefined and will probably fail. 604 704 605 \sa get(), put(), deleteResource() 705 \sa get(), put(), deleteResource(), sendCustomRequest() 606 706 */ 607 707 QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, QIODevice *data) … … 644 744 files through HTML forms, use the POST mechanism. 645 745 646 \sa get(), post() 746 \sa get(), post(), deleteResource(), sendCustomRequest() 647 747 */ 648 748 QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QIODevice *data) … … 675 775 HTTP DELETE request. 676 776 677 \sa get(), post(), put() 777 \sa get(), post(), put(), sendCustomRequest() 678 778 */ 679 779 QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &request) 680 780 { 681 781 return d_func()->postProcess(createRequest(QNetworkAccessManager::DeleteOperation, request)); 782 } 783 784 #ifndef QT_NO_BEARERMANAGEMENT 785 786 /*! 787 \since 4.7 788 789 Sets the network configuration that will be used when creating the 790 \l {QNetworkSession}{network session} to \a config. 791 792 The network configuration is used to create and open a network session before any request that 793 requires network access is process. If no network configuration is explicitly set via this 794 function the network configuration returned by 795 QNetworkConfigurationManager::defaultConfiguration() will be used. 796 797 To restore the default network configuration set the network configuration to the value 798 returned from QNetworkConfigurationManager::defaultConfiguration(). 799 800 \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 2 801 802 If an invalid network configuration is set, a network session will not be created. In this 803 case network requests will be processed regardless, but may fail. For example: 804 805 \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 3 806 807 \sa configuration(), QNetworkSession 808 */ 809 void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config) 810 { 811 d_func()->createSession(config); 812 } 813 814 /*! 815 \since 4.7 816 817 Returns the network configuration that will be used to create the 818 \l {QNetworkSession}{network session} which will be used when processing network requests. 819 820 \sa setConfiguration(), activeConfiguration() 821 */ 822 QNetworkConfiguration QNetworkAccessManager::configuration() const 823 { 824 Q_D(const QNetworkAccessManager); 825 826 if (d->networkSession) 827 return d->networkSession->configuration(); 828 else 829 return QNetworkConfiguration(); 830 } 831 832 /*! 833 \since 4.7 834 835 Returns the current active network configuration. 836 837 If the network configuration returned by configuration() is of type 838 QNetworkConfiguration::ServiceNetwork this function will return the current active child 839 network configuration of that configuration. Otherwise returns the same network configuration 840 as configuration(). 841 842 Use this function to return the actual network configuration currently in use by the network 843 session. 844 845 \sa configuration() 846 */ 847 QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const 848 { 849 Q_D(const QNetworkAccessManager); 850 851 if (d->networkSession) { 852 QNetworkConfigurationManager manager; 853 854 return manager.configurationFromIdentifier( 855 d->networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString()); 856 } else { 857 return QNetworkConfiguration(); 858 } 859 } 860 861 /*! 862 \since 4.7 863 864 Overrides the reported network accessibility. If \a accessible is NotAccessible the reported 865 network accessiblity will always be NotAccessible. Otherwise the reported network 866 accessibility will reflect the actual device state. 867 */ 868 void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkAccessibility accessible) 869 { 870 Q_D(QNetworkAccessManager); 871 872 if (d->networkAccessible != accessible) { 873 NetworkAccessibility previous = networkAccessible(); 874 d->networkAccessible = accessible; 875 NetworkAccessibility current = networkAccessible(); 876 if (previous != current) 877 emit networkAccessibleChanged(current); 878 } 879 } 880 881 /*! 882 \since 4.7 883 884 Returns the current network accessibility. 885 */ 886 QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccessible() const 887 { 888 Q_D(const QNetworkAccessManager); 889 890 if (d->networkSession) { 891 // d->online holds online/offline state of this network session. 892 if (d->online) 893 return d->networkAccessible; 894 else 895 return NotAccessible; 896 } else { 897 // Network accessibility is either disabled or unknown. 898 return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility; 899 } 900 } 901 902 #endif // QT_NO_BEARERMANAGEMENT 903 904 /*! 905 \since 4.7 906 907 Sends a custom request to the server identified by the URL of \a request. 908 909 It is the user's responsibility to send a \a verb to the server that is valid 910 according to the HTTP specification. 911 912 This method provides means to send verbs other than the common ones provided 913 via get() or post() etc., for instance sending an HTTP OPTIONS command. 914 915 If \a data is not empty, the contents of the \a data 916 device will be uploaded to the server; in that case, data must be open for 917 reading and must remain valid until the finished() signal is emitted for this reply. 918 919 \note This feature is currently available for HTTP only. 920 921 \sa get(), post(), put(), deleteResource() 922 */ 923 QNetworkReply *QNetworkAccessManager::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data) 924 { 925 QNetworkRequest newRequest(request); 926 newRequest.setAttribute(QNetworkRequest::CustomVerbAttribute, verb); 927 return d_func()->postProcess(createRequest(QNetworkAccessManager::CustomOperation, newRequest, data)); 682 928 } 683 929 … … 701 947 Q_D(QNetworkAccessManager); 702 948 949 // 4.7 only hotfix fast path for data:// URLs 950 // In 4.8 this is solved with QNetworkReplyDataImpl and will work there 951 // This hotfix is done for not needing a QNetworkSession for data:// 952 if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) 953 && (req.url().scheme() == QLatin1String("data"))) { 954 QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); 955 QNetworkReplyImplPrivate *priv = reply->d_func(); 956 priv->manager = this; 957 priv->backend = new QNetworkAccessDataBackend(); 958 priv->backend->manager = this->d_func(); 959 priv->backend->setParent(reply); 960 priv->backend->reply = priv; 961 priv->setup(op, req, outgoingData); 962 return reply; 963 } 964 703 965 // fast path for GET on file:// URLs 704 966 // Also if the scheme is empty we consider it a file. 705 // The QNetworkAccessFileBackend will right now only be used 706 // for PUT or qrc:// 967 // The QNetworkAccessFileBackend will right now only be used for PUT 707 968 if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) 708 969 && (req.url().scheme() == QLatin1String("file") 970 || req.url().scheme() == QLatin1String("qrc") 709 971 || req.url().scheme().isEmpty())) { 710 972 return new QFileNetworkReply(this, req, op); 711 973 } 974 975 // A request with QNetworkRequest::AlwaysCache does not need any bearer management 976 QNetworkRequest::CacheLoadControl mode = 977 static_cast<QNetworkRequest::CacheLoadControl>( 978 req.attribute(QNetworkRequest::CacheLoadControlAttribute, 979 QNetworkRequest::PreferNetwork).toInt()); 980 if (mode == QNetworkRequest::AlwaysCache 981 && (op == QNetworkAccessManager::GetOperation 982 || op == QNetworkAccessManager::HeadOperation)) { 983 // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106 984 QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); 985 QNetworkReplyImplPrivate *priv = reply->d_func(); 986 priv->manager = this; 987 priv->backend = new QNetworkAccessCacheBackend(); 988 priv->backend->manager = this->d_func(); 989 priv->backend->setParent(reply); 990 priv->backend->reply = priv; 991 priv->setup(op, req, outgoingData); 992 return reply; 993 } 994 995 #ifndef QT_NO_BEARERMANAGEMENT 996 // Return a disabled network reply if network access is disabled. 997 // Except if the scheme is empty or file://. 998 if (!d->networkAccessible && !(req.url().scheme() == QLatin1String("file") || 999 req.url().scheme().isEmpty())) { 1000 return new QDisabledNetworkReply(this, req, op); 1001 } 1002 1003 if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) { 1004 QNetworkConfigurationManager manager; 1005 if (!d->networkConfiguration.isEmpty()) { 1006 d->createSession(manager.configurationFromIdentifier(d->networkConfiguration)); 1007 } else { 1008 if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) 1009 d->createSession(manager.defaultConfiguration()); 1010 else 1011 d->initializeSession = false; 1012 } 1013 } 1014 1015 if (d->networkSession) 1016 d->networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), -1); 1017 #endif 712 1018 713 1019 QNetworkRequest request = req; … … 718 1024 request.setHeader(QNetworkRequest::ContentLengthHeader, outgoingData->size()); 719 1025 } 720 if (d->cookieJar) { 721 QList<QNetworkCookie> cookies = d->cookieJar->cookiesForUrl(request.url()); 722 if (!cookies.isEmpty()) 723 request.setHeader(QNetworkRequest::CookieHeader, qVariantFromValue(cookies)); 1026 1027 if (static_cast<QNetworkRequest::LoadControl> 1028 (request.attribute(QNetworkRequest::CookieLoadControlAttribute, 1029 QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic) { 1030 if (d->cookieJar) { 1031 QList<QNetworkCookie> cookies = d->cookieJar->cookiesForUrl(request.url()); 1032 if (!cookies.isEmpty()) 1033 request.setHeader(QNetworkRequest::CookieHeader, qVariantFromValue(cookies)); 1034 } 724 1035 } 725 1036 … … 727 1038 QUrl url = request.url(); 728 1039 QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); 1040 #ifndef QT_NO_BEARERMANAGEMENT 1041 if (req.url().scheme() != QLatin1String("file") && !req.url().scheme().isEmpty()) { 1042 connect(this, SIGNAL(networkSessionConnected()), 1043 reply, SLOT(_q_networkSessionConnected())); 1044 } 1045 #endif 729 1046 QNetworkReplyImplPrivate *priv = reply->d_func(); 730 1047 priv->manager = this; 731 1048 732 1049 // second step: fetch cached credentials 733 QNetworkAuthenticationCredential *cred = d->fetchCachedCredentials(url); 734 if (cred) { 735 url.setUserName(cred->user); 736 url.setPassword(cred->password); 737 priv->urlForLastAuthentication = url; 738 } 1050 // This is not done for the time being, we should use signal emissions to request 1051 // the credentials from cache. 739 1052 740 1053 // third step: find a backend … … 749 1062 priv->backend->reply = priv; 750 1063 } 751 // fourth step: setup the reply752 priv->setup(op, request, outgoingData);753 1064 754 1065 #ifndef QT_NO_OPENSSL 755 1066 reply->setSslConfiguration(request.sslConfiguration()); 756 1067 #endif 1068 1069 // fourth step: setup the reply 1070 priv->setup(op, request, outgoingData); 1071 757 1072 return reply; 758 1073 } … … 761 1076 { 762 1077 Q_Q(QNetworkAccessManager); 1078 763 1079 QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender()); 764 1080 if (reply) 765 1081 emit q->finished(reply); 1082 1083 #ifndef QT_NO_BEARERMANAGEMENT 1084 if (networkSession && q->findChildren<QNetworkReply *>().count() == 1) 1085 networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), 120000); 1086 #endif 766 1087 } 767 1088 … … 812 1133 // don't try the cache for the same URL twice in a row 813 1134 // being called twice for the same URL means the authentication failed 814 if (url != backend->reply->urlForLastAuthentication) { 1135 // also called when last URL is empty, e.g. on first call 1136 if (backend->reply->urlForLastAuthentication.isEmpty() 1137 || url != backend->reply->urlForLastAuthentication) { 815 1138 QNetworkAuthenticationCredential *cred = fetchCachedCredentials(url, authenticator); 816 1139 if (cred) { … … 822 1145 } 823 1146 1147 // if we emit a signal here in synchronous mode, the user might spin 1148 // an event loop, which might recurse and lead to problems 1149 if (backend->isSynchronous()) 1150 return; 1151 824 1152 backend->reply->urlForLastAuthentication = url; 825 1153 emit q->authenticationRequired(backend->reply->q_func(), authenticator); 826 addCredentials(url, authenticator);1154 cacheCredentials(url, authenticator); 827 1155 } 828 1156 … … 841 1169 // or a new function proxyAuthenticationSucceeded(true|false) 842 1170 if (proxy != backend->reply->lastProxyAuthentication) { 843 QNetworkAuthenticationCredential *cred = fetchCached Credentials(proxy);1171 QNetworkAuthenticationCredential *cred = fetchCachedProxyCredentials(proxy); 844 1172 if (cred) { 845 1173 authenticator->setUser(cred->user); … … 849 1177 } 850 1178 1179 // if we emit a signal here in synchronous mode, the user might spin 1180 // an event loop, which might recurse and lead to problems 1181 if (backend->isSynchronous()) 1182 return; 1183 851 1184 backend->reply->lastProxyAuthentication = proxy; 852 1185 emit q->proxyAuthenticationRequired(proxy, authenticator); 853 addCredentials(proxy, authenticator);854 } 855 856 void QNetworkAccessManagerPrivate:: addCredentials(const QNetworkProxy &p,1186 cacheProxyCredentials(proxy, authenticator); 1187 } 1188 1189 void QNetworkAccessManagerPrivate::cacheProxyCredentials(const QNetworkProxy &p, 857 1190 const QAuthenticator *authenticator) 858 1191 { … … 891 1224 892 1225 QNetworkAuthenticationCredential * 893 QNetworkAccessManagerPrivate::fetchCached Credentials(const QNetworkProxy &p,1226 QNetworkAccessManagerPrivate::fetchCachedProxyCredentials(const QNetworkProxy &p, 894 1227 const QAuthenticator *authenticator) 895 1228 { … … 943 1276 #endif 944 1277 945 void QNetworkAccessManagerPrivate:: addCredentials(const QUrl &url,1278 void QNetworkAccessManagerPrivate::cacheCredentials(const QUrl &url, 946 1279 const QAuthenticator *authenticator) 947 1280 { … … 1016 1349 } 1017 1350 1351 #ifndef QT_NO_BEARERMANAGEMENT 1352 void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &config) 1353 { 1354 Q_Q(QNetworkAccessManager); 1355 1356 initializeSession = false; 1357 1358 if (!config.isValid()) { 1359 networkSession.clear(); 1360 online = false; 1361 1362 if (networkAccessible == QNetworkAccessManager::NotAccessible) 1363 emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); 1364 else 1365 emit q->networkAccessibleChanged(QNetworkAccessManager::UnknownAccessibility); 1366 1367 return; 1368 } 1369 1370 networkSession = QSharedNetworkSessionManager::getSession(config); 1371 1372 QObject::connect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection); 1373 //QueuedConnection is used to avoid deleting the networkSession inside its closed signal 1374 QObject::connect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection); 1375 QObject::connect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), 1376 q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); 1377 1378 _q_networkSessionStateChanged(networkSession->state()); 1379 } 1380 1381 void QNetworkAccessManagerPrivate::_q_networkSessionClosed() 1382 { 1383 if (networkSession) { 1384 networkConfiguration = networkSession->configuration().identifier(); 1385 1386 networkSession.clear(); 1387 } 1388 } 1389 1390 void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state) 1391 { 1392 Q_Q(QNetworkAccessManager); 1393 1394 if (state == QNetworkSession::Connected) 1395 emit q->networkSessionConnected(); 1396 if (online) { 1397 if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { 1398 online = false; 1399 emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); 1400 } 1401 } else { 1402 if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { 1403 online = true; 1404 emit q->networkAccessibleChanged(networkAccessible); 1405 } 1406 } 1407 } 1408 #endif // QT_NO_BEARERMANAGEMENT 1409 1018 1410 QT_END_NAMESPACE 1019 1411 -
trunk/src/network/access/qnetworkaccessmanager.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 63 63 class QNetworkProxyFactory; 64 64 class QSslError; 65 #if !defined(QT_NO_BEARERMANAGEMENT) && !defined(QT_MOBILITY_BEARER) 66 class QNetworkConfiguration; 67 #endif 65 68 66 69 class QNetworkReplyImplPrivate; … … 69 72 { 70 73 Q_OBJECT 74 75 #ifndef QT_NO_BEARERMANAGEMENT 76 Q_PROPERTY(NetworkAccessibility networkAccessible READ networkAccessible WRITE setNetworkAccessible NOTIFY networkAccessibleChanged) 77 #endif 78 71 79 public: 72 80 enum Operation { … … 76 84 PostOperation, 77 85 DeleteOperation, 86 CustomOperation, 78 87 79 88 UnknownOperation = 0 80 89 }; 90 91 #ifndef QT_NO_BEARERMANAGEMENT 92 enum NetworkAccessibility { 93 UnknownAccessibility = -1, 94 NotAccessible = 0, 95 Accessible = 1 96 }; 97 #endif 81 98 82 99 explicit QNetworkAccessManager(QObject *parent = 0); … … 103 120 QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data); 104 121 QNetworkReply *deleteResource(const QNetworkRequest &request); 122 QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = 0); 123 124 #if !defined(QT_NO_BEARERMANAGEMENT) && !defined(QT_MOBILITY_BEARER) 125 void setConfiguration(const QNetworkConfiguration &config); 126 QNetworkConfiguration configuration() const; 127 QNetworkConfiguration activeConfiguration() const; 128 #endif 129 130 #ifndef QT_NO_BEARERMANAGEMENT 131 void setNetworkAccessible(NetworkAccessibility accessible); 132 NetworkAccessibility networkAccessible() const; 133 #endif 105 134 106 135 Q_SIGNALS: … … 114 143 #endif 115 144 145 #if !defined(QT_NO_BEARERMANAGEMENT) && !defined(QT_MOBILITY_BEARER) 146 void networkSessionConnected(); 147 #endif 148 149 #ifndef QT_NO_BEARERMANAGEMENT 150 void networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible); 151 #endif 152 116 153 protected: 117 154 virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, … … 123 160 Q_PRIVATE_SLOT(d_func(), void _q_replyFinished()) 124 161 Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>)) 162 #if !defined(QT_NO_BEARERMANAGEMENT) && !defined(QT_MOBILITY_BEARER) 163 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed()) 164 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) 165 #endif 125 166 }; 126 167 -
trunk/src/network/access/qnetworkaccessmanager_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 59 59 #include "private/qobject_p.h" 60 60 #include "QtNetwork/qnetworkproxy.h" 61 #include "QtNetwork/qnetworksession.h" 61 62 62 63 QT_BEGIN_NAMESPACE … … 75 76 proxyFactory(0), 76 77 #endif 78 #ifndef QT_NO_BEARERMANAGEMENT 79 networkSession(0), 80 networkAccessible(QNetworkAccessManager::Accessible), 81 online(false), 82 initializeSession(true), 83 #endif 77 84 cookieJarCreated(false) 78 85 { } … … 85 92 86 93 void authenticationRequired(QNetworkAccessBackend *backend, QAuthenticator *authenticator); 87 void addCredentials(const QUrl &url, const QAuthenticator *auth);94 void cacheCredentials(const QUrl &url, const QAuthenticator *auth); 88 95 QNetworkAuthenticationCredential *fetchCachedCredentials(const QUrl &url, 89 96 const QAuthenticator *auth = 0); … … 92 99 void proxyAuthenticationRequired(QNetworkAccessBackend *backend, const QNetworkProxy &proxy, 93 100 QAuthenticator *authenticator); 94 void addCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth);95 QNetworkAuthenticationCredential *fetchCached Credentials(const QNetworkProxy &proxy,101 void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth); 102 QNetworkAuthenticationCredential *fetchCachedProxyCredentials(const QNetworkProxy &proxy, 96 103 const QAuthenticator *auth = 0); 97 104 QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query); … … 99 106 100 107 QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request); 108 109 #ifndef QT_NO_BEARERMANAGEMENT 110 void createSession(const QNetworkConfiguration &config); 111 112 void _q_networkSessionClosed(); 113 void _q_networkSessionNewConfigurationActivated(); 114 void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config, 115 bool isSeamless); 116 void _q_networkSessionStateChanged(QNetworkSession::State state); 117 #endif 101 118 102 119 // this is the cache for storing downloaded files … … 111 128 #endif 112 129 130 #ifndef QT_NO_BEARERMANAGEMENT 131 QSharedPointer<QNetworkSession> networkSession; 132 QString networkConfiguration; 133 QNetworkAccessManager::NetworkAccessibility networkAccessible; 134 bool online; 135 bool initializeSession; 136 #endif 137 113 138 bool cookieJarCreated; 114 115 139 116 140 // this cache can be used by individual backends to cache e.g. their TCP connections to a server -
trunk/src/network/access/qnetworkcookie.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 992 992 993 993 QString normalizedDomain = QUrl::fromAce(QUrl::toAce(QString::fromUtf8(rawDomain))); 994 if (normalizedDomain.isEmpty() && !rawDomain.isEmpty()) 995 return result; 994 996 cookie.setDomain(maybeLeadingDot + normalizedDomain); 995 997 } else if (field.first == "max-age") { -
trunk/src/network/access/qnetworkcookie.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qnetworkcookie_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qnetworkcookiejar.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 41 41 42 42 #include "qnetworkcookiejar.h" 43 #include "qnetworkcookiejartlds_p.h" 43 44 #include "qnetworkcookiejar_p.h" 44 45 … … 158 159 url object. 159 160 160 Returns true if one or more cookes are set for url otherwise false. 161 Returns true if one or more cookies are set for \a url, 162 otherwise false. 161 163 162 164 If a cookie already exists in the cookie jar, it will be … … 209 211 QString domain = cookie.domain(); 210 212 if (!(isParentDomain(domain, defaultDomain) 211 || isParentDomain(defaultDomain, domain))) { 212 continue; // not accepted 213 } 214 215 // reject if domain is like ".com" 216 // (i.e., reject if domain does not contain embedded dots, see RFC 2109 section 4.3.2) 217 // this is just a rudimentary check and does not cover all cases 218 if (domain.lastIndexOf(QLatin1Char('.')) == 0) 219 continue; // not accepted 220 213 || isParentDomain(defaultDomain, domain))) 214 continue; // not accepted 215 216 // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2 217 // redundant; the "leading dot" rule has been relaxed anyway, see above 218 // we remove the leading dot for this check 219 if (QNetworkCookieJarPrivate::isEffectiveTLD(domain.remove(0, 1))) 220 continue; // not accepted 221 221 } 222 222 … … 251 251 differing paths, the one with longer path is returned before the 252 252 one with shorter path. In other words, this function returns 253 cookies sorted by path length.253 cookies sorted decreasingly by path length. 254 254 255 255 The default QNetworkCookieJar class implements only a very basic … … 270 270 QDateTime now = QDateTime::currentDateTime(); 271 271 QList<QNetworkCookie> result; 272 bool isEncrypted = url.scheme().toLower() == QLatin1String("https"); 272 273 273 274 // scan our cookies for something that matches … … 280 281 continue; 281 282 if (!(*it).isSessionCookie() && (*it).expirationDate() < now) 283 continue; 284 if ((*it).isSecure() && !isEncrypted) 282 285 continue; 283 286 … … 302 305 } 303 306 307 bool QNetworkCookieJarPrivate::isEffectiveTLD(const QString &domain) 308 { 309 // for domain 'foo.bar.com': 310 // 1. return if TLD table contains 'foo.bar.com' 311 if (containsTLDEntry(domain)) 312 return true; 313 314 if (domain.contains(QLatin1Char('.'))) { 315 int count = domain.size() - domain.indexOf(QLatin1Char('.')); 316 QString wildCardDomain; 317 wildCardDomain.reserve(count + 1); 318 wildCardDomain.append(QLatin1Char('*')); 319 wildCardDomain.append(domain.right(count)); 320 // 2. if table contains '*.bar.com', 321 // test if table contains '!foo.bar.com' 322 if (containsTLDEntry(wildCardDomain)) { 323 QString exceptionDomain; 324 exceptionDomain.reserve(domain.size() + 1); 325 exceptionDomain.append(QLatin1Char('!')); 326 exceptionDomain.append(domain); 327 return (! containsTLDEntry(exceptionDomain)); 328 } 329 } 330 return false; 331 } 332 333 bool QNetworkCookieJarPrivate::containsTLDEntry(const QString &entry) 334 { 335 int index = qHash(entry) % tldCount; 336 int currentDomainIndex = tldIndices[index]; 337 while (currentDomainIndex < tldIndices[index+1]) { 338 QString currentEntry = QString::fromUtf8(tldData + currentDomainIndex); 339 if (currentEntry == entry) 340 return true; 341 currentDomainIndex += qstrlen(tldData + currentDomainIndex) + 1; // +1 for the ending \0 342 } 343 return false; 344 } 345 304 346 QT_END_NAMESPACE -
trunk/src/network/access/qnetworkcookiejar.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qnetworkcookiejar_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 64 64 QList<QNetworkCookie> allCookies; 65 65 66 static bool Q_AUTOTEST_EXPORT isEffectiveTLD(const QString &domain); 67 static bool containsTLDEntry(const QString &entry); 68 66 69 Q_DECLARE_PUBLIC(QNetworkCookieJar) 67 70 }; -
trunk/src/network/access/qnetworkdiskcache.cpp
r774 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 512 512 QDirIterator it(cacheDirectory(), filters, QDirIterator::Subdirectories); 513 513 514 // performance tweak: we store the size together with the name in 515 // order to avoid querying the size again before the file is deleted 516 typedef QPair<QString, qint64> ExpireInfo; 517 518 QMultiMap<QDateTime, ExpireInfo> cacheItems; 514 QMultiMap<QDateTime, QString> cacheItems; 519 515 qint64 totalSize = 0; 520 516 while (it.hasNext()) { … … 523 519 QString fileName = info.fileName(); 524 520 if (fileName.endsWith(CACHE_POSTFIX) && fileName.startsWith(CACHE_PREFIX)) { 525 ExpireInfo item = qMakePair(path, info.size()); 526 cacheItems.insert(info.created(), item); 527 totalSize += item.second; 521 cacheItems.insert(info.created(), path); 522 totalSize += info.size(); 528 523 } 529 524 } … … 531 526 int removedFiles = 0; 532 527 qint64 goal = (maximumCacheSize() * 9) / 10; 533 QMultiMap<QDateTime, ExpireInfo>::const_iterator i = cacheItems.constBegin();528 QMultiMap<QDateTime, QString>::const_iterator i = cacheItems.constBegin(); 534 529 while (i != cacheItems.constEnd()) { 535 530 if (totalSize < goal) 536 531 break; 537 const ExpireInfo &item = i.value(); 538 QFile::remove(item.first); 539 totalSize -= item.second; 532 QString name = i.value(); 533 QFile file(name); 534 qint64 size = file.size(); 535 file.remove(); 536 totalSize -= size; 540 537 ++removedFiles; 541 538 ++i; -
trunk/src/network/access/qnetworkdiskcache.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qnetworkdiskcache_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qnetworkreply.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 126 126 should have been emitted. 127 127 128 \value TemporaryNetworkFailureError the connection was broken due 129 to disconnection from the network, however the system has initiated 130 roaming to another access point. The request should be resubmitted 131 and will be processed as soon as the connection is re-established. 132 128 133 \value ProxyConnectionRefusedError the connection to the proxy 129 134 server was refused (the proxy server is not accepting requests) … … 279 284 bytesTotal. At that time, \a bytesTotal will not be -1. 280 285 281 This signal is suitable to connecting to QProgressBar::setValue()282 to update the QProgressBar that provides user feedback.283 284 286 \sa downloadProgress() 285 287 */ … … 301 303 The download is finished when \a bytesReceived is equal to \a 302 304 bytesTotal. At that time, \a bytesTotal will not be -1. 303 304 This signal is suitable to connecting to QProgressBar::setValue()305 to update the QProgressBar that provides user feedback.306 305 307 306 Note that the values of both \a bytesReceived and \a bytesTotal … … 532 531 return it->second; 533 532 return QByteArray(); 533 } 534 535 /*! \typedef QNetworkReply::RawHeaderPair 536 537 RawHeaderPair is a QPair<QByteArray, QByteArray> where the first 538 QByteArray is the header name and the second is the header. 539 */ 540 541 /*! 542 Returns a list of raw header pairs. 543 */ 544 const QList<QNetworkReply::RawHeaderPair>& QNetworkReply::rawHeaderPairs() const 545 { 546 Q_D(const QNetworkReply); 547 return d->rawHeaders; 534 548 } 535 549 -
trunk/src/network/access/qnetworkreply.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 78 78 OperationCanceledError, 79 79 SslHandshakeFailedError, 80 TemporaryNetworkFailureError, 80 81 UnknownNetworkError = 99, 81 82 … … 129 130 QByteArray rawHeader(const QByteArray &headerName) const; 130 131 132 typedef QPair<QByteArray, QByteArray> RawHeaderPair; 133 const QList<RawHeaderPair>& rawHeaderPairs() const; 134 131 135 // attributes 132 136 QVariant attribute(QNetworkRequest::Attribute code) const; -
trunk/src/network/access/qnetworkreply_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/network/access/qnetworkreplyimpl.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 47 47 #include "QtCore/qdatetime.h" 48 48 #include "QtNetwork/qsslconfiguration.h" 49 #include "QtNetwork/qnetworksession.h" 49 50 #include "qnetworkaccesshttpbackend_p.h" 51 #include "qnetworkaccessmanager_p.h" 50 52 51 53 #include <QtCore/QCoreApplication> … … 58 60 cacheEnabled(false), cacheSaveDevice(0), 59 61 notificationHandlingPaused(false), 60 bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1), 62 bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1), preMigrationDownloaded(-1), 61 63 httpStatusCode(0), 62 64 state(Idle) … … 83 85 } 84 86 85 backend->open(); 86 if (state != Finished) { 87 if (operation == QNetworkAccessManager::GetOperation) 88 pendingNotifications.append(NotifyDownstreamReadyWrite); 89 90 handleNotifications(); 87 #ifndef QT_NO_BEARERMANAGEMENT 88 if (!backend->start()) { // ### we should call that method even if bearer is not used 89 // backend failed to start because the session state is not Connected. 90 // QNetworkAccessManager will call reply->backend->start() again for us when the session 91 // state changes. 92 state = WaitingForSession; 93 94 QNetworkSession *session = manager->d_func()->networkSession.data(); 95 96 if (session) { 97 Q_Q(QNetworkReplyImpl); 98 99 QObject::connect(session, SIGNAL(error(QNetworkSession::SessionError)), 100 q, SLOT(_q_networkSessionFailed())); 101 102 if (!session->isOpen()) 103 session->open(); 104 } else { 105 qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); 106 } 107 108 return; 109 } 110 #endif 111 112 if (backend && backend->isSynchronous()) { 113 state = Finished; 114 } else { 115 if (state != Finished) { 116 if (operation == QNetworkAccessManager::GetOperation) 117 pendingNotifications.append(NotifyDownstreamReadyWrite); 118 119 handleNotifications(); 120 } 91 121 } 92 122 } … … 135 165 lastBytesDownloaded = bytesDownloaded; 136 166 QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); 167 if (preMigrationDownloaded != Q_INT64_C(-1)) 168 totalSize = totalSize.toLongLong() + preMigrationDownloaded; 137 169 pauseNotificationHandling(); 138 170 emit q->downloadProgress(bytesDownloaded, … … 207 239 } 208 240 241 #ifndef QT_NO_BEARERMANAGEMENT 242 void QNetworkReplyImplPrivate::_q_networkSessionConnected() 243 { 244 Q_Q(QNetworkReplyImpl); 245 246 if (manager.isNull()) 247 return; 248 249 QNetworkSession *session = manager->d_func()->networkSession.data(); 250 if (!session) 251 return; 252 253 if (session->state() != QNetworkSession::Connected) 254 return; 255 256 switch (state) { 257 case QNetworkReplyImplPrivate::Buffering: 258 case QNetworkReplyImplPrivate::Working: 259 case QNetworkReplyImplPrivate::Reconnecting: 260 // Migrate existing downloads to new network connection. 261 migrateBackend(); 262 break; 263 case QNetworkReplyImplPrivate::WaitingForSession: 264 // Start waiting requests. 265 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 266 break; 267 default: 268 ; 269 } 270 } 271 272 void QNetworkReplyImplPrivate::_q_networkSessionFailed() 273 { 274 // Abort waiting and working replies. 275 if (state == WaitingForSession || state == Working) { 276 state = Working; 277 error(QNetworkReplyImpl::UnknownNetworkError, 278 QCoreApplication::translate("QNetworkReply", "Network session error.")); 279 finished(); 280 } 281 } 282 #endif 283 209 284 void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req, 210 285 QIODevice *data) … … 217 292 operation = op; 218 293 219 if (outgoingData && backend) { 294 q->QIODevice::open(QIODevice::ReadOnly); 295 // Internal code that does a HTTP reply for the synchronous Ajax 296 // in QtWebKit. 297 QVariant synchronousHttpAttribute = req.attribute( 298 static_cast<QNetworkRequest::Attribute>(QNetworkRequest::DownloadBufferAttribute + 1)); 299 if (backend && synchronousHttpAttribute.toBool()) { 300 backend->setSynchronous(true); 301 if (outgoingData && outgoingData->isSequential()) { 302 outgoingDataBuffer = new QRingBuffer(); 303 QByteArray data; 304 do { 305 data = outgoingData->readAll(); 306 if (data.isEmpty()) 307 break; 308 outgoingDataBuffer->append(data); 309 } while (1); 310 } 311 } 312 if (outgoingData && backend && !backend->isSynchronous()) { 220 313 // there is data to be uploaded, e.g. HTTP POST. 221 314 … … 228 321 bool bufferingDisallowed = 229 322 req.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute, 230 323 false).toBool(); 231 324 232 325 if (bufferingDisallowed) { … … 252 345 // for HTTP, we want to send out the request as fast as possible to the network, without 253 346 // invoking methods in a QueuedConnection 254 if (qobject_cast<QNetworkAccessHttpBackend *>(backend)) { 347 #ifndef QT_NO_HTTP 348 if (qobject_cast<QNetworkAccessHttpBackend *>(backend) || (backend && backend->isSynchronous())) { 255 349 _q_startOperation(); 256 350 } else { 257 351 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 258 352 } 259 } 260 261 q->QIODevice::open(QIODevice::ReadOnly); 353 #else 354 if (backend && backend->isSynchronous()) 355 _q_startOperation(); 356 else 357 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 358 #endif // QT_NO_HTTP 359 } 262 360 } 263 361 … … 472 570 473 571 QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); 572 if (preMigrationDownloaded != Q_INT64_C(-1)) 573 totalSize = totalSize.toLongLong() + preMigrationDownloaded; 474 574 pauseNotificationHandling(); 475 575 emit q->downloadProgress(bytesDownloaded, … … 512 612 void QNetworkReplyImplPrivate::appendDownstreamData(const QByteArray &data) 513 613 { 614 Q_UNUSED(data) 514 615 // TODO implement 515 616 … … 522 623 { 523 624 Q_Q(QNetworkReplyImpl); 524 if (state == Finished || state == Aborted) 525 return; 625 626 if (state == Finished || state == Aborted || state == WaitingForSession) 627 return; 628 629 pauseNotificationHandling(); 630 QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); 631 if (preMigrationDownloaded != Q_INT64_C(-1)) 632 totalSize = totalSize.toLongLong() + preMigrationDownloaded; 633 634 if (!manager.isNull()) { 635 #ifndef QT_NO_BEARERMANAGEMENT 636 QNetworkSession *session = manager->d_func()->networkSession.data(); 637 if (session && session->state() == QNetworkSession::Roaming && 638 state == Working && errorCode != QNetworkReply::OperationCanceledError) { 639 // only content with a known size will fail with a temporary network failure error 640 if (!totalSize.isNull()) { 641 if (bytesDownloaded != totalSize) { 642 if (migrateBackend()) { 643 // either we are migrating or the request is finished/aborted 644 if (state == Reconnecting || state == WaitingForSession) { 645 resumeNotificationHandling(); 646 return; // exit early if we are migrating. 647 } 648 } else { 649 error(QNetworkReply::TemporaryNetworkFailureError, 650 QNetworkReply::tr("Temporary network failure.")); 651 } 652 } 653 } 654 } 655 #endif 656 } 657 resumeNotificationHandling(); 526 658 527 659 state = Finished; … … 529 661 530 662 pauseNotificationHandling(); 531 QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);532 663 if (totalSize.isNull() || totalSize == -1) { 533 664 emit q->downloadProgress(bytesDownloaded, bytesDownloaded); … … 538 669 resumeNotificationHandling(); 539 670 540 completeCacheSave(); 671 // if we don't know the total size of or we received everything save the cache 672 if (totalSize.isNull() || totalSize == -1 || bytesDownloaded == totalSize) 673 completeCacheSave(); 541 674 542 675 // note: might not be a good idea, since users could decide to delete us … … 565 698 { 566 699 Q_Q(QNetworkReplyImpl); 567 // do we have cookies? 568 if (cookedHeaders.contains(QNetworkRequest::SetCookieHeader) && !manager.isNull()) { 700 // 1. do we have cookies? 701 // 2. are we allowed to set them? 702 if (cookedHeaders.contains(QNetworkRequest::SetCookieHeader) && !manager.isNull() 703 && (static_cast<QNetworkRequest::LoadControl> 704 (request.attribute(QNetworkRequest::CookieSaveControlAttribute, 705 QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic)) { 569 706 QList<QNetworkCookie> cookies = 570 707 qvariant_cast<QList<QNetworkCookie> >(cookedHeaders.value(QNetworkRequest::SetCookieHeader)); … … 662 799 d->finished(); 663 800 } 801 802 bool QNetworkReplyImpl::canReadLine () const 803 { 804 Q_D(const QNetworkReplyImpl); 805 return QNetworkReply::canReadLine() || d->readBuffer.canReadLine(); 806 } 807 664 808 665 809 /*! … … 751 895 } 752 896 897 /* 898 Migrates the backend of the QNetworkReply to a new network connection if required. Returns 899 true if the reply is migrated or it is not required; otherwise returns false. 900 */ 901 bool QNetworkReplyImplPrivate::migrateBackend() 902 { 903 Q_Q(QNetworkReplyImpl); 904 905 // Network reply is already finished or aborted, don't need to migrate. 906 if (state == Finished || state == Aborted) 907 return true; 908 909 // Backend does not support resuming download. 910 if (!backend->canResume()) 911 return false; 912 913 // Request has outgoing data, not migrating. 914 if (outgoingData) 915 return false; 916 917 // Request is serviced from the cache, don't need to migrate. 918 if (copyDevice) 919 return true; 920 921 state = QNetworkReplyImplPrivate::Reconnecting; 922 923 if (backend) { 924 delete backend; 925 backend = 0; 926 } 927 928 cookedHeaders.clear(); 929 rawHeaders.clear(); 930 931 preMigrationDownloaded = bytesDownloaded; 932 933 backend = manager->d_func()->findBackend(operation, request); 934 935 if (backend) { 936 backend->setParent(q); 937 backend->reply = this; 938 backend->setResumeOffset(bytesDownloaded); 939 } 940 941 #ifndef QT_NO_HTTP 942 if (qobject_cast<QNetworkAccessHttpBackend *>(backend)) { 943 _q_startOperation(); 944 } else { 945 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 946 } 947 #else 948 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 949 #endif // QT_NO_HTTP 950 951 return true; 952 } 953 954 #ifndef QT_NO_BEARERMANAGEMENT 955 QDisabledNetworkReply::QDisabledNetworkReply(QObject *parent, 956 const QNetworkRequest &req, 957 QNetworkAccessManager::Operation op) 958 : QNetworkReply(parent) 959 { 960 setRequest(req); 961 setUrl(req.url()); 962 setOperation(op); 963 964 qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError"); 965 966 QString msg = QCoreApplication::translate("QNetworkAccessManager", 967 "Network access is disabled."); 968 setError(UnknownNetworkError, msg); 969 970 QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, 971 Q_ARG(QNetworkReply::NetworkError, UnknownNetworkError)); 972 QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); 973 } 974 975 QDisabledNetworkReply::~QDisabledNetworkReply() 976 { 977 } 978 #endif 979 753 980 QT_END_NAMESPACE 754 981 -
trunk/src/network/access/qnetworkreplyimpl_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 78 78 virtual void abort(); 79 79 80 // reimplemented from QNetworkReply 80 // reimplemented from QNetworkReply / QIODevice 81 81 virtual void close(); 82 82 virtual qint64 bytesAvailable() const; 83 83 virtual void setReadBufferSize(qint64 size); 84 virtual bool canReadLine () const; 84 85 85 86 virtual qint64 readData(char *data, qint64 maxlen); … … 99 100 Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData()) 100 101 Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished()) 102 #ifndef QT_NO_BEARERMANAGEMENT 103 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) 104 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) 105 #endif 101 106 }; 102 107 … … 111 116 112 117 enum State { 113 Idle, 114 Buffering, 115 Working, 116 Finished, 117 Aborted 118 Idle, // The reply is idle. 119 Buffering, // The reply is buffering outgoing data. 120 Working, // The reply is uploading/downloading data. 121 Finished, // The reply has finished. 122 Aborted, // The reply has been aborted. 123 WaitingForSession, // The reply is waiting for the session to open before connecting. 124 Reconnecting // The reply will reconnect to once roaming has completed. 118 125 }; 119 126 … … 129 136 void _q_bufferOutgoingData(); 130 137 void _q_bufferOutgoingDataFinished(); 138 #ifndef QT_NO_BEARERMANAGEMENT 139 void _q_networkSessionConnected(); 140 void _q_networkSessionFailed(); 141 #endif 131 142 132 143 void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request, … … 167 178 QAbstractNetworkCache *networkCache() const; 168 179 180 bool migrateBackend(); 181 169 182 bool cacheEnabled; 170 183 QIODevice *cacheSaveDevice; … … 183 196 qint64 lastBytesDownloaded; 184 197 qint64 bytesUploaded; 198 qint64 preMigrationDownloaded; 185 199 186 200 QString httpReasonPhrase; … … 192 206 }; 193 207 208 #ifndef QT_NO_BEARERMANAGEMENT 209 class QDisabledNetworkReply : public QNetworkReply 210 { 211 Q_OBJECT 212 213 public: 214 QDisabledNetworkReply(QObject *parent, const QNetworkRequest &req, 215 QNetworkAccessManager::Operation op); 216 ~QDisabledNetworkReply(); 217 218 void abort() { } 219 protected: 220 qint64 readData(char *, qint64) { return -1; } 221 }; 222 #endif 223 194 224 QT_END_NAMESPACE 195 225 -
trunk/src/network/access/qnetworkrequest.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 106 106 /*! 107 107 \enum QNetworkRequest::Attribute 108 108 \since 4.7 109 109 110 Attribute codes for the QNetworkRequest and QNetworkReply. 110 111 … … 175 176 header must be set. 176 177 177 178 \value HttpPipeliningAllowedAttribute 178 179 Requests only, type: QVariant::Bool (default: false) 179 180 Indicates whether the QNetworkAccessManager code is 180 181 allowed to use HTTP pipelining with this request. 181 182 182 183 \value HttpPipeliningWasUsedAttribute 183 184 Replies only, type: QVariant::Bool 184 185 Indicates whether the HTTP pipelining was used for receiving 185 186 this reply. 187 188 \value CustomVerbAttribute 189 Requests only, type: QVariant::ByteArray 190 Holds the value for the custom HTTP verb to send (destined for usage 191 of other verbs than GET, POST, PUT and DELETE). This verb is set 192 when calling QNetworkAccessManager::sendCustomRequest(). 193 194 \value CookieLoadControlAttribute 195 Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) 196 Indicates whether to send 'Cookie' headers in the request. 197 This attribute is set to false by QtWebKit when creating a cross-origin 198 XMLHttpRequest where withCredentials has not been set explicitly to true by the 199 Javascript that created the request. 200 See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag}{here} for more information. 201 (This value was introduced in 4.7.) 202 203 \value CookieSaveControlAttribute 204 Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) 205 Indicates whether to save 'Cookie' headers received from the server in reply 206 to the request. 207 This attribute is set to false by QtWebKit when creating a cross-origin 208 XMLHttpRequest where withCredentials has not been set explicitly to true by the 209 Javascript that created the request. 210 See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information. 211 (This value was introduced in 4.7.) 212 213 \value AuthenticationReuseAttribute 214 Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) 215 Indicates whether to use cached authorization credentials in the request, 216 if available. If this is set to QNetworkRequest::Manual and the authentication 217 mechanism is 'Basic' or 'Digest', Qt will not send an an 'Authorization' HTTP 218 header with any cached credentials it may have for the request's URL. 219 This attribute is set to QNetworkRequest::Manual by QtWebKit when creating a cross-origin 220 XMLHttpRequest where withCredentials has not been set explicitly to true by the 221 Javascript that created the request. 222 See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information. 223 (This value was introduced in 4.7.) 224 225 \omitvalue MaximumDownloadBufferSizeAttribute 226 227 \omitvalue DownloadBufferAttribute 186 228 187 229 \value User … … 217 259 */ 218 260 261 /*! 262 \enum QNetworkRequest::LoadControl 263 \since 4.7 264 265 Indicates if an aspect of the request's loading mechanism has been 266 manually overridden, e.g. by QtWebKit. 267 268 \value Automatic default value: indicates default behaviour. 269 270 \value Manual indicates behaviour has been manually overridden. 271 */ 272 219 273 class QNetworkRequestPrivate: public QSharedData, public QNetworkHeadersPrivate 220 274 { 221 275 public: 222 276 inline QNetworkRequestPrivate() 277 : priority(QNetworkRequest::NormalPriority) 223 278 #ifndef QT_NO_OPENSSL 224 :sslConfiguration(0)279 , sslConfiguration(0) 225 280 #endif 226 281 { qRegisterMetaType<QNetworkRequest>(); } … … 237 292 { 238 293 url = other.url; 294 priority = other.priority; 239 295 240 296 #ifndef QT_NO_OPENSSL … … 248 304 { 249 305 return url == other.url && 306 priority == other.priority && 250 307 rawHeaders == other.rawHeaders && 251 308 attributes == other.attributes; … … 254 311 255 312 QUrl url; 313 QNetworkRequest::Priority priority; 256 314 #ifndef QT_NO_OPENSSL 257 315 mutable QSslConfiguration *sslConfiguration; … … 517 575 { 518 576 return d->originatingObject.data(); 577 } 578 579 /*! 580 \since 4.7 581 582 Return the priority of this request. 583 584 \sa setPriority() 585 */ 586 QNetworkRequest::Priority QNetworkRequest::priority() const 587 { 588 return d->priority; 589 } 590 591 /*! \enum QNetworkRequest::Priority 592 593 \since 4.7 594 595 This enum lists the possible network request priorities. 596 597 \value HighPriority High priority 598 \value NormalPriority Normal priority 599 \value LowPriority Low priority 600 */ 601 602 /*! 603 \since 4.7 604 605 Set the priority of this request to \a priority. 606 607 \note The \a priority is only a hint to the network access 608 manager. It can use it or not. Currently it is used for HTTP to 609 decide which request should be sent first to a server. 610 611 \sa priority() 612 */ 613 void QNetworkRequest::setPriority(Priority priority) 614 { 615 d->priority = priority; 519 616 } 520 617 … … 803 900 QNetworkRequest::KnownHeaders parsedKey = parseHeaderName(key); 804 901 if (parsedKey != QNetworkRequest::KnownHeaders(-1)) { 805 if (value.isNull()) 902 if (value.isNull()) { 806 903 cookedHeaders.remove(parsedKey); 807 else 904 } else if (parsedKey == QNetworkRequest::ContentLengthHeader 905 && cookedHeaders.contains(QNetworkRequest::ContentLengthHeader)) { 906 // Only set the cooked header "Content-Length" once. 907 // See bug QTBUG-15311 908 } else { 808 909 cookedHeaders.insert(parsedKey, parseHeaderValue(parsedKey, value)); 910 } 911 809 912 } 810 913 } -
trunk/src/network/access/qnetworkrequest.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 79 79 HttpPipeliningAllowedAttribute, 80 80 HttpPipeliningWasUsedAttribute, 81 CustomVerbAttribute, 82 CookieLoadControlAttribute, 83 AuthenticationReuseAttribute, 84 CookieSaveControlAttribute, 85 MaximumDownloadBufferSizeAttribute, // internal 86 DownloadBufferAttribute, // internal 87 88 // (DownloadBufferAttribute + 1) is reserved internal for QSynchronousHttpNetworkReply 89 // add the enum in 4.8 81 90 82 91 User = 1000, … … 88 97 PreferCache, 89 98 AlwaysCache 99 }; 100 enum LoadControl { 101 Automatic = 0, 102 Manual 103 }; 104 105 enum Priority { 106 HighPriority = 1, 107 NormalPriority = 3, 108 LowPriority = 5 90 109 }; 91 110 … … 124 143 QObject *originatingObject() const; 125 144 145 Priority priority() const; 146 void setPriority(Priority priority); 147 126 148 private: 127 149 QSharedDataPointer<QNetworkRequestPrivate> d; -
trunk/src/network/access/qnetworkrequest_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
Note:
See TracChangeset
for help on using the changeset viewer.