Changeset 846 for trunk/src/network
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 deleted
- 141 edited
- 21 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) -
trunk/src/network/kernel/kernel.pri
r561 r846 29 29 mac:SOURCES += kernel/qnetworkproxy_mac.cpp 30 30 else:win32:SOURCES += kernel/qnetworkproxy_win.cpp 31 else:symbian:SOURCES += kernel/qnetworkproxy_symbian.cpp 31 32 else:SOURCES += kernel/qnetworkproxy_generic.cpp 32 33 34 symbian: LIBS += -lcommsdat -
trunk/src/network/kernel/qauthenticator.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 <qendian.h> 52 52 #include <qstring.h> 53 #include <qdatetime.h> 54 55 //#define NTLMV1_CLIENT 53 56 54 57 QT_BEGIN_NAMESPACE 55 58 59 #ifdef NTLMV1_CLIENT 56 60 #include "../../3rdparty/des/des.cpp" 61 #endif 57 62 58 63 static QByteArray qNtlmPhase1(); … … 84 89 Note that, in particular, NTLM version 2 is not supported. 85 90 91 \section1 Options 92 93 In addition to the username and password required for authentication, a 94 QAuthenticator object can also contain additional options. The 95 options() function can be used to query incoming options sent by 96 the server; the setOption() function can 97 be used to set outgoing options, to be processed by the authenticator 98 calculation. The options accepted and provided depend on the authentication 99 type (see method()). 100 101 The following tables list known incoming options as well as accepted 102 outgoing options. The list of incoming options is not exhaustive, since 103 servers may include additional information at any time. The list of 104 outgoing options is exhaustive, however, and no unknown options will be 105 treated or sent back to the server. 106 107 \section2 Basic 108 109 \table 110 \header \o Option \o Direction \o Description 111 \row \o \tt{realm} \o Incoming \o Contains the realm of the authentication, the same as realm() 112 \endtable 113 114 The Basic authentication mechanism supports no outgoing options. 115 116 \section2 NTLM version 1 117 118 The NTLM authentication mechanism currently supports no incoming or outgoing options. 119 120 \section2 Digest-MD5 121 122 \table 123 \header \o Option \o Direction \o Description 124 \row \o \tt{realm} \o Incoming \o Contains the realm of the authentication, the same as realm() 125 \endtable 126 127 The Digest-MD5 authentication mechanism supports no outgoing options. 128 86 129 \sa QSslSocket 87 130 */ … … 122 165 if (d == other.d) 123 166 return *this; 124 detach(); 125 d->user = other.d->user; 126 d->password = other.d->password; 167 168 if (d && !d->ref.deref()) 169 delete d; 170 171 d = other.d; 172 if (d) 173 d->ref.ref(); 127 174 return *this; 128 175 } … … 139 186 && d->password == other.d->password 140 187 && d->realm == other.d->realm 141 && d->method == other.d->method; 188 && d->method == other.d->method 189 && d->options == other.d->options; 142 190 } 143 191 … … 163 211 { 164 212 detach(); 165 d->user = user; 213 int separatorPosn = 0; 214 215 switch(d->method) { 216 case QAuthenticatorPrivate::Ntlm: 217 if((separatorPosn = user.indexOf(QLatin1String("\\"))) != -1) { 218 //domain name is present 219 d->realm.clear(); 220 d->userDomain = user.left(separatorPosn); 221 d->extractedUser = user.mid(separatorPosn + 1); 222 d->user = user; 223 } else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) { 224 //domain name is present 225 d->realm.clear(); 226 d->userDomain = user.left(separatorPosn); 227 d->extractedUser = user.left(separatorPosn); 228 d->user = user; 229 } else { 230 d->extractedUser = user; 231 d->user = user; 232 d->realm.clear(); 233 d->userDomain.clear(); 234 } 235 break; 236 default: 237 d->user = user; 238 d->userDomain.clear(); 239 break; 240 } 166 241 } 167 242 … … 206 281 } 207 282 208 209 /*! 210 returns true if the authenticator is null. 283 /*! 284 \since 4.7 285 Returns the value related to option \a opt if it was set by the server. 286 See \l{QAuthenticator#Options} for more information on incoming options. 287 If option \a opt isn't found, an invalid QVariant will be returned. 288 289 \sa options(), QAuthenticator#Options 290 */ 291 QVariant QAuthenticator::option(const QString &opt) const 292 { 293 return d ? d->options.value(opt) : QVariant(); 294 } 295 296 /*! 297 \since 4.7 298 Returns all incoming options set in this QAuthenticator object by parsing 299 the server reply. See \l{QAuthenticator#Options} for more information 300 on incoming options. 301 302 \sa option(), QAuthenticator#Options 303 */ 304 QVariantHash QAuthenticator::options() const 305 { 306 return d ? d->options : QVariantHash(); 307 } 308 309 /*! 310 \since 4.7 311 312 Sets the outgoing option \a opt to value \a value. 313 See \l{QAuthenticator#Options} for more information on outgoing options. 314 315 \sa options(), option(), QAuthenticator#Options 316 */ 317 void QAuthenticator::setOption(const QString &opt, const QVariant &value) 318 { 319 detach(); 320 d->options.insert(opt, value); 321 } 322 323 324 /*! 325 Returns true if the authenticator is null. 211 326 */ 212 327 bool QAuthenticator::isNull() const … … 229 344 void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, bool isProxy) 230 345 { 231 QList<QPair<QString, QString> > values = header.values(); 346 const QList<QPair<QString, QString> > values = header.values(); 347 QList<QPair<QByteArray, QByteArray> > rawValues; 348 349 QList<QPair<QString, QString> >::const_iterator it, end; 350 for (it = values.constBegin(), end = values.constEnd(); it != end; ++it) 351 rawValues.append(qMakePair(it->first.toLatin1(), it->second.toUtf8())); 352 353 // continue in byte array form 354 parseHttpResponse(rawValues, isProxy); 355 } 356 #endif 357 358 void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByteArray> > &values, bool isProxy) 359 { 232 360 const char *search = isProxy ? "proxy-authenticate" : "www-authenticate"; 233 361 … … 243 371 */ 244 372 245 Q StringheaderVal;373 QByteArray headerVal; 246 374 for (int i = 0; i < values.size(); ++i) { 247 const QPair<Q String, QString> ¤t = values.at(i);248 if (current.first.toLower() != QLatin1String(search))375 const QPair<QByteArray, QByteArray> ¤t = values.at(i); 376 if (current.first.toLower() != search) 249 377 continue; 250 QString str = current.second; 251 if (method < Basic && str.startsWith(QLatin1String("Basic"), Qt::CaseInsensitive)) { 252 method = Basic; headerVal = str.mid(6); 253 } else if (method < Ntlm && str.startsWith(QLatin1String("NTLM"), Qt::CaseInsensitive)) { 378 QByteArray str = current.second.toLower(); 379 if (method < Basic && str.startsWith("basic")) { 380 method = Basic; 381 headerVal = current.second.mid(6); 382 } else if (method < Ntlm && str.startsWith("ntlm")) { 254 383 method = Ntlm; 255 headerVal = str.mid(5);256 } else if (method < DigestMd5 && str.startsWith( QLatin1String("Digest"), Qt::CaseInsensitive)) {384 headerVal = current.second.mid(5); 385 } else if (method < DigestMd5 && str.startsWith("digest")) { 257 386 method = DigestMd5; 258 headerVal = str.mid(7);387 headerVal = current.second.mid(7); 259 388 } 260 389 } 261 390 262 challenge = headerVal.trimmed() .toLatin1();391 challenge = headerVal.trimmed(); 263 392 QHash<QByteArray, QByteArray> options = parseDigestAuthenticationChallenge(challenge); 264 393 265 394 switch(method) { 266 395 case Basic: 267 realm = QString::fromLatin1(options.value("realm")); 396 if(realm.isEmpty()) 397 this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm")); 268 398 if (user.isEmpty()) 269 399 phase = Done; … … 271 401 case Ntlm: 272 402 // #### extract from header 273 realm.clear();274 403 break; 275 404 case DigestMd5: { 276 realm = QString::fromLatin1(options.value("realm")); 405 if(realm.isEmpty()) 406 this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm")); 277 407 if (options.value("stale").toLower() == "true") 278 408 phase = Start; … … 287 417 } 288 418 } 289 #endif290 419 291 420 QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMethod, const QByteArray &path) … … 662 791 #define NTLMSSP_NEGOTIATE_56 0x80000000 663 792 793 /* 794 * AvId values 795 */ 796 #define AVTIMESTAMP 7 797 798 //#define NTLMV1_CLIENT 799 800 801 //************************Global variables*************************** 802 803 const int blockSize = 64; //As per RFC2104 Block-size is 512 bits 804 const int nDigestLen = 16; //Trunctaion Length of the Hmac-Md5 digest 805 const quint8 respversion = 1; 806 const quint8 hirespversion = 1; 664 807 665 808 /* usage: … … 804 947 // extracted 805 948 QString targetNameStr, targetInfoStr; 949 QByteArray targetInfoBuff; 806 950 }; 807 951 … … 819 963 QByteArray lmResponseBuf, ntlmResponseBuf; 820 964 QString domainStr, userStr, workstationStr, sessionKeyStr; 965 QByteArray v2Hash; 821 966 }; 822 967 … … 900 1045 } 901 1046 902 1047 #ifdef NTLMV1_CLIENT 903 1048 static QByteArray qEncodeNtlmResponse(const QAuthenticatorPrivate *ctx, const QNtlmPhase2Block& ch) 904 1049 { … … 942 1087 return rc; 943 1088 } 944 1089 #endif 1090 1091 /********************************************************************* 1092 * Function Name: qEncodeHmacMd5 1093 * Params: 1094 * key: Type - QByteArray 1095 * - It is the Authentication key 1096 * message: Type - QByteArray 1097 * - This is the actual message which will be encoded 1098 * using HMacMd5 hash algorithm 1099 * 1100 * Return Value: 1101 * hmacDigest: Type - QByteArray 1102 * 1103 * Description: 1104 * This function will be used to encode the input message using 1105 * HMacMd5 hash algorithm. 1106 * 1107 * As per the RFC2104 the HMacMd5 algorithm can be specified 1108 * --------------------------------------- 1109 * MD5(K XOR opad, MD5(K XOR ipad, text)) 1110 * --------------------------------------- 1111 * 1112 *********************************************************************/ 1113 QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message) 1114 { 1115 Q_ASSERT_X(!(message.isEmpty()),"qEncodeHmacMd5", "Empty message check"); 1116 Q_ASSERT_X(!(key.isEmpty()),"qEncodeHmacMd5", "Empty key check"); 1117 1118 QCryptographicHash hash(QCryptographicHash::Md5); 1119 QByteArray hMsg; 1120 1121 QByteArray iKeyPad(blockSize, 0x36); 1122 QByteArray oKeyPad(blockSize, 0x5c); 1123 1124 hash.reset(); 1125 // Adjust the key length to blockSize 1126 1127 if(blockSize < key.length()) { 1128 hash.addData(key); 1129 key = hash.result(); //MD5 will always return 16 bytes length output 1130 } 1131 1132 //Key will be <= 16 or 20 bytes as hash function (MD5 or SHA hash algorithms) 1133 //key size can be max of Block size only 1134 key = key.leftJustified(blockSize,0,true); 1135 1136 //iKeyPad, oKeyPad and key are all of same size "blockSize" 1137 1138 //xor of iKeyPad with Key and store the result into iKeyPad 1139 for(int i = 0; i<key.size();i++) { 1140 iKeyPad[i] = key[i]^iKeyPad[i]; 1141 } 1142 1143 //xor of oKeyPad with Key and store the result into oKeyPad 1144 for(int i = 0; i<key.size();i++) { 1145 oKeyPad[i] = key[i]^oKeyPad[i]; 1146 } 1147 1148 iKeyPad.append(message); // (K0 xor ipad) || text 1149 1150 hash.reset(); 1151 hash.addData(iKeyPad); 1152 hMsg = hash.result(); 1153 //Digest gen after pass-1: H((K0 xor ipad)||text) 1154 1155 QByteArray hmacDigest; 1156 oKeyPad.append(hMsg); 1157 hash.reset(); 1158 hash.addData(oKeyPad); 1159 hmacDigest = hash.result(); 1160 // H((K0 xor opad )|| H((K0 xor ipad) || text)) 1161 1162 /*hmacDigest should not be less than half the length of the HMAC output 1163 (to match the birthday attack bound) and not less than 80 bits 1164 (a suitable lower bound on the number of bits that need to be 1165 predicted by an attacker). 1166 Refer RFC 2104 for more details on truncation part */ 1167 1168 /*MD5 hash always returns 16 byte digest only and HMAC-MD5 spec 1169 (RFC 2104) also says digest length should be 16 bytes*/ 1170 return hmacDigest; 1171 } 1172 1173 static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx, 1174 QNtlmPhase3Block *phase3) 1175 { 1176 Q_ASSERT(phase3 != 0); 1177 // since v2 Hash is need for both NTLMv2 and LMv2 it is calculated 1178 // only once and stored and reused 1179 if(phase3->v2Hash.size() == 0) { 1180 QCryptographicHash md4(QCryptographicHash::Md4); 1181 QByteArray passUnicode = qStringAsUcs2Le(ctx->password); 1182 md4.addData(passUnicode.data(), passUnicode.size()); 1183 1184 QByteArray hashKey = md4.result(); 1185 Q_ASSERT(hashKey.size() == 16); 1186 // Assuming the user and domain is always unicode in challenge 1187 QByteArray message = 1188 qStringAsUcs2Le(ctx->extractedUser.toUpper()) + 1189 qStringAsUcs2Le(phase3->domainStr); 1190 1191 phase3->v2Hash = qEncodeHmacMd5(hashKey, message); 1192 } 1193 return phase3->v2Hash; 1194 } 1195 1196 static QByteArray clientChallenge(const QAuthenticatorPrivate *ctx) 1197 { 1198 Q_ASSERT(ctx->cnonce.size() >= 8); 1199 QByteArray clientCh = ctx->cnonce.right(8); 1200 return clientCh; 1201 } 1202 1203 // caller has to ensure a valid targetInfoBuff 1204 static QByteArray qExtractServerTime(const QByteArray& targetInfoBuff) 1205 { 1206 QByteArray timeArray; 1207 QDataStream ds(targetInfoBuff); 1208 ds.setByteOrder(QDataStream::LittleEndian); 1209 1210 quint16 avId; 1211 quint16 avLen; 1212 1213 ds >> avId; 1214 ds >> avLen; 1215 while(avId != 0) { 1216 if(avId == AVTIMESTAMP) { 1217 timeArray.resize(avLen); 1218 //avLen size of QByteArray is allocated 1219 ds.readRawData(timeArray.data(), avLen); 1220 break; 1221 } 1222 ds.skipRawData(avLen); 1223 ds >> avId; 1224 ds >> avLen; 1225 } 1226 return timeArray; 1227 } 1228 1229 static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx, 1230 const QNtlmPhase2Block& ch, 1231 QNtlmPhase3Block *phase3) 1232 { 1233 Q_ASSERT(phase3 != 0); 1234 // return value stored in phase3 1235 qCreatev2Hash(ctx, phase3); 1236 1237 QByteArray temp; 1238 QDataStream ds(&temp, QIODevice::WriteOnly); 1239 ds.setByteOrder(QDataStream::LittleEndian); 1240 1241 ds << respversion; 1242 ds << hirespversion; 1243 1244 //Reserved 1245 QByteArray reserved1(6, 0); 1246 ds.writeRawData(reserved1.constData(), reserved1.size()); 1247 1248 quint64 time = 0; 1249 QByteArray timeArray; 1250 1251 if(ch.targetInfo.len) 1252 { 1253 timeArray = qExtractServerTime(ch.targetInfoBuff); 1254 } 1255 1256 //if server sends time, use it instead of current time 1257 if(timeArray.size()) { 1258 ds.writeRawData(timeArray.constData(), timeArray.size()); 1259 } else { 1260 QDateTime currentTime(QDate::currentDate(), 1261 QTime::currentTime(), Qt::UTC); 1262 1263 // number of seconds between 1601 and epoc(1970) 1264 // 369 years, 89 leap years 1265 // ((369 * 365) + 89) * 24 * 3600 = 11644473600 1266 1267 time = Q_UINT64_C(currentTime.toTime_t() + 11644473600); 1268 1269 // represented as 100 nano seconds 1270 time = Q_UINT64_C(time * 10000000); 1271 ds << time; 1272 } 1273 1274 //8 byte client challenge 1275 QByteArray clientCh = clientChallenge(ctx); 1276 ds.writeRawData(clientCh.constData(), clientCh.size()); 1277 1278 //Reserved 1279 QByteArray reserved2(4, 0); 1280 ds.writeRawData(reserved2.constData(), reserved2.size()); 1281 1282 if (ch.targetInfo.len > 0) { 1283 ds.writeRawData(ch.targetInfoBuff.constData(), 1284 ch.targetInfoBuff.size()); 1285 } 1286 1287 //Reserved 1288 QByteArray reserved3(4, 0); 1289 ds.writeRawData(reserved3.constData(), reserved3.size()); 1290 1291 QByteArray message((const char*)ch.challenge, sizeof(ch.challenge)); 1292 message.append(temp); 1293 1294 QByteArray ntChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message); 1295 ntChallengeResp.append(temp); 1296 1297 return ntChallengeResp; 1298 } 1299 1300 static QByteArray qEncodeLmv2Response(const QAuthenticatorPrivate *ctx, 1301 const QNtlmPhase2Block& ch, 1302 QNtlmPhase3Block *phase3) 1303 { 1304 Q_ASSERT(phase3 != 0); 1305 // return value stored in phase3 1306 qCreatev2Hash(ctx, phase3); 1307 1308 QByteArray message((const char*)ch.challenge, sizeof(ch.challenge)); 1309 QByteArray clientCh = clientChallenge(ctx); 1310 1311 message.append(clientCh); 1312 1313 QByteArray lmChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message); 1314 lmChallengeResp.append(clientCh); 1315 1316 return lmChallengeResp; 1317 } 945 1318 946 1319 static bool qNtlmDecodePhase2(const QByteArray& data, QNtlmPhase2Block& ch) … … 977 1350 978 1351 if (ch.targetInfo.len > 0) { 979 // UNUSED right now 1352 if (ch.targetInfo.len + ch.targetInfo.offset > (unsigned)data.size()) 1353 return false; 1354 1355 ch.targetInfoBuff = data.mid(ch.targetInfo.offset, ch.targetInfo.len); 980 1356 } 981 1357 … … 996 1372 997 1373 bool unicode = ch.flags & NTLMSSP_NEGOTIATE_UNICODE; 998 999 ctx->realm = ch.targetNameStr;1000 1374 1001 1375 pb.flags = NTLMSSP_NEGOTIATE_NTLM; … … 1009 1383 Q_ASSERT(QNtlmPhase3BlockBase::Size == sizeof(QNtlmPhase3BlockBase)); 1010 1384 1011 offset = qEncodeNtlmString(pb.domain, offset, ctx->realm, unicode); 1012 pb.domainStr = ctx->realm; 1013 offset = qEncodeNtlmString(pb.user, offset, ctx->user, unicode); 1014 pb.userStr = ctx->user; 1385 if(ctx->userDomain.isEmpty()) { 1386 offset = qEncodeNtlmString(pb.domain, offset, ch.targetNameStr, unicode); 1387 pb.domainStr = ch.targetNameStr; 1388 } else { 1389 offset = qEncodeNtlmString(pb.domain, offset, ctx->userDomain, unicode); 1390 pb.domainStr = ctx->userDomain; 1391 } 1392 1393 offset = qEncodeNtlmString(pb.user, offset, ctx->extractedUser, unicode); 1394 pb.userStr = ctx->extractedUser; 1015 1395 1016 1396 offset = qEncodeNtlmString(pb.workstation, offset, ctx->workstation, unicode); … … 1018 1398 1019 1399 // Get LM response 1400 #ifdef NTLMV1_CLIENT 1020 1401 pb.lmResponseBuf = qEncodeLmResponse(ctx, ch); 1402 #else 1403 if (ch.targetInfo.len > 0) { 1404 pb.lmResponseBuf = QByteArray(); 1405 } else { 1406 pb.lmResponseBuf = qEncodeLmv2Response(ctx, ch, &pb); 1407 } 1408 #endif 1021 1409 offset = qEncodeNtlmBuffer(pb.lmResponse, offset, pb.lmResponseBuf); 1022 1410 1023 1411 // Get NTLM response 1412 #ifdef NTLMV1_CLIENT 1024 1413 pb.ntlmResponseBuf = qEncodeNtlmResponse(ctx, ch); 1414 #else 1415 pb.ntlmResponseBuf = qEncodeNtlmv2Response(ctx, ch, &pb); 1416 #endif 1025 1417 offset = qEncodeNtlmBuffer(pb.ntlmResponse, offset, pb.ntlmResponseBuf); 1026 1418 -
trunk/src/network/kernel/qauthenticator.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) … … 44 44 45 45 #include <QtCore/qstring.h> 46 #include <QtCore/qvariant.h> 46 47 47 48 QT_BEGIN_HEADER … … 74 75 QString realm() const; 75 76 77 QVariant option(const QString &opt) const; 78 QVariantHash options() const; 79 void setOption(const QString &opt, const QVariant &value); 80 76 81 bool isNull() const; 77 82 void detach(); -
trunk/src/network/kernel/qauthenticator_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) … … 58 58 #include <qstring.h> 59 59 #include <qauthenticator.h> 60 #include <qvariant.h> 60 61 61 62 QT_BEGIN_NAMESPACE … … 63 64 class QHttpResponseHeader; 64 65 65 class Q AuthenticatorPrivate66 class Q_AUTOTEST_EXPORT QAuthenticatorPrivate 66 67 { 67 68 public: … … 71 72 QAtomicInt ref; 72 73 QString user; 74 QString extractedUser; 73 75 QString password; 74 Q Hash<QByteArray, QByteArray>options;76 QVariantHash options; 75 77 Method method; 76 78 QString realm; … … 91 93 // ntlm specific 92 94 QString workstation; 95 QString userDomain; 93 96 94 97 QByteArray calculateResponse(const QByteArray &method, const QByteArray &path); … … 103 106 void parseHttpResponse(const QHttpResponseHeader &, bool isProxy); 104 107 #endif 108 void parseHttpResponse(const QList<QPair<QByteArray, QByteArray> >&, bool isProxy); 105 109 106 110 }; -
trunk/src/network/kernel/qhostaddress.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) … … 429 429 and QUdpSocket to connect to a host or to set up a server. 430 430 431 A host address is set with setAddress(), checked for its type432 using isIPv4Address() or isIPv6Address(), and retrieved with433 t oIPv4Address(), toIPv6Address(), or toString().431 A host address is set with setAddress(), and retrieved with 432 toIPv4Address(), toIPv6Address(), or toString(). You can check the 433 type with protocol(). 434 434 435 435 \note Please note that QHostAddress does not do DNS lookups. … … 680 680 2130706433 (i.e. 0x7f000001). 681 681 682 This value is only valid if isIp4Addr() returns true. 682 This value is only valid if the Protocol() is 683 \l{QAbstractSocket::}{IPv4Protocol}. 683 684 684 685 \sa toString() … … 705 706 \snippet doc/src/snippets/code/src_network_kernel_qhostaddress.cpp 0 706 707 707 This value is only valid if isIPv6Address() returns true. 708 This value is only valid if the protocol() is 709 \l{QAbstractSocket::}{IPv6Protocol}. 708 710 709 711 \sa toString() … … 1098 1100 to the stream. 1099 1101 1100 \sa { Format of the QDataStream operators}1102 \sa {Serializing Qt Data Types} 1101 1103 */ 1102 1104 QDataStream &operator<<(QDataStream &out, const QHostAddress &address) … … 1128 1130 reference to the stream. 1129 1131 1130 \sa { Format of the QDataStream operators}1132 \sa {Serializing Qt Data Types} 1131 1133 */ 1132 1134 QDataStream &operator>>(QDataStream &in, QHostAddress &address) -
trunk/src/network/kernel/qhostaddress.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/kernel/qhostaddress_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/kernel/qhostinfo.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) … … 169 169 QHostInfo hostInfo(id); 170 170 hostInfo.setError(QHostInfo::HostNotFound); 171 hostInfo.setErrorString(Q Object::tr("No host name given"));171 hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given")); 172 172 QScopedPointer<QHostInfoResult> result(new QHostInfoResult); 173 173 QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), … … 244 244 #endif 245 245 246 return QHostInfoAgent::fromName(name); 246 QHostInfo hostInfo = QHostInfoAgent::fromName(name); 247 QHostInfoLookupManager *manager = theHostInfoLookupManager(); 248 manager->cache.put(name, hostInfo); 249 return hostInfo; 247 250 } 248 251 … … 468 471 resultEmitter.emitResultsReady(hostInfo); 469 472 473 // now also iterate through the postponed ones 474 { 475 QMutexLocker locker(&manager->mutex); 476 QMutableListIterator<QHostInfoRunnable*> iterator(manager->postponedLookups); 477 while (iterator.hasNext()) { 478 QHostInfoRunnable* postponed = iterator.next(); 479 if (toBeLookedUp == postponed->toBeLookedUp) { 480 // we can now emit 481 iterator.remove(); 482 hostInfo.setLookupId(postponed->id); 483 postponed->resultEmitter.emitResultsReady(hostInfo); 484 } 485 } 486 } 487 470 488 manager->lookupFinished(this); 471 489 … … 485 503 486 504 // don't qDeleteAll currentLookups, the QThreadPool has ownership 487 qDeleteAll(postponedLookups); 488 qDeleteAll(scheduledLookups); 489 qDeleteAll(finishedLookups); 505 clear(); 506 } 507 508 void QHostInfoLookupManager::clear() 509 { 510 { 511 QMutexLocker locker(&mutex); 512 qDeleteAll(postponedLookups); 513 qDeleteAll(scheduledLookups); 514 qDeleteAll(finishedLookups); 515 postponedLookups.clear(); 516 scheduledLookups.clear(); 517 finishedLookups.clear(); 518 } 519 520 threadPool.waitForDone(); 521 cache.clear(); 490 522 } 491 523 … … 579 611 580 612 QMutexLocker locker(&this->mutex); 613 614 // is postponed? delete and return 615 for (int i = 0; i < postponedLookups.length(); i++) { 616 if (postponedLookups.at(i)->id == id) { 617 delete postponedLookups.takeAt(i); 618 return; 619 } 620 } 621 622 // is scheduled? delete and return 623 for (int i = 0; i < scheduledLookups.length(); i++) { 624 if (scheduledLookups.at(i)->id == id) { 625 delete scheduledLookups.takeAt(i); 626 return; 627 } 628 } 629 581 630 if (!abortedLookups.contains(id)) 582 631 abortedLookups.append(id); … … 605 654 } 606 655 607 // This function returns immediat ly when we had a result in the cache, else it will later emit a signal656 // This function returns immediately when we had a result in the cache, else it will later emit a signal 608 657 QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id) 609 658 { … … 631 680 QHostInfoLookupManager* manager = theHostInfoLookupManager(); 632 681 if (manager) { 633 manager->c ache.clear();682 manager->clear(); 634 683 } 635 684 } -
trunk/src/network/kernel/qhostinfo.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/kernel/qhostinfo_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) … … 85 85 86 86 Q_SIGNALS: 87 void resultsReady(const QHostInfo info);87 void resultsReady(const QHostInfo &info); 88 88 }; 89 89 … … 117 117 // Do NOT use them outside of QAbstractSocket. 118 118 QHostInfo Q_NETWORK_EXPORT qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id); 119 void Q_ NETWORK_EXPORT qt_qhostinfo_clear_cache();119 void Q_AUTOTEST_EXPORT qt_qhostinfo_clear_cache(); 120 120 void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e); 121 121 … … 162 162 ~QHostInfoLookupManager(); 163 163 164 void clear(); 164 165 void work(); 165 166 … … 173 174 174 175 QHostInfoCache cache; 176 177 friend class QHostInfoRunnable; 175 178 protected: 176 179 QList<QHostInfoRunnable*> currentLookups; // in progress -
trunk/src/network/kernel/qhostinfo_unix.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) … … 195 195 if (aceHostname.isEmpty()) { 196 196 results.setError(QHostInfo::HostNotFound); 197 results.setErrorString(hostName.isEmpty() ? QObject::tr("No host name given") : QObject::tr("Invalid hostname")); 197 results.setErrorString(hostName.isEmpty() ? 198 QCoreApplication::translate("QHostInfoAgent", "No host name given") : 199 QCoreApplication::translate("QHostInfoAgent", "Invalid hostname")); 198 200 return results; 199 201 } … … 209 211 hints.ai_flags = Q_ADDRCONFIG; 210 212 #endif 213 #ifdef Q_OS_SYMBIAN 214 # ifdef QHOSTINFO_DEBUG 215 qDebug() << "Setting flags: 'hints.ai_flags &= AI_V4MAPPED | AI_ALL'"; 216 # endif 217 #endif 211 218 212 219 int result = getaddrinfo(aceHostname.constData(), 0, &hints, &res); … … 215 222 // if the lookup failed with AI_ADDRCONFIG set, try again without it 216 223 hints.ai_flags = 0; 224 #ifdef Q_OS_SYMBIAN 225 # ifdef QHOSTINFO_DEBUG 226 qDebug() << "Setting flags: 'hints.ai_flags &= AI_V4MAPPED | AI_ALL'"; 227 # endif 228 hints.ai_flags &= AI_V4MAPPED | AI_ALL; 229 #endif 217 230 result = getaddrinfo(aceHostname.constData(), 0, &hints, &res); 218 231 } … … 223 236 QList<QHostAddress> addresses; 224 237 while (node) { 238 #ifdef QHOSTINFO_DEBUG 239 qDebug() << "getaddrinfo node: flags:" << node->ai_flags << "family:" << node->ai_family << "ai_socktype:" << node->ai_socktype << "ai_protocol:" << node->ai_protocol << "ai_addrlen:" << node->ai_addrlen; 240 #endif 225 241 if (node->ai_family == AF_INET) { 226 242 QHostAddress addr; … … 232 248 else if (node->ai_family == AF_INET6) { 233 249 QHostAddress addr; 234 addr.setAddress(((sockaddr_in6 *) node->ai_addr)->sin6_addr.s6_addr); 250 sockaddr_in6 *sa6 = (sockaddr_in6 *) node->ai_addr; 251 addr.setAddress(sa6->sin6_addr.s6_addr); 252 if (sa6->sin6_scope_id) 253 addr.setScopeId(QString::number(sa6->sin6_scope_id)); 235 254 if (!addresses.contains(addr)) 236 255 addresses.append(addr); -
trunk/src/network/kernel/qhostinfo_win.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) … … 50 50 #include "private/qnativesocketengine_p.h" 51 51 #include <ws2tcpip.h> 52 #include < qlibrary.h>52 #include <private/qsystemlibrary_p.h> 53 53 #include <qmutex.h> 54 54 #include <qurl.h> … … 91 91 // back to gethostbyname(), which has no IPv6 support. 92 92 #if !defined(Q_OS_WINCE) 93 local_getaddrinfo = (getaddrinfoProto) Q Library::resolve(QLatin1String("ws2_32.dll"), "getaddrinfo");94 local_freeaddrinfo = (freeaddrinfoProto) Q Library::resolve(QLatin1String("ws2_32.dll"), "freeaddrinfo");95 local_getnameinfo = (getnameinfoProto) Q Library::resolve(QLatin1String("ws2_32.dll"), "getnameinfo");93 local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo"); 94 local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); 95 local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); 96 96 #else 97 local_getaddrinfo = (getaddrinfoProto) Q Library::resolve(QLatin1String("ws2.dll"), "getaddrinfo");98 local_freeaddrinfo = (freeaddrinfoProto) Q Library::resolve(QLatin1String("ws2.dll"), "freeaddrinfo");99 local_getnameinfo = (getnameinfoProto) Q Library::resolve(QLatin1String("ws2.dll"), "getnameinfo");97 local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getaddrinfo"); 98 local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "freeaddrinfo"); 99 local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getnameinfo"); 100 100 #endif 101 101 } -
trunk/src/network/kernel/qnetworkinterface.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) -
trunk/src/network/kernel/qnetworkinterface.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/kernel/qnetworkinterface_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/kernel/qnetworkinterface_symbian.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/kernel/qnetworkinterface_unix.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/kernel/qnetworkinterface_win.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) … … 49 49 #include <qhash.h> 50 50 #include <qurl.h> 51 #include <private/qsystemlibrary_p.h> 51 52 52 53 QT_BEGIN_NAMESPACE … … 67 68 done = true; 68 69 69 HINSTANCE iphlpapiHnd = LoadLibrary(L"iphlpapi");70 HINSTANCE iphlpapiHnd = QSystemLibrary::load(L"iphlpapi"); 70 71 if (iphlpapiHnd == NULL) 71 72 return; -
trunk/src/network/kernel/qnetworkinterface_win_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/kernel/qnetworkproxy.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) … … 427 427 : d(0) 428 428 { 429 globalNetworkProxy()->init(); 429 if (QGlobalNetworkProxy *globalProxy = globalNetworkProxy()) 430 globalProxy->init(); 430 431 } 431 432 … … 442 443 : d(new QNetworkProxyPrivate(type, hostName, port, user, password)) 443 444 { 444 globalNetworkProxy()->init(); 445 if (QGlobalNetworkProxy *globalProxy = globalNetworkProxy()) 446 globalProxy->init(); 445 447 } 446 448 … … 1139 1141 such object, the factory will be queried for sockets created by 1140 1142 that framework only. 1143 1144 \section1 System Proxies 1145 1146 You can configure a factory to use the system proxy's settings. 1147 Call the setUseSystemConfiguration() function with true to enable 1148 this behavior, or false to disable it. 1149 1150 Similarly, you can use a factory to make queries directly to the 1151 system proxy by calling its systemProxyForQuery() function. 1152 1153 \warning Depending on the configuration of the user's system, the 1154 use of system proxy features on certain platforms may be subject 1155 to limitations. The systemProxyForQuery() documentation contains a 1156 list of these limitations for those platforms that are affected. 1141 1157 */ 1142 1158 … … 1160 1176 1161 1177 /*! 1178 \since 4.6 1179 1162 1180 Enables the use of the platform-specific proxy settings, and only those. 1163 1181 See systemProxyForQuery() for more information. … … 1165 1183 Internally, this method (when called with \a enable set to true) 1166 1184 sets an application-wide proxy factory. For this reason, this method 1167 is mutually exclusive with setApplicationProxyFactory : calling1168 setApplicationProxyFactory overrides the use of the system-wide proxy,1169 and calling setUseSystemConfiguration overrides any1185 is mutually exclusive with setApplicationProxyFactory(): calling 1186 setApplicationProxyFactory() overrides the use of the system-wide proxy, 1187 and calling setUseSystemConfiguration() overrides any 1170 1188 application proxy or proxy factory that was previously set. 1171 1189 1172 \since 4.6 1190 \note See the systemProxyForQuery() documentation for a list of 1191 limitations related to the use of system proxies. 1173 1192 */ 1174 1193 void QNetworkProxyFactory::setUseSystemConfiguration(bool enable) … … 1265 1284 listed here. 1266 1285 1267 On MacOS X, this function will ignore the Proxy Auto Configuration 1286 \list 1287 \o On MacOS X, this function will ignore the Proxy Auto Configuration 1268 1288 settings, since it cannot execute the associated ECMAScript code. 1289 1290 \o On Windows platforms, this function may take several seconds to 1291 execute depending on the configuration of the user's system. 1292 \endlist 1269 1293 */ 1270 1294 -
trunk/src/network/kernel/qnetworkproxy.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/kernel/qnetworkproxy_generic.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/kernel/qnetworkproxy_mac.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) … … 158 158 } 159 159 160 if (isHostExcluded(dict, query.peerHostName())) 160 if (isHostExcluded(dict, query.peerHostName())) { 161 CFRelease(dict); 161 162 return result; // no proxy for this host 163 } 162 164 163 165 // is there a PAC enabled? If so, use it first. … … 223 225 } 224 226 227 CFRelease(dict); 225 228 return result; 226 229 } -
trunk/src/network/kernel/qnetworkproxy_win.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) … … 52 52 #include <qt_windows.h> 53 53 #include <wininet.h> 54 #include <private/qsystemlibrary_p.h> 54 55 55 56 /* … … 100 101 #define WINHTTP_NO_PROXY_NAME NULL 101 102 #define WINHTTP_NO_PROXY_BYPASS NULL 103 104 #define WINHTTP_ERROR_BASE 12000 105 #define ERROR_WINHTTP_LOGIN_FAILURE (WINHTTP_ERROR_BASE + 15) 106 #define ERROR_WINHTTP_AUTODETECTION_FAILED (WINHTTP_ERROR_BASE + 180) 102 107 103 108 QT_BEGIN_NAMESPACE … … 274 279 #else 275 280 // load the winhttp.dll library 276 HINSTANCE winhttpHnd = LoadLibrary(L"winhttp");277 if (! winhttpHnd)281 QSystemLibrary lib(L"winhttp"); 282 if (!lib.load()) 278 283 return; // failed to load 279 284 280 ptrWinHttpOpen = (PtrWinHttpOpen) GetProcAddress(winhttpHnd,"WinHttpOpen");281 ptrWinHttpCloseHandle = (PtrWinHttpCloseHandle) GetProcAddress(winhttpHnd,"WinHttpCloseHandle");282 ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl) GetProcAddress(winhttpHnd,"WinHttpGetProxyForUrl");283 ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration) GetProcAddress(winhttpHnd,"WinHttpGetDefaultProxyConfiguration");284 ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser) GetProcAddress(winhttpHnd,"WinHttpGetIEProxyConfigForCurrentUser");285 ptrWinHttpOpen = (PtrWinHttpOpen)lib.resolve("WinHttpOpen"); 286 ptrWinHttpCloseHandle = (PtrWinHttpCloseHandle)lib.resolve("WinHttpCloseHandle"); 287 ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)lib.resolve("WinHttpGetProxyForUrl"); 288 ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)lib.resolve("WinHttpGetDefaultProxyConfiguration"); 289 ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)lib.resolve("WinHttpGetIEProxyConfigForCurrentUser"); 285 290 286 291 // Try to obtain the Internet Explorer configuration. … … 321 326 isAutoConfig = true; 322 327 memset(&autoProxyOptions, 0, sizeof autoProxyOptions); 323 autoProxyOptions.fAutoLogonIfChallenged = true;328 autoProxyOptions.fAutoLogonIfChallenged = false; 324 329 if (ieProxyConfig.fAutoDetect) { 325 330 autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; … … 378 383 url.setScheme(QLatin1String("https")); 379 384 } 380 if (ptrWinHttpGetProxyForUrl(sp->hHttpSession, 381 (LPCWSTR)url.toString().utf16(), 382 &sp->autoProxyOptions, 383 &proxyInfo)) { 385 386 bool getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession, 387 (LPCWSTR)url.toString().utf16(), 388 &sp->autoProxyOptions, 389 &proxyInfo); 390 DWORD getProxyError = GetLastError(); 391 392 if (!getProxySucceeded 393 && (ERROR_WINHTTP_LOGIN_FAILURE == getProxyError)) { 394 // We first tried without AutoLogon, because this might prevent caching the result. 395 // But now we've to enable it (http://msdn.microsoft.com/en-us/library/aa383153%28v=VS.85%29.aspx) 396 sp->autoProxyOptions.fAutoLogonIfChallenged = TRUE; 397 getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession, 398 (LPCWSTR)url.toString().utf16(), 399 &sp->autoProxyOptions, 400 &proxyInfo); 401 getProxyError = GetLastError(); 402 } 403 404 if (getProxySucceeded) { 384 405 // yes, we got a config for this URL 385 406 QString proxyBypass = QString::fromWCharArray(proxyInfo.lpszProxyBypass); … … 396 417 397 418 // GetProxyForUrl failed 419 420 if (ERROR_WINHTTP_AUTODETECTION_FAILED == getProxyError) { 421 //No config file could be retrieved on the network. 422 //Don't search for it next time again. 423 sp->isAutoConfig = false; 424 } 425 398 426 return sp->defaultResult; 399 427 } -
trunk/src/network/kernel/qurlinfo.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/kernel/qurlinfo.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/network.pro
r561 r846 21 21 include(../qbase.pri) 22 22 include(access/access.pri) 23 include(bearer/bearer.pri) 23 24 include(kernel/kernel.pri) 24 25 include(socket/socket.pri) … … 30 31 symbian { 31 32 TARGET.UID3=0x2001B2DE 32 LIBS += -lesock -linsock 33 LIBS += -lesock -linsock -lcertstore -lefsrv -lctframework 33 34 } -
trunk/src/network/socket/qabstractsocket.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) … … 366 366 367 367 #include <qabstracteventdispatcher.h> 368 #include <qdatetime.h>369 368 #include <qhostaddress.h> 370 369 #include <qhostinfo.h> … … 372 371 #include <qpointer.h> 373 372 #include <qtimer.h> 373 #include <qelapsedtimer.h> 374 374 375 375 #ifndef QT_NO_OPENSSL … … 1213 1213 } 1214 1214 1215 1216 void QAbstractSocketPrivate::pauseSocketNotifiers(QAbstractSocket *socket) 1217 { 1218 QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine; 1219 if (!socketEngine) 1220 return; 1221 socket->d_func()->prePauseReadSocketNotifierState = socketEngine->isReadNotificationEnabled(); 1222 socket->d_func()->prePauseWriteSocketNotifierState = socketEngine->isWriteNotificationEnabled(); 1223 socket->d_func()->prePauseExceptionSocketNotifierState = socketEngine->isExceptionNotificationEnabled(); 1224 socketEngine->setReadNotificationEnabled(false); 1225 socketEngine->setWriteNotificationEnabled(false); 1226 socketEngine->setExceptionNotificationEnabled(false); 1227 } 1228 1229 void QAbstractSocketPrivate::resumeSocketNotifiers(QAbstractSocket *socket) 1230 { 1231 QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine; 1232 if (!socketEngine) 1233 return; 1234 socketEngine->setReadNotificationEnabled(socket->d_func()->prePauseReadSocketNotifierState); 1235 socketEngine->setWriteNotificationEnabled(socket->d_func()->prePauseWriteSocketNotifierState); 1236 socketEngine->setExceptionNotificationEnabled(socket->d_func()->prePauseExceptionSocketNotifierState); 1237 } 1238 1239 QAbstractSocketEngine* QAbstractSocketPrivate::getSocketEngine(QAbstractSocket *socket) 1240 { 1241 return socket->d_func()->socketEngine; 1242 } 1243 1244 1215 1245 /*! \internal 1216 1246 … … 1381 1411 } else { 1382 1412 if (d->threadData->eventDispatcher) { 1383 // this internal API for QHostInfo either immediat ly gives us the desired1413 // this internal API for QHostInfo either immediately gives us the desired 1384 1414 // QHostInfo from cache or later calls the _q_startConnecting slot. 1385 1415 bool immediateResultValid = false; … … 1739 1769 bool wasPendingClose = d->pendingClose; 1740 1770 d->pendingClose = false; 1741 Q TimestopWatch;1771 QElapsedTimer stopWatch; 1742 1772 stopWatch.start(); 1743 1773 … … 1820 1850 } 1821 1851 1822 Q TimestopWatch;1852 QElapsedTimer stopWatch; 1823 1853 stopWatch.start(); 1824 1854 … … 1879 1909 return false; 1880 1910 1881 Q TimestopWatch;1911 QElapsedTimer stopWatch; 1882 1912 stopWatch.start(); 1883 1913 … … 1961 1991 } 1962 1992 1963 Q TimestopWatch;1993 QElapsedTimer stopWatch; 1964 1994 stopWatch.start(); 1965 1995 -
trunk/src/network/socket/qabstractsocket.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/socket/qabstractsocket_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) … … 159 159 160 160 QAbstractSocket::SocketError socketError; 161 162 bool prePauseReadSocketNotifierState; 163 bool prePauseWriteSocketNotifierState; 164 bool prePauseExceptionSocketNotifierState; 165 static void pauseSocketNotifiers(QAbstractSocket*); 166 static void resumeSocketNotifiers(QAbstractSocket*); 167 static QAbstractSocketEngine* getSocketEngine(QAbstractSocket*); 161 168 }; 162 169 -
trunk/src/network/socket/qabstractsocketengine.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/socket/qabstractsocketengine_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/socket/qhttpsocketengine.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) … … 43 43 #include "qtcpsocket.h" 44 44 #include "qhostaddress.h" 45 #include "qdatetime.h"46 45 #include "qurl.h" 47 46 #include "qhttp.h" 47 #include "qelapsedtimer.h" 48 48 49 49 #if !defined(QT_NO_NETWORKPROXY) && !defined(QT_NO_HTTP) … … 320 320 return false; 321 321 322 Q TimestopWatch;322 QElapsedTimer stopWatch; 323 323 stopWatch.start(); 324 324 … … 367 367 } 368 368 369 Q TimestopWatch;369 QElapsedTimer stopWatch; 370 370 stopWatch.start(); 371 371 -
trunk/src/network/socket/qhttpsocketengine_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/socket/qlocalserver.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) -
trunk/src/network/socket/qlocalserver.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/socket/qlocalserver_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) … … 100 100 HANDLE handle; 101 101 OVERLAPPED overlapped; 102 bool connected; 102 103 }; 103 104 -
trunk/src/network/socket/qlocalserver_tcp.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/socket/qlocalserver_unix.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) … … 120 120 // 121 121 // This change can be removed once more generic fix to select thread 122 // sync ronization problem is implemented.122 // synchronization problem is implemented. 123 123 int flags = fcntl(listenSocket, F_GETFL, 0); 124 124 if (-1 == flags -
trunk/src/network/socket/qlocalserver_win.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) … … 66 66 (const wchar_t *)fullServerName.utf16(), // pipe name 67 67 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access 68 PIPE_TYPE_ MESSAGE | // message type pipe69 PIPE_READMODE_ MESSAGE | // message-read mode68 PIPE_TYPE_BYTE | // byte type pipe 69 PIPE_READMODE_BYTE | // byte-read mode 70 70 PIPE_WAIT, // blocking mode 71 71 PIPE_UNLIMITED_INSTANCES, // max. instances … … 86 86 switch (GetLastError()) { 87 87 case ERROR_IO_PENDING: 88 listener.connected = false; 88 89 break; 89 90 case ERROR_PIPE_CONNECTED: 91 listener.connected = true; 90 92 SetEvent(eventHandle); 91 93 break; … … 156 158 for (int i = 0; i < listeners.size(); ) { 157 159 HANDLE handle = listeners[i].handle; 158 if (GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) { 160 if (listeners[i].connected 161 || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) 162 { 159 163 listeners.removeAt(i); 160 164 -
trunk/src/network/socket/qlocalsocket.cpp
r755 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/socket/qlocalsocket.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/socket/qlocalsocket_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) … … 136 136 void _q_pipeClosed(); 137 137 void _q_emitReadyRead(); 138 DWORD bytesAvailable();138 DWORD checkPipeState(); 139 139 void startAsyncRead(); 140 140 bool completeAsyncRead(); -
trunk/src/network/socket/qlocalsocket_tcp.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) -
trunk/src/network/socket/qlocalsocket_unix.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) … … 53 53 #include <errno.h> 54 54 55 #include <qdatetime.h>56 55 #include <qdir.h> 57 56 #include <qdebug.h> 57 #include <qelapsedtimer.h> 58 58 59 59 #ifdef Q_OS_VXWORKS … … 535 535 int result = -1; 536 536 // on Linux timeout will be updated by select, but _not_ on other systems. 537 Q Timetimer;537 QElapsedTimer timer; 538 538 timer.start(); 539 539 while (state() == ConnectingState -
trunk/src/network/socket/qlocalsocket_win.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) … … 193 193 Q_D(QLocalSocket); 194 194 195 if (d->pipeClosed && d->actualReadBufferSize == 0) 196 return -1; // signal EOF 197 195 198 qint64 readSoFar; 196 199 // If startAsyncRead() read data, copy it to its destination. … … 214 217 215 218 if (d->pipeClosed) { 216 if ( readSoFar == 0) {219 if (d->actualReadBufferSize == 0) 217 220 QTimer::singleShot(0, this, SLOT(_q_pipeClosed())); 218 return -1; // signal EOF219 }220 221 } else { 221 222 if (!d->readSequenceStarted) … … 251 252 { 252 253 do { 253 DWORD bytesToRead = bytesAvailable(); 254 DWORD bytesToRead = checkPipeState(); 255 if (pipeClosed) 256 return; 257 254 258 if (bytesToRead == 0) { 255 259 // There are no bytes in the pipe but we need to … … 277 281 // This is not an error. We're getting notified, when data arrives. 278 282 return; 283 case ERROR_MORE_DATA: 284 // This is not an error. The synchronous read succeeded. 285 // We're connected to a message mode pipe and the message 286 // didn't fit into the pipe's system buffer. 287 completeAsyncRead(); 288 break; 279 289 case ERROR_PIPE_NOT_CONNECTED: 280 290 { … … 297 307 \internal 298 308 Sets the correct size of the read buffer after a read operation. 299 Returns false, if an error occur ed or the connection dropped.309 Returns false, if an error occurred or the connection dropped. 300 310 */ 301 311 bool QLocalSocketPrivate::completeAsyncRead() … … 306 316 DWORD bytesRead; 307 317 if (!GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) { 308 if (GetLastError() != ERROR_PIPE_NOT_CONNECTED) 318 switch (GetLastError()) { 319 case ERROR_MORE_DATA: 320 // This is not an error. We're connected to a message mode 321 // pipe and the message didn't fit into the pipe's system 322 // buffer. We will read the remaining data in the next call. 323 break; 324 case ERROR_PIPE_NOT_CONNECTED: 325 return false; 326 default: 309 327 setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); 310 return false; 328 return false; 329 } 311 330 } 312 331 … … 334 353 335 354 /*! 336 The number of bytes available from the pipe 337 */ 338 DWORD QLocalSocketPrivate::bytesAvailable() 355 \internal 356 Returns the number of available bytes in the pipe. 357 Sets QLocalSocketPrivate::pipeClosed to true if the connection is broken. 358 */ 359 DWORD QLocalSocketPrivate::checkPipeState() 339 360 { 340 361 Q_Q(QLocalSocket); … … 346 367 pipeClosed = true; 347 368 emit q->readChannelFinished(); 348 QTimer::singleShot(0, q, SLOT(_q_pipeClosed())); 369 if (actualReadBufferSize == 0) 370 QTimer::singleShot(0, q, SLOT(_q_pipeClosed())); 349 371 } 350 372 } … … 479 501 pipeClosed = true; 480 502 emit q->readChannelFinished(); 503 if (actualReadBufferSize == 0) 504 QTimer::singleShot(0, q, SLOT(_q_pipeClosed())); 481 505 return; 482 506 } … … 530 554 QIncrementalSleepTimer timer(msecs); 531 555 forever { 532 d-> bytesAvailable(); // to check if PeekNamedPipe fails556 d->checkPipeState(); 533 557 if (d->pipeClosed) 534 558 close(); … … 562 586 return false; 563 587 588 // We already know that the pipe is gone, but did not enter the event loop yet. 589 if (d->pipeClosed) { 590 close(); 591 return false; 592 } 593 564 594 Q_ASSERT(d->readSequenceStarted); 565 595 DWORD result = WaitForSingleObject(d->overlapped.hEvent, msecs == -1 ? INFINITE : msecs); … … 567 597 case WAIT_OBJECT_0: 568 598 d->_q_notified(); 599 // We just noticed that the pipe is gone. 600 if (d->pipeClosed) { 601 close(); 602 return false; 603 } 569 604 return true; 570 605 case WAIT_TIMEOUT: -
trunk/src/network/socket/qnativesocketengine.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) … … 186 186 // one exception: SocketError(11) bypasses this as it's purely 187 187 // a temporary internal error condition. 188 // Another exception is the way the waitFor*() functions set 189 // an error when a timeout occurs. After the call to setError() 190 // they reset the hasSetSocketError to false 188 191 return; 189 192 } … … 860 863 d->setError(QAbstractSocket::SocketTimeoutError, 861 864 QNativeSocketEnginePrivate::TimeOutErrorString); 865 d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions 862 866 return false; 863 867 } else if (state() == QAbstractSocket::ConnectingState) { … … 928 932 d->setError(QAbstractSocket::SocketTimeoutError, 929 933 QNativeSocketEnginePrivate::TimeOutErrorString); 934 d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions 930 935 return false; 931 936 } else if (state() == QAbstractSocket::ConnectingState) { … … 979 984 d->setError(QAbstractSocket::SocketTimeoutError, 980 985 QNativeSocketEnginePrivate::TimeOutErrorString); 986 d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions 981 987 return false; 982 988 } else if (state() == QAbstractSocket::ConnectingState) { -
trunk/src/network/socket/qnativesocketengine_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/socket/qnativesocketengine_unix.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) … … 45 45 #include "qiodevice.h" 46 46 #include "qhostaddress.h" 47 #include "qelapsedtimer.h" 47 48 #include "qvarlengtharray.h" 48 #include "qdatetime.h"49 49 #include <time.h> 50 50 #include <errno.h> … … 203 203 } 204 204 205 // Ensure that the socket is closed on exec*().206 ::fcntl(socket, F_SETFD, FD_CLOEXEC);207 208 205 socketDescriptor = socket; 209 206 return true; … … 353 350 sockAddrIPv6.sin6_family = AF_INET6; 354 351 sockAddrIPv6.sin6_port = htons(port); 352 353 QString scopeid = addr.scopeId(); 354 bool ok; 355 sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); 355 356 #ifndef QT_NO_IPV6IFNAME 356 sockAddrIPv6.sin6_scope_id = ::if_nametoindex(addr.scopeId().toLatin1().data()); 357 #else 358 sockAddrIPv6.sin6_scope_id = addr.scopeId().toInt(); 357 if (!ok) 358 sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); 359 359 #endif 360 360 Q_IPV6ADDR ip6 = addr.toIPv6Address(); … … 426 426 case EFAULT: 427 427 case ENOTSOCK: 428 #ifdef Q_OS_SYMBIAN 429 case EPIPE: 430 #endif 428 431 socketState = QAbstractSocket::UnconnectedState; 429 432 default: … … 559 562 #else 560 563 int acceptedDescriptor = qt_safe_accept(socketDescriptor, 0, 0); 561 #endif562 //check if we have vaild descriptor at all563 if(acceptedDescriptor > 0) {564 // Ensure that the socket is closed on exec*()565 ::fcntl(acceptedDescriptor, F_SETFD, FD_CLOEXEC);566 }567 #ifdef Q_OS_SYMBIAN568 else {569 qWarning("QNativeSocketEnginePrivate::nativeAccept() - acceptedDescriptor <= 0");570 }571 564 #endif 572 565 … … 1009 1002 ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); 1010 1003 #else 1011 Q Timetimer;1004 QElapsedTimer timer; 1012 1005 timer.start(); 1013 1006 -
trunk/src/network/socket/qnativesocketengine_win.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) … … 208 208 memset(sockAddrIPv6, 0, sizeof(qt_sockaddr_in6)); 209 209 sockAddrIPv6->sin6_family = AF_INET6; 210 sockAddrIPv6->sin6_scope_id = address.scopeId().toInt(); 210 211 WSAHtons(socketDescriptor, port, &(sockAddrIPv6->sin6_port)); 211 212 Q_IPV6ADDR tmp = address.toIPv6Address(); … … 733 734 int acceptedDescriptor = WSAAccept(socketDescriptor, 0,0,0,0); 734 735 if (acceptedDescriptor != -1 && QAbstractEventDispatcher::instance()) { 735 // Bec uase of WSAAsyncSelect() WSAAccept returns a non blocking socket736 // Because of WSAAsyncSelect() WSAAccept returns a non blocking socket 736 737 // with the same attributes as the listening socket including the current 737 738 // WSAAsyncSelect(). To be able to change the socket to blocking mode the -
trunk/src/network/socket/qnet_unix_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/socket/qsocks5socketengine.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 #include "qhash.h" 51 51 #include "qqueue.h" 52 #include "q datetime.h"52 #include "qelapsedtimer.h" 53 53 #include "qmutex.h" 54 54 #include "qthread.h" … … 309 309 QHostAddress peerAddress; 310 310 quint16 peerPort; 311 Q DateTimetimeStamp;311 QElapsedTimer timeStamp; 312 312 }; 313 313 … … 370 370 // qDebug() << "delete it"; 371 371 } 372 bindData->timeStamp = QDateTime::currentDateTime();372 bindData->timeStamp.start(); 373 373 store.insert(socketDescriptor, bindData); 374 374 // start sweep timer if not started … … 413 413 while (it.hasNext()) { 414 414 it.next(); 415 if (it.value()->timeStamp. secsTo(QDateTime::currentDateTime()) > 350) {415 if (it.value()->timeStamp.hasExpired(350000)) { 416 416 QSOCKS5_DEBUG << "QSocks5BindStore removing JJJJ"; 417 417 it.remove(); … … 1356 1356 1357 1357 int msecs = SOCKS5_BLOCKING_BIND_TIMEOUT; 1358 Q TimestopWatch;1358 QElapsedTimer stopWatch; 1359 1359 stopWatch.start(); 1360 1360 d->data->controlSocket->connectToHost(d->proxyInfo.hostName(), d->proxyInfo.port()); … … 1456 1456 if (d->data->controlSocket->state() == QAbstractSocket::ConnectedState) { 1457 1457 int msecs = 100; 1458 Q TimestopWatch;1458 QElapsedTimer stopWatch; 1459 1459 stopWatch.start(); 1460 1460 while (!d->data->controlSocket->bytesToWrite()) { … … 1675 1675 UdpAssociateSuccess; 1676 1676 1677 Q TimestopWatch;1677 QElapsedTimer stopWatch; 1678 1678 stopWatch.start(); 1679 1679 … … 1700 1700 d->readNotificationActivated = false; 1701 1701 1702 Q TimestopWatch;1702 QElapsedTimer stopWatch; 1703 1703 stopWatch.start(); 1704 1704 … … 1750 1750 QSOCKS5_DEBUG << "waitForWrite" << msecs; 1751 1751 1752 Q TimestopWatch;1752 QElapsedTimer stopWatch; 1753 1753 stopWatch.start(); 1754 1754 -
trunk/src/network/socket/qsocks5socketengine_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/socket/qtcpserver.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) … … 563 563 use its setSocketDescriptor() method. 564 564 565 \sa newConnection(), nextPendingConnection() 565 \sa newConnection(), nextPendingConnection(), addPendingConnection() 566 566 */ 567 567 void QTcpServer::incomingConnection(int socketDescriptor) … … 573 573 QTcpSocket *socket = new QTcpSocket(this); 574 574 socket->setSocketDescriptor(socketDescriptor); 575 addPendingConnection(socket); 576 } 577 578 /*! 579 This function is called by QTcpServer::incomingConnection() 580 to add the \a socket to the list of pending incoming connections. 581 582 \note Don't forget to call this member from reimplemented 583 incomingConnection() if you do not want to break the 584 Pending Connections mechanism. 585 586 \sa incomingConnection() 587 \since 4.7 588 */ 589 void QTcpServer::addPendingConnection(QTcpSocket* socket) 590 { 575 591 d_func()->pendingConnections.append(socket); 576 592 } -
trunk/src/network/socket/qtcpserver.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) … … 94 94 protected: 95 95 virtual void incomingConnection(int handle); 96 void addPendingConnection(QTcpSocket* socket); 96 97 97 98 Q_SIGNALS: -
trunk/src/network/socket/qtcpsocket.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) -
trunk/src/network/socket/qtcpsocket.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/socket/qtcpsocket_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/socket/qudpsocket.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) -
trunk/src/network/socket/qudpsocket.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/ssl/qssl.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/ssl/qssl.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/ssl/qsslcertificate.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) … … 260 260 /*! 261 261 Returns the certificate's serial number string in decimal format. 262 In case the serial number cannot be converted to decimal format 263 (i.e. if it is bigger than 4294967295, which means it does not fit into 4 bytes), 264 its hexadecimal version is returned. 262 265 */ 263 266 QByteArray QSslCertificate::serialNumber() const 264 267 { 265 if (d->serialNumberString.isEmpty() && d->x509) 266 d->serialNumberString = 267 QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->serialNumber))); 268 268 if (d->serialNumberString.isEmpty() && d->x509) { 269 ASN1_INTEGER *serialNumber = d->x509->cert_info->serialNumber; 270 // if we cannot convert to a long, just output the hexadecimal number 271 if (serialNumber->length > 4) { 272 QByteArray hexString; 273 hexString.reserve(serialNumber->length * 3); 274 for (int a = 0; a < serialNumber->length; ++a) { 275 hexString += QByteArray::number(serialNumber->data[a], 16).rightJustified(2, '0'); 276 hexString += ':'; 277 } 278 hexString.chop(1); 279 d->serialNumberString = hexString; 280 } else { 281 d->serialNumberString = QByteArray::number(qlonglong(q_ASN1_INTEGER_get(serialNumber))); 282 } 283 } 269 284 return d->serialNumberString; 270 285 } … … 534 549 int startIndex = 0; 535 550 if (pathPrefix.trimmed().isEmpty()) { 536 startIndex = 2; 537 pathPrefix = QLatin1String("."); 551 if(path.startsWith(QLatin1Char('/'))) { 552 pathPrefix = path.left(path.indexOf(QRegExp(QLatin1String("[\\*\\?\\[]")))); 553 pathPrefix = path.left(path.lastIndexOf(QLatin1Char('/'))); 554 } else { 555 startIndex = 2; 556 pathPrefix = QLatin1String("."); 557 } 538 558 } 539 559 … … 697 717 static bool matchLineFeed(const QByteArray &pem, int *offset) 698 718 { 699 char ch ;719 char ch = 0; 700 720 701 721 // ignore extra whitespace at the end of the line -
trunk/src/network/ssl/qsslcertificate.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/ssl/qsslcertificate_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/ssl/qsslcipher.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/ssl/qsslcipher.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/ssl/qsslcipher_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/ssl/qsslconfiguration.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) … … 486 486 Returns this connection's CA certificate database. The CA certificate 487 487 database is used by the socket during the handshake phase to 488 validate the peer's certificate. It can be moodified prior to the 489 handshake with addCaCertificate(), addCaCertificates(), and 490 setCaCertificates(). 488 validate the peer's certificate. It can be modified prior to the 489 handshake with setCaCertificates(), or with \l{QSslSocket}'s 490 \l{QSslSocket::}{addCaCertificate()} and 491 \l{QSslSocket::}{addCaCertificates()}. 491 492 492 493 \sa setCaCertificates() -
trunk/src/network/ssl/qsslconfiguration.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/ssl/qsslconfiguration_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/ssl/qsslerror.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/ssl/qsslerror.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/ssl/qsslkey.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) -
trunk/src/network/ssl/qsslkey.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/ssl/qsslkey_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/ssl/qsslsocket.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) … … 211 211 signal. This mode is the default for clients. 212 212 213 \value AutoVerifyPeer QSslSocket will automatical y use QueryPeer for213 \value AutoVerifyPeer QSslSocket will automatically use QueryPeer for 214 214 server sockets and VerifyPeer for client sockets. 215 215 … … 297 297 #include <QtCore/qdebug.h> 298 298 #include <QtCore/qdir.h> 299 #include <QtCore/qdatetime.h>300 299 #include <QtCore/qmutex.h> 300 #include <QtCore/qelapsedtimer.h> 301 301 #include <QtNetwork/qhostaddress.h> 302 302 #include <QtNetwork/qhostinfo.h> … … 575 575 576 576 The default mode is AutoVerifyPeer, which tells QSslSocket to use 577 VerifyPeer for clients , QueryPeer for clients.577 VerifyPeer for clients and QueryPeer for servers. 578 578 579 579 \sa setPeerVerifyMode(), peerVerifyDepth(), mode() … … 595 595 596 596 The default mode is AutoVerifyPeer, which tells QSslSocket to use 597 VerifyPeer for clients , QueryPeer for clients.597 VerifyPeer for clients and QueryPeer for servers. 598 598 599 599 Setting this mode after encryption has started has no effect on the … … 1330 1330 Returns the current default CA certificate database. This database 1331 1331 is originally set to your system's default CA certificate database. 1332 If no system default database is found, Qt will provide its own1333 default database. You can override the default CA certificate database1332 If no system default database is found, an empty database will be 1333 returned. You can override the default CA certificate database 1334 1334 with your own CA certificate database using setDefaultCaCertificates(). 1335 1335 … … 1345 1345 1346 1346 /*! 1347 This function provides a defaultCA certificate database1348 shipped together with Qt. The CA certificate database1347 This function provides the CA certificate database 1348 provided by the operating system. The CA certificate database 1349 1349 returned by this function is used to initialize the database 1350 1350 returned by defaultCaCertificates(). You can replace that database … … 1355 1355 QList<QSslCertificate> QSslSocket::systemCaCertificates() 1356 1356 { 1357 QSslSocketPrivate::ensureInitialized();1357 // we are calling ensureInitialized() in the method below 1358 1358 return QSslSocketPrivate::systemCaCertificates(); 1359 1359 } … … 1404 1404 return false; 1405 1405 1406 Q TimestopWatch;1406 QElapsedTimer stopWatch; 1407 1407 stopWatch.start(); 1408 1408 … … 1444 1444 d->readyReadEmittedPointer = &readyReadEmitted; 1445 1445 1446 Q TimestopWatch;1446 QElapsedTimer stopWatch; 1447 1447 stopWatch.start(); 1448 1448 … … 1481 1481 return d->plainSocket->waitForBytesWritten(msecs); 1482 1482 1483 Q TimestopWatch;1483 QElapsedTimer stopWatch; 1484 1484 stopWatch.start(); 1485 1485 … … 1519 1519 return d->plainSocket->waitForDisconnected(msecs); 1520 1520 1521 Q TimestopWatch;1521 QElapsedTimer stopWatch; 1522 1522 stopWatch.start(); 1523 1523 … … 1557 1557 bool QSslSocket::supportsSsl() 1558 1558 { 1559 return QSslSocketPrivate:: ensureInitialized();1559 return QSslSocketPrivate::supportsSsl(); 1560 1560 } 1561 1561 … … 1966 1966 QMutexLocker locker(&globalData()->mutex); 1967 1967 const QSslConfigurationPrivate *global = globalData()->config.constData(); 1968 1969 if (!global) { 1970 ptr = 0; 1971 return; 1972 } 1968 1973 1969 1974 ptr->ref = 1; … … 2031 2036 } 2032 2037 2038 void QSslSocketPrivate::pauseSocketNotifiers(QSslSocket *socket) 2039 { 2040 if (!socket->d_func()->plainSocket) 2041 return; 2042 QAbstractSocketPrivate::pauseSocketNotifiers(socket->d_func()->plainSocket); 2043 } 2044 2045 void QSslSocketPrivate::resumeSocketNotifiers(QSslSocket *socket) 2046 { 2047 if (!socket->d_func()->plainSocket) 2048 return; 2049 QAbstractSocketPrivate::resumeSocketNotifiers(socket->d_func()->plainSocket); 2050 } 2051 2033 2052 /*! 2034 2053 \internal -
trunk/src/network/ssl/qsslsocket.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/ssl/qsslsocket_openssl.cpp
r788 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) … … 52 52 #include <QtCore/qdir.h> 53 53 #include <QtCore/qdiriterator.h> 54 #include <QtCore/qelapsedtimer.h> 54 55 #include <QtCore/qfile.h> 55 56 #include <QtCore/qfileinfo.h> … … 58 59 #include <QtCore/qurl.h> 59 60 #include <QtCore/qvarlengtharray.h> 60 61 static void initNetworkResources() 62 { 63 // Initialize resources 64 Q_INIT_RESOURCE(network); 65 } 61 #include <QLibrary> // for loading the security lib for the CA store 66 62 67 63 QT_BEGIN_NAMESPACE 68 64 69 // Useful defines 70 #define SSL_ERRORSTR() QString::fromLocal8Bit(q_ERR_error_string(q_ERR_get_error(), NULL)) 65 #if defined(Q_OS_MAC) 66 #define kSecTrustSettingsDomainSystem 2 // so we do not need to include the header file 67 PtrSecCertificateGetData QSslSocketPrivate::ptrSecCertificateGetData = 0; 68 PtrSecTrustSettingsCopyCertificates QSslSocketPrivate::ptrSecTrustSettingsCopyCertificates = 0; 69 PtrSecTrustCopyAnchorCertificates QSslSocketPrivate::ptrSecTrustCopyAnchorCertificates = 0; 70 #elif defined(Q_OS_WIN) 71 PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = 0; 72 PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = 0; 73 PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = 0; 74 #elif defined(Q_OS_SYMBIAN) 75 #include <e32base.h> 76 #include <e32std.h> 77 #include <e32debug.h> 78 #include <QtCore/private/qcore_symbian_p.h> 79 #endif 80 81 bool QSslSocketPrivate::s_libraryLoaded = false; 82 bool QSslSocketPrivate::s_loadedCiphersAndCerts = false; 71 83 72 84 /* \internal … … 147 159 static unsigned long id_function() 148 160 { 149 return ( unsigned long)QThread::currentThreadId();161 return (quintptr)QThread::currentThreadId(); 150 162 } 151 163 } // extern "C" … … 154 166 : ssl(0), 155 167 ctx(0), 168 pkey(0), 156 169 readBio(0), 157 170 writeBio(0), … … 258 271 259 272 // ### Bad error code 260 q->setErrorString(QSslSocket::tr("Error creating SSL context (%1)").arg( SSL_ERRORSTR()));273 q->setErrorString(QSslSocket::tr("Error creating SSL context (%1)").arg(getErrorsFromOpenSsl())); 261 274 q->setSocketError(QAbstractSocket::UnknownSocketError); 262 275 emit q->error(QAbstractSocket::UnknownSocketError); … … 283 296 if (!q_SSL_CTX_set_cipher_list(ctx, cipherString.data())) { 284 297 // ### Bad error code 285 q->setErrorString(QSslSocket::tr("Invalid or empty cipher list (%1)").arg( SSL_ERRORSTR()));298 q->setErrorString(QSslSocket::tr("Invalid or empty cipher list (%1)").arg(getErrorsFromOpenSsl())); 286 299 q->setSocketError(QAbstractSocket::UnknownSocketError); 287 300 emit q->error(QAbstractSocket::UnknownSocketError); … … 290 303 291 304 // Add all our CAs to this store. 292 foreach (const QSslCertificate &caCertificate, q->caCertificates()) 305 QList<QSslCertificate> expiredCerts; 306 foreach (const QSslCertificate &caCertificate, q->caCertificates()) { 307 // add expired certs later, so that the 308 // valid ones are used before the expired ones 309 if (! caCertificate.isValid()) { 310 expiredCerts.append(caCertificate); 311 } else { 312 q_X509_STORE_add_cert(ctx->cert_store, (X509 *)caCertificate.handle()); 313 } 314 } 315 // now add the expired certs 316 foreach (const QSslCertificate &caCertificate, expiredCerts) { 293 317 q_X509_STORE_add_cert(ctx->cert_store, (X509 *)caCertificate.handle()); 318 } 294 319 295 320 // Register a custom callback to get all verification errors. … … 299 324 // Require a private key as well. 300 325 if (configuration.privateKey.isNull()) { 301 q->setErrorString(QSslSocket::tr("Cannot provide a certificate with no key, %1").arg( SSL_ERRORSTR()));326 q->setErrorString(QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(getErrorsFromOpenSsl())); 302 327 emit q->error(QAbstractSocket::UnknownSocketError); 303 328 return false; … … 306 331 // Load certificate 307 332 if (!q_SSL_CTX_use_certificate(ctx, (X509 *)configuration.localCertificate.handle())) { 308 q->setErrorString(QSslSocket::tr("Error loading local certificate, %1").arg( SSL_ERRORSTR()));333 q->setErrorString(QSslSocket::tr("Error loading local certificate, %1").arg(getErrorsFromOpenSsl())); 309 334 emit q->error(QAbstractSocket::UnknownSocketError); 310 335 return false; … … 312 337 313 338 // Load private key 314 EVP_PKEY *pkey = q_EVP_PKEY_new(); 339 pkey = q_EVP_PKEY_new(); 340 // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free. 341 // this lead to a memory leak. Now we use the *_set1_* functions which do not 342 // take ownership of the RSA/DSA key instance because the QSslKey already has ownership. 315 343 if (configuration.privateKey.algorithm() == QSsl::Rsa) 316 q_EVP_PKEY_ assign_RSA(pkey, (RSA *)configuration.privateKey.handle());344 q_EVP_PKEY_set1_RSA(pkey, (RSA *)configuration.privateKey.handle()); 317 345 else 318 q_EVP_PKEY_ assign_DSA(pkey, (DSA *)configuration.privateKey.handle());346 q_EVP_PKEY_set1_DSA(pkey, (DSA *)configuration.privateKey.handle()); 319 347 if (!q_SSL_CTX_use_PrivateKey(ctx, pkey)) { 320 q->setErrorString(QSslSocket::tr("Error loading private key, %1").arg( SSL_ERRORSTR()));348 q->setErrorString(QSslSocket::tr("Error loading private key, %1").arg(getErrorsFromOpenSsl())); 321 349 emit q->error(QAbstractSocket::UnknownSocketError); 322 350 return false; … … 325 353 // Check if the certificate matches the private key. 326 354 if (!q_SSL_CTX_check_private_key(ctx)) { 327 q->setErrorString(QSslSocket::tr("Private key does not certify public key, %1").arg( SSL_ERRORSTR()));355 q->setErrorString(QSslSocket::tr("Private key does not certify public key, %1").arg(getErrorsFromOpenSsl())); 328 356 emit q->error(QAbstractSocket::UnknownSocketError); 329 357 return false; … … 345 373 if (!(ssl = q_SSL_new(ctx))) { 346 374 // ### Bad error code 347 q->setErrorString(QSslSocket::tr("Error creating SSL session, %1").arg( SSL_ERRORSTR()));375 q->setErrorString(QSslSocket::tr("Error creating SSL session, %1").arg(getErrorsFromOpenSsl())); 348 376 q->setSocketError(QAbstractSocket::UnknownSocketError); 349 377 emit q->error(QAbstractSocket::UnknownSocketError); … … 360 388 if (!readBio || !writeBio) { 361 389 // ### Bad error code 362 q->setErrorString(QSslSocket::tr("Error creating SSL session: %1").arg( SSL_ERRORSTR()));390 q->setErrorString(QSslSocket::tr("Error creating SSL session: %1").arg(getErrorsFromOpenSsl())); 363 391 q->setSocketError(QAbstractSocket::UnknownSocketError); 364 392 emit q->error(QAbstractSocket::UnknownSocketError); … … 389 417 \internal 390 418 391 D eclared static in QSslSocketPrivate, makes sure the SSL libraries have392 been initialized.419 Does the minimum amount of initialization to determine whether SSL 420 is supported or not. 393 421 */ 394 bool QSslSocketPrivate::ensureInitialized() 422 423 bool QSslSocketPrivate::supportsSsl() 424 { 425 return ensureLibraryLoaded(); 426 } 427 428 bool QSslSocketPrivate::ensureLibraryLoaded() 395 429 { 396 430 if (!q_resolveOpenSslSymbols()) … … 399 433 // Check if the library itself needs to be initialized. 400 434 QMutexLocker locker(openssl_locks()->initLock()); 401 static int q_initialized = false; 402 if (!q_initialized) { 403 q_initialized = true; 404 405 // Initialize resources 406 initNetworkResources(); 435 if (!s_libraryLoaded) { 436 s_libraryLoaded = true; 407 437 408 438 // Initialize OpenSSL. … … 441 471 return false; 442 472 } 443 444 resetDefaultCiphers();445 setDefaultCaCertificates(systemCaCertificates());446 473 } 447 474 return true; 475 } 476 477 void QSslSocketPrivate::ensureCiphersAndCertsLoaded() 478 { 479 QMutexLocker locker(openssl_locks()->initLock()); 480 if (s_loadedCiphersAndCerts) 481 return; 482 s_loadedCiphersAndCerts = true; 483 484 resetDefaultCiphers(); 485 486 //load symbols needed to receive certificates from system store 487 #if defined(Q_OS_MAC) 488 QLibrary securityLib("/System/Library/Frameworks/Security.framework/Versions/Current/Security"); 489 if (securityLib.load()) { 490 ptrSecCertificateGetData = (PtrSecCertificateGetData) securityLib.resolve("SecCertificateGetData"); 491 if (!ptrSecCertificateGetData) 492 qWarning("could not resolve symbols in security library"); // should never happen 493 494 ptrSecTrustSettingsCopyCertificates = (PtrSecTrustSettingsCopyCertificates) securityLib.resolve("SecTrustSettingsCopyCertificates"); 495 if (!ptrSecTrustSettingsCopyCertificates) { // method was introduced in Leopard, use legacy method if it's not there 496 ptrSecTrustCopyAnchorCertificates = (PtrSecTrustCopyAnchorCertificates) securityLib.resolve("SecTrustCopyAnchorCertificates"); 497 if (!ptrSecTrustCopyAnchorCertificates) 498 qWarning("could not resolve symbols in security library"); // should never happen 499 } 500 } else { 501 qWarning("could not load security library"); 502 } 503 #elif defined(Q_OS_WIN) 504 HINSTANCE hLib = LoadLibraryW(L"Crypt32"); 505 if (hLib) { 506 #if defined(Q_OS_WINCE) 507 ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, L"CertOpenStore"); 508 ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, L"CertFindCertificateInStore"); 509 ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, L"CertCloseStore"); 510 #else 511 ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW"); 512 ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore"); 513 ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore"); 514 #endif 515 if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore) 516 qWarning("could not resolve symbols in crypt32 library"); // should never happen 517 } else { 518 qWarning("could not load crypt32 library"); // should never happen 519 } 520 #endif 521 setDefaultCaCertificates(systemCaCertificates()); 522 } 523 524 /*! 525 \internal 526 527 Declared static in QSslSocketPrivate, makes sure the SSL libraries have 528 been initialized. 529 */ 530 531 void QSslSocketPrivate::ensureInitialized() 532 { 533 if (!supportsSsl()) 534 return; 535 536 ensureCiphersAndCertsLoaded(); 448 537 } 449 538 … … 481 570 } 482 571 572 #if defined(Q_OS_SYMBIAN) 573 574 CSymbianCertificateRetriever::CSymbianCertificateRetriever() : CActive(CActive::EPriorityStandard), 575 iCertificatePtr(0,0,0), iSequenceError(KErrNone) 576 { 577 } 578 579 CSymbianCertificateRetriever::~CSymbianCertificateRetriever() 580 { 581 iThread.Close(); 582 } 583 584 CSymbianCertificateRetriever* CSymbianCertificateRetriever::NewL() 585 { 586 CSymbianCertificateRetriever* self = new (ELeave) CSymbianCertificateRetriever(); 587 CleanupStack::PushL(self); 588 self->ConstructL(); 589 CleanupStack::Pop(); 590 return self; 591 } 592 593 int CSymbianCertificateRetriever::GetCertificates(QList<QByteArray> &certificates) 594 { 595 iCertificates = &certificates; 596 597 TRequestStatus status; 598 iThread.Logon(status); 599 iThread.Resume(); 600 User::WaitForRequest(status); 601 if (iThread.ExitType() == EExitKill) 602 return KErrDied; 603 else 604 return status.Int(); // Logon() completes with the thread's exit value 605 } 606 607 void CSymbianCertificateRetriever::doThreadEntryL() 608 { 609 CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler; 610 CleanupStack::PushL(activeScheduler); 611 CActiveScheduler::Install(activeScheduler); 612 613 CActiveScheduler::Add(this); 614 615 // These aren't deleted in the destructor so leaving the to CS is ok 616 iCertStore = CUnifiedCertStore::NewLC(qt_s60GetRFs(), EFalse); 617 iCertFilter = CCertAttributeFilter::NewLC(); 618 619 // only interested in CA certs 620 iCertFilter->SetOwnerType(ECACertificate); 621 // only interested in X.509 format (we don't support WAP formats) 622 iCertFilter->SetFormat(EX509Certificate); 623 624 // Kick off the sequence by initializing the cert store 625 iState = Initializing; 626 iCertStore->Initialize(iStatus); 627 SetActive(); 628 629 CActiveScheduler::Start(); 630 631 // Sequence complete, clean up 632 633 // These MUST be cleaned up before the installed CActiveScheduler is destroyed and can't be left to the 634 // destructor of CSymbianCertificateRetriever. Otherwise the destructor of CActiveScheduler will get 635 // stuck. 636 iCertInfos.Close(); 637 CleanupStack::PopAndDestroy(3); // activeScheduler, iCertStore, iCertFilter 638 } 639 640 641 TInt CSymbianCertificateRetriever::ThreadEntryPoint(TAny* aParams) 642 { 643 User::SetCritical(User::EProcessCritical); 644 CTrapCleanup* cleanupStack = CTrapCleanup::New(); 645 646 CSymbianCertificateRetriever* self = (CSymbianCertificateRetriever*) aParams; 647 TRAPD(err, self->doThreadEntryL()); 648 delete cleanupStack; 649 650 // doThreadEntryL() can leave only before the retrieval sequence is started 651 if (err) 652 return err; 653 else 654 return self->iSequenceError; // return any error that occurred during the retrieval 655 } 656 657 void CSymbianCertificateRetriever::ConstructL() 658 { 659 TInt err; 660 int i=0; 661 QString name(QLatin1String("CertWorkerThread-%1")); 662 //recently closed thread names remain in use for a while until all handles have been closed 663 //including users of RUndertaker 664 do { 665 err = iThread.Create(qt_QString2TPtrC(name.arg(i++)), 666 CSymbianCertificateRetriever::ThreadEntryPoint, 16384, NULL, this); 667 } while (err == KErrAlreadyExists); 668 User::LeaveIfError(err); 669 } 670 671 void CSymbianCertificateRetriever::DoCancel() 672 { 673 switch(iState) { 674 case Initializing: 675 iCertStore->CancelInitialize(); 676 break; 677 case Listing: 678 iCertStore->CancelList(); 679 break; 680 case RetrievingCertificates: 681 iCertStore->CancelGetCert(); 682 break; 683 } 684 } 685 686 TInt CSymbianCertificateRetriever::RunError(TInt aError) 687 { 688 // If something goes wrong in the sequence, abort the sequence 689 iSequenceError = aError; // this gets reported to the client in the TRequestStatus 690 CActiveScheduler::Stop(); 691 return KErrNone; 692 } 693 694 void CSymbianCertificateRetriever::GetCertificateL() 695 { 696 if (iCurrentCertIndex < iCertInfos.Count()) { 697 CCTCertInfo* certInfo = iCertInfos[iCurrentCertIndex++]; 698 iCertificateData = QByteArray(); 699 QT_TRYCATCH_LEAVING(iCertificateData.resize(certInfo->Size())); 700 iCertificatePtr.Set((TUint8*)iCertificateData.data(), 0, iCertificateData.size()); 701 #ifdef QSSLSOCKET_DEBUG 702 qDebug() << "getting " << qt_TDesC2QString(certInfo->Label()) << " size=" << certInfo->Size(); 703 qDebug() << "format=" << certInfo->CertificateFormat(); 704 qDebug() << "ownertype=" << certInfo->CertificateOwnerType(); 705 qDebug() << "type=" << hex << certInfo->Type().iUid; 706 #endif 707 iCertStore->Retrieve(*certInfo, iCertificatePtr, iStatus); 708 iState = RetrievingCertificates; 709 SetActive(); 710 } else { 711 //reached end of list 712 CActiveScheduler::Stop(); 713 } 714 } 715 716 void CSymbianCertificateRetriever::RunL() 717 { 718 #ifdef QSSLSOCKET_DEBUG 719 qDebug() << "CSymbianCertificateRetriever::RunL status " << iStatus.Int() << " count " << iCertInfos.Count() << " index " << iCurrentCertIndex; 720 #endif 721 switch (iState) { 722 case Initializing: 723 User::LeaveIfError(iStatus.Int()); // initialise fail means pointless to continue 724 iState = Listing; 725 iCertStore->List(iCertInfos, *iCertFilter, iStatus); 726 SetActive(); 727 break; 728 729 case Listing: 730 User::LeaveIfError(iStatus.Int()); // listing fail means pointless to continue 731 iCurrentCertIndex = 0; 732 GetCertificateL(); 733 break; 734 735 case RetrievingCertificates: 736 if (iStatus.Int() == KErrNone) 737 iCertificates->append(iCertificateData); 738 else 739 qWarning() << "CSymbianCertificateRetriever: failed to retrieve a certificate, error " << iStatus.Int(); 740 GetCertificateL(); 741 break; 742 } 743 } 744 #endif // defined(Q_OS_SYMBIAN) 745 483 746 QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates() 484 747 { 485 // Qt provides a default bundle of certificates 486 QFile caBundle(QLatin1String(":/trolltech/network/ssl/qt-ca-bundle.crt")); 487 if (caBundle.open(QIODevice::ReadOnly | QIODevice::Text)) 488 return QSslCertificate::fromDevice(&caBundle); 489 490 // Unreachable; return no bundle. 491 return QList<QSslCertificate>(); 748 ensureInitialized(); 749 #ifdef QSSLSOCKET_DEBUG 750 QElapsedTimer timer; 751 timer.start(); 752 #endif 753 QList<QSslCertificate> systemCerts; 754 #if defined(Q_OS_MAC) 755 CFArrayRef cfCerts; 756 OSStatus status = 1; 757 758 OSStatus SecCertificateGetData ( 759 SecCertificateRef certificate, 760 CSSM_DATA_PTR data 761 ); 762 763 if (ptrSecCertificateGetData) { 764 if (ptrSecTrustSettingsCopyCertificates) 765 status = ptrSecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts); 766 else if (ptrSecTrustCopyAnchorCertificates) 767 status = ptrSecTrustCopyAnchorCertificates(&cfCerts); 768 if (!status) { 769 CFIndex size = CFArrayGetCount(cfCerts); 770 for (CFIndex i = 0; i < size; ++i) { 771 SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i); 772 CSSM_DATA data; 773 CSSM_DATA_PTR dataPtr = &data; 774 if (ptrSecCertificateGetData(cfCert, dataPtr)) { 775 qWarning("error retrieving a CA certificate from the system store"); 776 } else { 777 int len = data.Length; 778 char *rawData = reinterpret_cast<char *>(data.Data); 779 QByteArray rawCert(rawData, len); 780 systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der)); 781 } 782 } 783 } 784 else { 785 // no detailed error handling here 786 qWarning("could not retrieve system CA certificates"); 787 } 788 } 789 #elif defined(Q_OS_WIN) 790 if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) { 791 HCERTSTORE hSystemStore; 792 #if defined(Q_OS_WINCE) 793 hSystemStore = ptrCertOpenSystemStoreW(CERT_STORE_PROV_SYSTEM_W, 794 0, 795 0, 796 CERT_STORE_NO_CRYPT_RELEASE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER, 797 L"ROOT"); 798 #else 799 hSystemStore = ptrCertOpenSystemStoreW(0, L"ROOT"); 800 #endif 801 if(hSystemStore) { 802 PCCERT_CONTEXT pc = NULL; 803 while(1) { 804 pc = ptrCertFindCertificateInStore( hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pc); 805 if(!pc) 806 break; 807 QByteArray der((const char *)(pc->pbCertEncoded), static_cast<int>(pc->cbCertEncoded)); 808 QSslCertificate cert(der, QSsl::Der); 809 systemCerts.append(cert); 810 } 811 ptrCertCloseStore(hSystemStore, 0); 812 } 813 } 814 #elif defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) 815 QSet<QString> certFiles; 816 QList<QByteArray> directories; 817 directories << "/etc/ssl/certs/"; // (K)ubuntu, OpenSUSE, Mandriva, MeeGo ... 818 directories << "/usr/lib/ssl/certs/"; // Gentoo, Mandrake 819 directories << "/usr/share/ssl/"; // Centos, Redhat, SuSE 820 directories << "/usr/local/ssl/"; // Normal OpenSSL Tarball 821 directories << "/var/ssl/certs/"; // AIX 822 directories << "/usr/local/ssl/certs/"; // Solaris 823 directories << "/opt/openssl/certs/"; // HP-UX 824 825 QDir currentDir; 826 QStringList nameFilters; 827 nameFilters << QLatin1String("*.pem") << QLatin1String("*.crt"); 828 currentDir.setNameFilters(nameFilters); 829 for (int a = 0; a < directories.count(); a++) { 830 currentDir.setPath(QLatin1String(directories.at(a))); 831 QDirIterator it(currentDir); 832 while(it.hasNext()) { 833 it.next(); 834 // use canonical path here to not load the same certificate twice if symlinked 835 certFiles.insert(it.fileInfo().canonicalFilePath()); 836 } 837 } 838 QSetIterator<QString> it(certFiles); 839 while(it.hasNext()) { 840 systemCerts.append(QSslCertificate::fromPath(it.next())); 841 } 842 systemCerts.append(QSslCertificate::fromPath(QLatin1String("/etc/pki/tls/certs/ca-bundle.crt"), QSsl::Pem)); // Fedora, Mandriva 843 systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/local/share/certs/ca-root-nss.crt"), QSsl::Pem)); // FreeBSD's ca_root_nss 844 845 #elif defined(Q_OS_SYMBIAN) 846 QList<QByteArray> certs; 847 QScopedPointer<CSymbianCertificateRetriever> retriever(CSymbianCertificateRetriever::NewL()); 848 849 retriever->GetCertificates(certs); 850 foreach (const QByteArray &encodedCert, certs) { 851 QSslCertificate cert(encodedCert, QSsl::Der); 852 if (!cert.isNull()) { 853 #ifdef QSSLSOCKET_DEBUG 854 qDebug() << "imported certificate: " << cert.issuerInfo(QSslCertificate::CommonName); 855 #endif 856 systemCerts.append(cert); 857 } 858 } 859 #endif 860 #ifdef QSSLSOCKET_DEBUG 861 qDebug() << "systemCaCertificates retrieval time " << timer.elapsed() << "ms"; 862 qDebug() << "imported " << systemCerts.count() << " certificates"; 863 #endif 864 865 return systemCerts; 492 866 } 493 867 … … 544 918 if (writtenBytes <= 0) { 545 919 // ### Better error handling. 546 q->setErrorString(QSslSocket::tr("Unable to write data: %1").arg( SSL_ERRORSTR()));920 q->setErrorString(QSslSocket::tr("Unable to write data: %1").arg(getErrorsFromOpenSsl())); 547 921 q->setSocketError(QAbstractSocket::UnknownSocketError); 548 922 emit q->error(QAbstractSocket::UnknownSocketError); … … 607 981 } else { 608 982 // ### Better error handling. 609 q->setErrorString(QSslSocket::tr("Unable to decrypt data: %1").arg( SSL_ERRORSTR()));983 q->setErrorString(QSslSocket::tr("Unable to decrypt data: %1").arg(getErrorsFromOpenSsl())); 610 984 q->setSocketError(QAbstractSocket::UnknownSocketError); 611 985 emit q->error(QAbstractSocket::UnknownSocketError); … … 681 1055 plainSocket->disconnectFromHost(); 682 1056 break; 1057 case SSL_ERROR_SYSCALL: // some IO error 1058 case SSL_ERROR_SSL: // error in the SSL library 1059 // we do not know exactly what the error is, nor whether we can recover from it, 1060 // so just return to prevent an endless loop in the outer "while" statement 1061 q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl())); 1062 q->setSocketError(QAbstractSocket::UnknownSocketError); 1063 emit q->error(QAbstractSocket::UnknownSocketError); 1064 return; 683 1065 default: 684 // ### Handle errors better. 685 q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(SSL_ERRORSTR())); 1066 // SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: can only happen with a 1067 // BIO_s_connect() or BIO_s_accept(), which we do not call. 1068 // SSL_ERROR_WANT_X509_LOOKUP: can only happen with a 1069 // SSL_CTX_set_client_cert_cb(), which we do not call. 1070 // So this default case should never be triggered. 1071 q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl())); 686 1072 q->setSocketError(QAbstractSocket::UnknownSocketError); 687 1073 emit q->error(QAbstractSocket::UnknownSocketError); … … 778 1164 break; 779 1165 default: 780 // ### Handle errors better 781 q->setErrorString(QSslSocket::tr("Error during SSL handshake: %1").arg(SSL_ERRORSTR())); 1166 q->setErrorString(QSslSocket::tr("Error during SSL handshake: %1").arg(getErrorsFromOpenSsl())); 782 1167 q->setSocketError(QAbstractSocket::SslHandshakeFailedError); 783 1168 #ifdef QSSLSOCKET_DEBUG … … 816 1201 QString commonName = configuration.peerCertificate.subjectInfo(QSslCertificate::CommonName); 817 1202 818 QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard); 819 if (!regexp.exactMatch(peerName)) { 1203 if (!isMatchingHostname(commonName.toLower(), peerName.toLower())) { 820 1204 bool matched = false; 821 1205 foreach (const QString &altName, configuration.peerCertificate 822 1206 .alternateSubjectNames().values(QSsl::DnsEntry)) { 823 regexp.setPattern(altName); 824 if (regexp.exactMatch(peerName)) { 1207 if (isMatchingHostname(altName.toLower(), peerName.toLower())) { 825 1208 matched = true; 826 1209 break; 827 1210 } 828 1211 } 1212 829 1213 if (!matched) { 830 1214 // No matches in common names or alternate names. … … 923 1307 ctx = 0; 924 1308 } 1309 if (pkey) { 1310 q_EVP_PKEY_free(pkey); 1311 pkey = 0; 1312 } 1313 925 1314 } 926 1315 … … 951 1340 } 952 1341 1342 QString QSslSocketBackendPrivate::getErrorsFromOpenSsl() 1343 { 1344 QString errorString; 1345 unsigned long errNum; 1346 while((errNum = q_ERR_get_error())) { 1347 if (! errorString.isEmpty()) 1348 errorString.append(QLatin1String(", ")); 1349 const char *error = q_ERR_error_string(errNum, NULL); 1350 errorString.append(QString::fromAscii(error)); // error is ascii according to man ERR_error_string 1351 } 1352 return errorString; 1353 } 1354 1355 bool QSslSocketBackendPrivate::isMatchingHostname(const QString &cn, const QString &hostname) 1356 { 1357 int wildcard = cn.indexOf(QLatin1Char('*')); 1358 1359 // Check this is a wildcard cert, if not then just compare the strings 1360 if (wildcard < 0) 1361 return cn == hostname; 1362 1363 int firstCnDot = cn.indexOf(QLatin1Char('.')); 1364 int secondCnDot = cn.indexOf(QLatin1Char('.'), firstCnDot+1); 1365 1366 // Check at least 3 components 1367 if ((-1 == secondCnDot) || (secondCnDot+1 >= cn.length())) 1368 return false; 1369 1370 // Check * is last character of 1st component (ie. there's a following .) 1371 if (wildcard+1 != firstCnDot) 1372 return false; 1373 1374 // Check only one star 1375 if (cn.lastIndexOf(QLatin1Char('*')) != wildcard) 1376 return false; 1377 1378 // Check characters preceding * (if any) match 1379 if (wildcard && (hostname.leftRef(wildcard) != cn.leftRef(wildcard))) 1380 return false; 1381 1382 // Check characters following first . match 1383 if (hostname.midRef(hostname.indexOf(QLatin1Char('.'))) != cn.midRef(firstCnDot)) 1384 return false; 1385 1386 // Check if the hostname is an IP address, if so then wildcards are not allowed 1387 QHostAddress addr(hostname); 1388 if (!addr.isNull()) 1389 return false; 1390 1391 // Ok, I guess this was a wildcard CN and the hostname matches. 1392 return true; 1393 } 1394 953 1395 QT_END_NAMESPACE -
trunk/src/network/ssl/qsslsocket_openssl_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) … … 98 98 SSL *ssl; 99 99 SSL_CTX *ctx; 100 EVP_PKEY *pkey; 100 101 BIO *readBio; 101 102 BIO *writeBio; … … 116 117 static QSslCipher QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher); 117 118 static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509); 119 Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname); 120 static QString getErrorsFromOpenSsl(); 118 121 }; 122 123 #if defined(Q_OS_SYMBIAN) 124 125 #include <QByteArray> 126 #include <e32base.h> 127 #include <f32file.h> 128 #include <unifiedcertstore.h> // link against certstore.lib 129 #include <ccertattributefilter.h> // link against ctframework.lib 130 131 // The purpose of this class is to wrap the asynchronous API of Symbian certificate store to one 132 // synchronizable call. The user of this class needs to provide a TRequestStatus object which can 133 // be used with User::WaitForRequest() unlike with the calls of the certificate store API. 134 // A thread is used instead of a CActiveSchedulerWait scheme, because that would make the call 135 // asynchronous (other events might be processed during the call even though the call would be seemingly 136 // synchronous). 137 138 class CSymbianCertificateRetriever : public CActive 139 { 140 public: 141 static CSymbianCertificateRetriever* NewL(); 142 ~CSymbianCertificateRetriever(); 143 144 int GetCertificates(QList<QByteArray> &aCertificates); 145 146 private: 147 void ConstructL(); 148 CSymbianCertificateRetriever(); 149 static TInt ThreadEntryPoint(TAny* aParams); 150 void doThreadEntryL(); 151 void GetCertificateL(); 152 void DoCancel(); 153 void RunL(); 154 TInt RunError(TInt aError); 155 156 private: 157 enum { 158 Initializing, 159 Listing, 160 RetrievingCertificates 161 } iState; 162 163 RThread iThread; 164 CUnifiedCertStore* iCertStore; 165 RMPointerArray<CCTCertInfo> iCertInfos; 166 CCertAttributeFilter* iCertFilter; 167 TInt iCurrentCertIndex; 168 QByteArray iCertificateData; 169 TPtr8 iCertificatePtr; 170 QList<QByteArray>* iCertificates; 171 TInt iSequenceError; 172 }; 173 174 175 #endif 176 119 177 120 178 QT_END_NAMESPACE -
trunk/src/network/ssl/qsslsocket_openssl_symbols.cpp
r788 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) … … 43 43 #include "qsslsocket_openssl_symbols_p.h" 44 44 45 #include <QtCore/qlibrary.h> 45 #ifdef Q_OS_WIN 46 # include <private/qsystemlibrary_p.h> 47 #else 48 # include <QtCore/qlibrary.h> 49 #endif 46 50 #include <QtCore/qmutex.h> 47 51 #include <private/qmutexpool_p.h> … … 120 124 DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return) 121 125 DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return) 126 DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return) 127 DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return) 122 128 DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG) 123 129 DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return) … … 333 339 .split(QLatin1Char(':'), QString::SkipEmptyParts); 334 340 # endif 335 paths << QLatin1String("/ usr/lib") << QLatin1String("/usr/local/lib");341 paths << QLatin1String("/lib") << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib"); 336 342 337 343 QStringList foundSsls; … … 348 354 } 349 355 # endif 356 357 #ifdef Q_OS_WIN 358 static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32() 359 { 360 QPair<QSystemLibrary*,QSystemLibrary*> pair; 361 pair.first = 0; 362 pair.second = 0; 363 364 QSystemLibrary *ssleay32 = new QSystemLibrary(QLatin1String("ssleay32")); 365 if (!ssleay32->load(false)) { 366 // Cannot find ssleay32.dll 367 delete ssleay32; 368 return pair; 369 } 370 371 QSystemLibrary *libeay32 = new QSystemLibrary(QLatin1String("libeay32")); 372 if (!libeay32->load(false)) { 373 delete ssleay32; 374 delete libeay32; 375 return pair; 376 } 377 378 pair.first = ssleay32; 379 pair.second = libeay32; 380 return pair; 381 } 382 #else 350 383 351 384 static QPair<QLibrary*, QLibrary*> loadOpenSsl() … … 355 388 pair.second = 0; 356 389 357 # ifdef Q_OS_WIN 358 QLibrary *ssleay32 = new QLibrary(QLatin1String("ssleay32")); 359 if (!ssleay32->load()) { 360 // Cannot find ssleay32.dll 361 delete ssleay32; 362 return pair; 363 } 364 365 QLibrary *libeay32 = new QLibrary(QLatin1String("libeay32")); 366 if (!libeay32->load()) { 367 delete ssleay32; 368 delete libeay32; 369 return pair; 370 } 371 372 pair.first = ssleay32; 373 pair.second = libeay32; 374 return pair; 375 # elif defined(Q_OS_SYMBIAN) 390 # if defined(Q_OS_SYMBIAN) 376 391 QLibrary *libssl = new QLibrary(QLatin1String("libssl")); 377 392 if (!libssl->load()) { … … 506 521 # endif 507 522 } 523 #endif 508 524 509 525 bool q_resolveOpenSslSymbols() … … 520 536 triedToResolveSymbols = true; 521 537 538 #ifdef Q_OS_WIN 539 QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32(); 540 #else 522 541 QPair<QLibrary *, QLibrary *> libs = loadOpenSsl(); 542 #endif 523 543 if (!libs.first || !libs.second) 524 544 // failed to load them … … 549 569 RESOLVEFUNC(EVP_des_ede3_cbc, 919, libs.second ) 550 570 RESOLVEFUNC(EVP_PKEY_assign, 859, libs.second ) 571 RESOLVEFUNC(EVP_PKEY_set1_RSA, 880, libs.second ) 572 RESOLVEFUNC(EVP_PKEY_set1_DSA, 879, libs.second ) 551 573 RESOLVEFUNC(EVP_PKEY_free, 867, libs.second ) 552 574 RESOLVEFUNC(EVP_PKEY_get1_DSA, 869, libs.second ) … … 671 693 RESOLVEFUNC(EVP_des_ede3_cbc) 672 694 RESOLVEFUNC(EVP_PKEY_assign) 695 RESOLVEFUNC(EVP_PKEY_set1_RSA) 696 RESOLVEFUNC(EVP_PKEY_set1_DSA) 673 697 RESOLVEFUNC(EVP_PKEY_free) 674 698 RESOLVEFUNC(EVP_PKEY_get1_DSA) … … 794 818 QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime) 795 819 { 796 char lBuffer[24];797 char *pBuffer = lBuffer;798 799 820 size_t lTimeLength = aTime->length; 800 821 char *pString = (char *) aTime->data; 801 822 802 823 if (aTime->type == V_ASN1_UTCTIME) { 824 825 char lBuffer[24]; 826 char *pBuffer = lBuffer; 827 803 828 if ((lTimeLength < 11) || (lTimeLength > 17)) 804 829 return QDateTime(); … … 807 832 pBuffer += 10; 808 833 pString += 10; 834 835 if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) { 836 *pBuffer++ = '0'; 837 *pBuffer++ = '0'; 838 } else { 839 *pBuffer++ = *pString++; 840 *pBuffer++ = *pString++; 841 // Skip any fractional seconds... 842 if (*pString == '.') { 843 pString++; 844 while ((*pString >= '0') && (*pString <= '9')) 845 pString++; 846 } 847 } 848 849 *pBuffer++ = 'Z'; 850 *pBuffer++ = '\0'; 851 852 time_t lSecondsFromUCT; 853 if (*pString == 'Z') { 854 lSecondsFromUCT = 0; 855 } else { 856 if ((*pString != '+') && (*pString != '-')) 857 return QDateTime(); 858 859 lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60; 860 lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0'); 861 lSecondsFromUCT *= 60; 862 if (*pString == '-') 863 lSecondsFromUCT = -lSecondsFromUCT; 864 } 865 866 tm lTime; 867 lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0'); 868 lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0'); 869 lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0'); 870 lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0'); 871 lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1; 872 lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0'); 873 if (lTime.tm_year < 50) 874 lTime.tm_year += 100; // RFC 2459 875 876 QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday); 877 QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec); 878 879 QDateTime result(resDate, resTime, Qt::UTC); 880 result = result.addSecs(lSecondsFromUCT); 881 return result; 882 883 } else if (aTime->type == V_ASN1_GENERALIZEDTIME) { 884 885 if (lTimeLength < 15) 886 return QDateTime(); // hopefully never triggered 887 888 // generalized time is always YYYYMMDDHHMMSSZ (RFC 2459, section 4.1.2.5.2) 889 tm lTime; 890 lTime.tm_sec = ((pString[12] - '0') * 10) + (pString[13] - '0'); 891 lTime.tm_min = ((pString[10] - '0') * 10) + (pString[11] - '0'); 892 lTime.tm_hour = ((pString[8] - '0') * 10) + (pString[9] - '0'); 893 lTime.tm_mday = ((pString[6] - '0') * 10) + (pString[7] - '0'); 894 lTime.tm_mon = (((pString[4] - '0') * 10) + (pString[5] - '0')); 895 lTime.tm_year = ((pString[0] - '0') * 1000) + ((pString[1] - '0') * 100) + 896 ((pString[2] - '0') * 10) + (pString[3] - '0'); 897 898 QDate resDate(lTime.tm_year, lTime.tm_mon, lTime.tm_mday); 899 QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec); 900 901 QDateTime result(resDate, resTime, Qt::UTC); 902 return result; 903 809 904 } else { 810 if (lTimeLength < 13) 811 return QDateTime(); 812 813 memcpy(pBuffer, pString, 12); 814 pBuffer += 12; 815 pString += 12; 816 } 817 818 if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) { 819 *pBuffer++ = '0'; 820 *pBuffer++ = '0'; 821 } else { 822 *pBuffer++ = *pString++; 823 *pBuffer++ = *pString++; 824 // Skip any fractional seconds... 825 if (*pString == '.') { 826 pString++; 827 while ((*pString >= '0') && (*pString <= '9')) 828 pString++; 829 } 830 } 831 832 *pBuffer++ = 'Z'; 833 *pBuffer++ = '\0'; 834 835 time_t lSecondsFromUCT; 836 if (*pString == 'Z') { 837 lSecondsFromUCT = 0; 838 } else { 839 if ((*pString != '+') && (*pString != '-')) 840 return QDateTime(); 841 842 lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60; 843 lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0'); 844 lSecondsFromUCT *= 60; 845 if (*pString == '-') 846 lSecondsFromUCT = -lSecondsFromUCT; 847 } 848 849 tm lTime; 850 lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0'); 851 lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0'); 852 lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0'); 853 lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0'); 854 lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1; 855 lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0'); 856 if (lTime.tm_year < 50) 857 lTime.tm_year += 100; // RFC 2459 858 859 QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday); 860 QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec); 861 QDateTime result(resDate, resTime, Qt::UTC); 862 result = result.addSecs(lSecondsFromUCT); 863 return result; 905 qWarning("unsupported date format detected"); 906 return QDateTime(); 907 } 908 864 909 } 865 910 -
trunk/src/network/ssl/qsslsocket_openssl_symbols_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) … … 228 228 const EVP_CIPHER *q_EVP_des_ede3_cbc(); 229 229 int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); 230 int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b); 231 int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); 230 232 void q_EVP_PKEY_free(EVP_PKEY *a); 231 233 RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a); -
trunk/src/network/ssl/qsslsocket_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) … … 67 67 QT_BEGIN_NAMESPACE 68 68 69 #if defined(Q_OS_MAC) 70 #include <Security/SecCertificate.h> 71 #include <CoreFoundation/CFArray.h> 72 typedef OSStatus (*PtrSecCertificateGetData)(SecCertificateRef, CSSM_DATA_PTR); 73 typedef OSStatus (*PtrSecTrustSettingsCopyCertificates)(int, CFArrayRef*); 74 typedef OSStatus (*PtrSecTrustCopyAnchorCertificates)(CFArrayRef*); 75 #elif defined(Q_OS_WIN) 76 #include <wincrypt.h> 77 #ifndef HCRYPTPROV_LEGACY 78 #define HCRYPTPROV_LEGACY HCRYPTPROV 79 #endif 80 #if defined(Q_OS_WINCE) 81 typedef HCERTSTORE (WINAPI *PtrCertOpenSystemStoreW)(LPCSTR, DWORD, HCRYPTPROV_LEGACY, DWORD, const void*); 82 #else 83 typedef HCERTSTORE (WINAPI *PtrCertOpenSystemStoreW)(HCRYPTPROV_LEGACY, LPCWSTR); 84 #endif 85 typedef PCCERT_CONTEXT (WINAPI *PtrCertFindCertificateInStore)(HCERTSTORE, DWORD, DWORD, DWORD, const void*, PCCERT_CONTEXT); 86 typedef BOOL (WINAPI *PtrCertCloseStore)(HCERTSTORE, DWORD); 87 #endif 88 89 90 69 91 class QSslSocketPrivate : public QTcpSocketPrivate 70 92 { … … 91 113 QString verificationPeerName; 92 114 93 static bool ensureInitialized(); 115 static bool supportsSsl(); 116 static void ensureInitialized(); 94 117 static void deinitialize(); 95 118 static QList<QSslCipher> defaultCiphers(); … … 107 130 static void addDefaultCaCertificates(const QList<QSslCertificate> &certs); 108 131 132 #if defined(Q_OS_MAC) 133 static PtrSecCertificateGetData ptrSecCertificateGetData; 134 static PtrSecTrustSettingsCopyCertificates ptrSecTrustSettingsCopyCertificates; 135 static PtrSecTrustCopyAnchorCertificates ptrSecTrustCopyAnchorCertificates; 136 #elif defined(Q_OS_WIN) 137 static PtrCertOpenSystemStoreW ptrCertOpenSystemStoreW; 138 static PtrCertFindCertificateInStore ptrCertFindCertificateInStore; 139 static PtrCertCloseStore ptrCertCloseStore; 140 #endif 141 109 142 // The socket itself, including private slots. 110 143 QTcpSocket *plainSocket; 111 144 void createPlainSocket(QIODevice::OpenMode openMode); 145 static void pauseSocketNotifiers(QSslSocket*); 146 static void resumeSocketNotifiers(QSslSocket*); 112 147 void _q_connectedSlot(); 113 148 void _q_hostFoundSlot(); … … 127 162 virtual void disconnected() = 0; 128 163 virtual QSslCipher sessionCipher() const = 0; 164 165 private: 166 static bool ensureLibraryLoaded(); 167 static void ensureCiphersAndCertsLoaded(); 168 169 static bool s_libraryLoaded; 170 static bool s_loadedCiphersAndCerts; 129 171 }; 130 172 -
trunk/src/network/ssl/ssl.pri
r788 r846 32 32 ssl/qsslsocket_openssl_symbols.cpp 33 33 34 # Include Qt's default CA bundle35 RESOURCES += network.qrc36 37 34 # Add optional SSL libs 38 35 LIBS_PRIVATE += $$OPENSSL_LIBS
Note:
See TracChangeset
for help on using the changeset viewer.