diff options
29 files changed, 297 insertions, 361 deletions
diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index 13375f8..9c2f79a 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -2442,7 +2442,7 @@ void QHttpPrivate::_q_slotSendRequest() if (proxy.hostName().isEmpty()) { proxy.setType(QNetworkProxy::NoProxy); } else if (sslInUse) { - // Disallow use of cacheing proxy with HTTPS; instead fall back to + // Disallow use of caching proxy with HTTPS; instead fall back to // transparent HTTP CONNECT proxying. transparentProxyInUse = true; } else { diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index ccdbb20..89f9b03 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include <private/qabstractsocket_p.h> #include "qhttpnetworkconnection_p.h" #include "qhttpnetworkconnectionchannel_p.h" #include "private/qnoncontiguousbytedevice_p.h" @@ -56,6 +57,7 @@ #ifndef QT_NO_HTTP #ifndef QT_NO_OPENSSL +# include <private/qsslsocket_p.h> # include <QtNetwork/qsslkey.h> # include <QtNetwork/qsslcipher.h> # include <QtNetwork/qsslconfiguration.h> @@ -79,9 +81,9 @@ const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2; QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt) -: hostName(hostName), port(port), encrypt(encrypt), - channelCount(defaultChannelCount), - pendingAuthSignal(false), pendingProxyAuthSignal(false) +: state(RunningState), + hostName(hostName), port(port), encrypt(encrypt), + channelCount(defaultChannelCount) #ifndef QT_NO_NETWORKPROXY , networkProxy(QNetworkProxy::NoProxy) #endif @@ -90,9 +92,9 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host } QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt) -: hostName(hostName), port(port), encrypt(encrypt), - channelCount(channelCount), - pendingAuthSignal(false), pendingProxyAuthSignal(false) +: state(RunningState), + hostName(hostName), port(port), encrypt(encrypt), + channelCount(channelCount) #ifndef QT_NO_NETWORKPROXY , networkProxy(QNetworkProxy::NoProxy) #endif @@ -121,6 +123,42 @@ void QHttpNetworkConnectionPrivate::init() } } +void QHttpNetworkConnectionPrivate::pauseConnection() +{ + state = PausedState; + + // Disable all socket notifiers + for (int i = 0; i < channelCount; i++) { +#ifndef QT_NO_OPENSSL + if (encrypt) + QSslSocketPrivate::pauseSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket)); + else +#endif + QAbstractSocketPrivate::pauseSocketNotifiers(channels[i].socket); + } +} + +void QHttpNetworkConnectionPrivate::resumeConnection() +{ + state = RunningState; + // Enable all socket notifiers + for (int i = 0; i < channelCount; i++) { +#ifndef QT_NO_OPENSSL + if (encrypt) + QSslSocketPrivate::resumeSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket)); + else +#endif + QAbstractSocketPrivate::resumeSocketNotifiers(channels[i].socket); + + // Resume pending upload if needed + if (channels[i].state == QHttpNetworkConnectionChannel::WritingState) + QMetaObject::invokeMethod(&channels[i], "_q_uploadDataReadyRead", Qt::QueuedConnection); + } + + // queue _q_startNextRequest + QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection); +} + int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const { for (int i = 0; i < channelCount; ++i) @@ -257,6 +295,13 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica { Q_ASSERT(auth); + // NTLM is a multi phase authentication. Copying credentials between authenticators would mess things up. + if (!isProxy && channels[fromChannel].authMethod == QAuthenticatorPrivate::Ntlm) + return; + if (isProxy && channels[fromChannel].proxyAuthMethod == QAuthenticatorPrivate::Ntlm) + return; + + // select another channel QAuthenticator* otherAuth = 0; for (int i = 0; i < channelCount; ++i) { @@ -296,10 +341,10 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket QAuthenticator* auth = 0; if (isProxy) { auth = &channels[i].proxyAuthenticator; - channels[i].proxyAuthMehtod = authMethod; + channels[i].proxyAuthMethod = authMethod; } else { auth = &channels[i].authenticator; - channels[i].authMehtod = authMethod; + channels[i].authMethod = authMethod; } //proceed with the authentication. if (auth->isNull()) @@ -308,43 +353,23 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket priv->parseHttpResponse(fields, isProxy); if (priv->phase == QAuthenticatorPrivate::Done) { - if ((isProxy && pendingProxyAuthSignal) ||(!isProxy && pendingAuthSignal)) { - // drop the request - reply->d_func()->eraseData(); - channels[i].close(); - channels[i].lastStatus = 0; - channels[i].state = QHttpNetworkConnectionChannel::Wait4AuthState; - return false; - } - // cannot use this socket until the slot returns - channels[i].state = QHttpNetworkConnectionChannel::WaitingState; - socket->blockSignals(true); + pauseConnection(); if (!isProxy) { - pendingAuthSignal = true; - emit q->authenticationRequired(reply->request(), auth, q); - pendingAuthSignal = false; + emit reply->authenticationRequired(reply->request(), auth); #ifndef QT_NO_NETWORKPROXY } else { - pendingProxyAuthSignal = true; - emit q->proxyAuthenticationRequired(networkProxy, auth, q); - pendingProxyAuthSignal = false; + emit reply->proxyAuthenticationRequired(networkProxy, auth); #endif } - socket->blockSignals(false); - // socket free to use - channels[i].state = QHttpNetworkConnectionChannel::IdleState; + resumeConnection(); + if (priv->phase != QAuthenticatorPrivate::Done) { // send any pending requests copyCredentials(i, auth, isProxy); - QMetaObject::invokeMethod(q, "_q_restartAuthPendingRequests", Qt::QueuedConnection); } - } else if (priv->phase == QAuthenticatorPrivate::Start) { - // If the url's authenticator has a 'user' set we will end up here (phase is only set to 'Done' by - // parseHttpResponse above if 'user' is empty). So if credentials were supplied with the request, - // such as in the case of an XMLHttpRequest, this is our only opportunity to cache them. - emit q->cacheCredentials(reply->request(), auth, q); } - // - Changing values in QAuthenticator will reset the 'phase'. + // - Changing values in QAuthenticator will reset the 'phase'. Therefore if it is still "Done" + // then nothing was filled in by the user or the cache // - If withCredentials has been set to false (e.g. by QtWebKit for a cross-origin XMLHttpRequest) then // we need to bail out if authentication is required. if (priv->phase == QAuthenticatorPrivate::Done || !reply->request().withCredentials()) { @@ -356,15 +381,9 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket ? QNetworkReply::ProxyAuthenticationRequiredError : QNetworkReply::AuthenticationRequiredError; reply->d_func()->errorString = errorDetail(errorCode, socket); - emit q->error(errorCode, reply->d_func()->errorString); - emit channels[i].reply->finished(); + emit reply->finishedWithError(errorCode, reply->d_func()->errorString); // ### at this point the reply could be deleted socket->close(); - // remove pending request on the other channels - for (int j = 0; j < channelCount; ++j) { - if (j != i && channels[j].state == QHttpNetworkConnectionChannel::Wait4AuthState) - channels[j].state = QHttpNetworkConnectionChannel::IdleState; - } return true; } //resend the request @@ -380,8 +399,9 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, int i = indexOf(socket); - if (channels[i].authMehtod != QAuthenticatorPrivate::None) { - if (!(channels[i].authMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) { + // Send "Authorization" header, but not if it's NTLM and the socket is already authenticated. + if (channels[i].authMethod != QAuthenticatorPrivate::None) { + if (!(channels[i].authMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) { QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator); if (priv && priv->method != QAuthenticatorPrivate::None) { QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false)); @@ -389,8 +409,10 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, } } } - if (channels[i].proxyAuthMehtod != QAuthenticatorPrivate::None) { - if (!(channels[i].proxyAuthMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) { + + // Send "Proxy-Authorization" header, but not if it's NTLM and the socket is already authenticated. + if (channels[i].proxyAuthMethod != QAuthenticatorPrivate::None) { + if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) { QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator); if (priv && priv->method != QAuthenticatorPrivate::None) { QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false)); @@ -723,6 +745,10 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) // although it is called _q_startNextRequest, it will actually start multiple requests when possible void QHttpNetworkConnectionPrivate::_q_startNextRequest() { + // If the QHttpNetworkConnection is currently paused then bail out immediately + if (state == PausedState) + return; + //resend the necessary ones. for (int i = 0; i < channelCount; ++i) { if (channels[i].resendCurrent) { @@ -773,17 +799,6 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() fillPipeline(channels[i].socket); } -void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests() -{ - // send the request using the idle socket - for (int i = 0 ; i < channelCount; ++i) { - if (channels[i].state == QHttpNetworkConnectionChannel::Wait4AuthState) { - channels[i].state = QHttpNetworkConnectionChannel::IdleState; - if (channels[i].reply) - channels[i].sendRequest(); - } - } -} void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply) { @@ -832,33 +847,12 @@ QHttpNetworkReply* QHttpNetworkConnection::sendRequest(const QHttpNetworkRequest return d->queueRequest(request); } -void QHttpNetworkConnection::enableEncryption() -{ - Q_D(QHttpNetworkConnection); - d->encrypt = true; -} - bool QHttpNetworkConnection::isEncrypted() const { Q_D(const QHttpNetworkConnection); return d->encrypt; } -void QHttpNetworkConnection::setProxyAuthentication(QAuthenticator *authenticator) -{ - Q_D(QHttpNetworkConnection); - for (int i = 0; i < d->channelCount; ++i) - d->channels[i].proxyAuthenticator = *authenticator; -} - -void QHttpNetworkConnection::setAuthentication(const QString &domain, QAuthenticator *authenticator) -{ - Q_UNUSED(domain); // ### domain ? - Q_D(QHttpNetworkConnection); - for (int i = 0; i < d->channelCount; ++i) - d->channels[i].authenticator = *authenticator; -} - #ifndef QT_NO_NETWORKPROXY void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy) { @@ -951,8 +945,11 @@ void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int // e.g. it is for SOCKS proxies which require authentication. void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth) { - Q_Q(QHttpNetworkConnection); - emit q->proxyAuthenticationRequired(proxy, auth, q); + // Also pause the connection because socket notifiers may fire while an user + // dialog is displaying + pauseConnection(); + emit chan->reply->proxyAuthenticationRequired(proxy, auth); + resumeConnection(); int i = indexOf(chan->socket); copyCredentials(i, auth, true); } diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 51666d6..8461426c 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -108,43 +108,22 @@ public: QNetworkProxy transparentProxy() const; #endif - //enable encryption - void enableEncryption(); bool isEncrypted() const; - //authentication parameters - void setProxyAuthentication(QAuthenticator *authenticator); - void setAuthentication(const QString &domain, QAuthenticator *authenticator); - #ifndef QT_NO_OPENSSL void setSslConfiguration(const QSslConfiguration &config); void ignoreSslErrors(int channel = -1); void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1); - -Q_SIGNALS: - void sslErrors(const QList<QSslError> &errors); -#endif - -Q_SIGNALS: -#ifndef QT_NO_NETWORKPROXY - //cannot be used with queued connection. - void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator, - const QHttpNetworkConnection *connection = 0); #endif - void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator, - const QHttpNetworkConnection *connection = 0); - void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator, - const QHttpNetworkConnection *connection = 0); - void error(QNetworkReply::NetworkError errorCode, const QString &detail = QString()); private: Q_DECLARE_PRIVATE(QHttpNetworkConnection) Q_DISABLE_COPY(QHttpNetworkConnection) friend class QHttpNetworkReply; + friend class QHttpNetworkReplyPrivate; friend class QHttpNetworkConnectionChannel; Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest()) - Q_PRIVATE_SLOT(d_func(), void _q_restartAuthPendingRequests()) }; @@ -160,11 +139,20 @@ public: static const int defaultPipelineLength; static const int defaultRePipelineLength; + enum ConnectionState { + RunningState = 0, + PausedState = 1, + }; + QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt); ~QHttpNetworkConnectionPrivate(); void init(); + void pauseConnection(); + void resumeConnection(); + ConnectionState state; + enum { ChunkSize = 4096 }; int indexOf(QAbstractSocket *socket) const; @@ -184,7 +172,6 @@ public: // private slots void _q_startNextRequest(); // send the next request from the queue - void _q_restartAuthPendingRequests(); // send the currently blocked request void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); @@ -203,9 +190,6 @@ public: const int channelCount; QHttpNetworkConnectionChannel *channels; // parallel connections to the server - bool pendingAuthSignal; // there is an incomplete authentication signal - bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal - qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const; qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index d10f951..4e5de53 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -68,8 +68,8 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel() , lastStatus(0) , pendingEncrypt(false) , reconnectAttempts(2) - , authMehtod(QAuthenticatorPrivate::None) - , proxyAuthMehtod(QAuthenticatorPrivate::None) + , authMethod(QAuthenticatorPrivate::None) + , proxyAuthMethod(QAuthenticatorPrivate::None) #ifndef QT_NO_OPENSSL , ignoreAllSslErrors(false) #endif @@ -190,6 +190,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() || (!url.password().isEmpty() && url.password() != auth.password())) { auth.setUser(url.userName()); auth.setPassword(url.password()); + emit reply->cacheCredentials(request, &auth); connection->d_func()->copyCredentials(connection->d_func()->indexOf(socket), &auth, false); } // clear the userinfo, since we use the same request for resending @@ -309,7 +310,6 @@ bool QHttpNetworkConnectionChannel::sendRequest() break; } case QHttpNetworkConnectionChannel::ReadingState: - case QHttpNetworkConnectionChannel::Wait4AuthState: // ignore _q_bytesWritten in these states // fall through default: @@ -797,8 +797,7 @@ void QHttpNetworkConnectionChannel::handleStatus() ? QNetworkReply::ProxyAuthenticationRequiredError : QNetworkReply::AuthenticationRequiredError; reply->d_func()->errorString = connection->d_func()->errorDetail(errorCode, socket); - emit connection->error(errorCode, reply->d_func()->errorString); - emit reply->finished(); + emit reply->finishedWithError(errorCode, reply->d_func()->errorString); } break; default: @@ -945,7 +944,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket { if (!socket) return; - bool send2Reply = false; QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; switch (socketError) { @@ -963,7 +961,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket closeAndResendCurrentRequest(); return; } else { - send2Reply = true; errorCode = QNetworkReply::RemoteHostClosedError; } } else { @@ -976,7 +973,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket closeAndResendCurrentRequest(); return; } - send2Reply = true; errorCode = QNetworkReply::TimeoutError; break; case QAbstractSocket::ProxyAuthenticationRequiredError: @@ -992,18 +988,14 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket } QPointer<QHttpNetworkConnection> that = connection; QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString()); - if (send2Reply) { - if (reply) { - reply->d_func()->errorString = errorString; - // this error matters only to this reply - emit reply->finishedWithError(errorCode, errorString); - } - // send the next request - QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); - } else { - // the failure affects all requests. - emit connection->error(errorCode, errorString); + + if (reply) { + reply->d_func()->errorString = errorString; + emit reply->finishedWithError(errorCode, errorString); } + // send the next request + QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); + if (that) //signal emission triggered event loop close(); } @@ -1034,7 +1026,11 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors) if (!socket) return; //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure; - emit connection->sslErrors(errors); + // Also pause the connection because socket notifiers may fire while an user + // dialog is displaying + connection->d_func()->pauseConnection(); + emit reply->sslErrors(errors); + connection->d_func()->resumeConnection(); } void QHttpNetworkConnectionChannel::_q_encryptedBytesWritten(qint64 bytes) diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 41a896d..442086a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -95,8 +95,7 @@ public: WritingState = 2, // writing the data WaitingState = 4, // waiting for reply ReadingState = 8, // reading the reply - Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done - BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState) + BusyState = (ConnectingState|WritingState|WaitingState|ReadingState) }; QAbstractSocket *socket; ChannelState state; @@ -108,8 +107,8 @@ public: int lastStatus; // last status received on this channel bool pendingEncrypt; // for https (send after encrypted) int reconnectAttempts; // maximum 2 reconnection attempts - QAuthenticatorPrivate::Method authMehtod; - QAuthenticatorPrivate::Method proxyAuthMehtod; + QAuthenticatorPrivate::Method authMethod; + QAuthenticatorPrivate::Method proxyAuthMethod; QAuthenticator authenticator; QAuthenticator proxyAuthenticator; #ifndef QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 108ba8a..e4eb7c4 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -205,6 +205,11 @@ bool QHttpNetworkReply::isPipeliningUsed() const return d_func()->pipeliningUsed; } +QHttpNetworkConnection* QHttpNetworkReply::connection() +{ + return d_func()->connection; +} + QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100), diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 4011c78..3f79d81 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -132,6 +132,8 @@ public: bool isPipeliningUsed() const; + QHttpNetworkConnection* connection(); + #ifndef QT_NO_OPENSSL QSslConfiguration sslConfiguration() const; void setSslConfiguration(const QSslConfiguration &config); @@ -149,7 +151,11 @@ Q_SIGNALS: void headerChanged(); void dataReadProgress(int done, int total); void dataSendProgress(qint64 done, qint64 total); - + void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator); +#ifndef QT_NO_NETWORKPROXY + void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); +#endif + void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator); private: Q_DECLARE_PRIVATE(QHttpNetworkReply) friend class QHttpNetworkConnection; diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 60f7dc6..0a0987a 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -329,7 +329,7 @@ void QNetworkAccessBackend::authenticationRequired(QAuthenticator *authenticator void QNetworkAccessBackend::cacheCredentials(QAuthenticator *authenticator) { - manager->addCredentials(this->reply->url, authenticator); + manager->cacheCredentials(this->reply->url, authenticator); } void QNetworkAccessBackend::metaDataChanged() diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index f617244..2a0daf8 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -338,24 +338,6 @@ void QNetworkAccessHttpBackend::finished() QNetworkAccessBackend::finished(); } -void QNetworkAccessHttpBackend::setupConnection() -{ -#ifndef QT_NO_NETWORKPROXY - connect(http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), - SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); -#endif - connect(http, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)), - SLOT(httpAuthenticationRequired(QHttpNetworkRequest,QAuthenticator*))); - connect(http, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)), - SLOT(httpCacheCredentials(QHttpNetworkRequest,QAuthenticator*))); - connect(http, SIGNAL(error(QNetworkReply::NetworkError,QString)), - SLOT(httpError(QNetworkReply::NetworkError,QString))); -#ifndef QT_NO_OPENSSL - connect(http, SIGNAL(sslErrors(QList<QSslError>)), - SLOT(sslErrors(QList<QSslError>))); -#endif -} - /* For a given httpRequest 1) If AlwaysNetwork, return @@ -593,6 +575,8 @@ void QNetworkAccessHttpBackend::postRequest() if (pendingIgnoreAllSslErrors) httpReply->ignoreSslErrors(); httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList); + connect(httpReply, SIGNAL(sslErrors(QList<QSslError>)), + SLOT(sslErrors(QList<QSslError>))); #endif connect(httpReply, SIGNAL(readyRead()), SLOT(replyReadyRead())); @@ -600,6 +584,14 @@ void QNetworkAccessHttpBackend::postRequest() connect(httpReply, SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)), SLOT(httpError(QNetworkReply::NetworkError,QString))); connect(httpReply, SIGNAL(headerChanged()), SLOT(replyHeaderChanged())); + connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)), + SLOT(httpCacheCredentials(QHttpNetworkRequest,QAuthenticator*))); +#ifndef QT_NO_NETWORKPROXY + connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); +#endif + connect(httpReply, SIGNAL(authenticationRequired(const QHttpNetworkRequest,QAuthenticator*)), + SLOT(httpAuthenticationRequired(const QHttpNetworkRequest,QAuthenticator*))); } void QNetworkAccessHttpBackend::invalidateCache() @@ -674,7 +666,6 @@ void QNetworkAccessHttpBackend::open() cache->addEntry(cacheKey, http); } - setupConnection(); postRequest(); } @@ -880,29 +871,6 @@ void QNetworkAccessHttpBackend::httpError(QNetworkReply::NetworkError errorCode, #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) qDebug() << "http error!" << errorCode << errorString; #endif -#if 0 - static const QNetworkReply::NetworkError conversionTable[] = { - QNetworkReply::ConnectionRefusedError, - QNetworkReply::RemoteHostClosedError, - QNetworkReply::HostNotFoundError, - QNetworkReply::UnknownNetworkError, // SocketAccessError - QNetworkReply::UnknownNetworkError, // SocketResourceError - QNetworkReply::TimeoutError, // SocketTimeoutError - QNetworkReply::UnknownNetworkError, // DatagramTooLargeError - QNetworkReply::UnknownNetworkError, // NetworkError - QNetworkReply::UnknownNetworkError, // AddressInUseError - QNetworkReply::UnknownNetworkError, // SocketAddressNotAvailableError - QNetworkReply::UnknownNetworkError, // UnsupportedSocketOperationError - QNetworkReply::UnknownNetworkError, // UnfinishedSocketOperationError - QNetworkReply::ProxyAuthenticationRequiredError - }; - QNetworkReply::NetworkError code; - if (int(errorCode) >= 0 && - uint(errorCode) < (sizeof conversionTable / sizeof conversionTable[0])) - code = conversionTable[errorCode]; - else - code = QNetworkReply::UnknownNetworkError; -#endif error(errorCode, errorString); finished(); } diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h index c4c88ae..568b2ee 100644 --- a/src/network/access/qnetworkaccesshttpbackend_p.h +++ b/src/network/access/qnetworkaccesshttpbackend_p.h @@ -125,7 +125,6 @@ private: quint64 resumeOffset; void disconnectFromHttp(); - void setupConnection(); void validateCache(QHttpNetworkRequest &httpRequest, bool &loadedFromCache); void invalidateCache(); void postRequest(); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 12fe094..e5f4d5a 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1025,16 +1025,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera priv->manager = this; // second step: fetch cached credentials - if (static_cast<QNetworkRequest::LoadControl> - (request.attribute(QNetworkRequest::AuthenticationReuseAttribute, - QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic) { - QNetworkAuthenticationCredential *cred = d->fetchCachedCredentials(url); - if (cred) { - url.setUserName(cred->user); - url.setPassword(cred->password); - priv->urlForLastAuthentication = url; - } - } + // This is not done for the time being, we should use signal emissions to request + // the credentials from cache. // third step: find a backend priv->backend = d->findBackend(op, request); @@ -1116,7 +1108,9 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend // don't try the cache for the same URL twice in a row // being called twice for the same URL means the authentication failed - if (url != backend->reply->urlForLastAuthentication) { + // also called when last URL is empty, e.g. on first call + if (backend->reply->urlForLastAuthentication.isEmpty() + || url != backend->reply->urlForLastAuthentication) { QNetworkAuthenticationCredential *cred = fetchCachedCredentials(url, authenticator); if (cred) { authenticator->setUser(cred->user); @@ -1128,7 +1122,7 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend backend->reply->urlForLastAuthentication = url; emit q->authenticationRequired(backend->reply->q_func(), authenticator); - addCredentials(url, authenticator); + cacheCredentials(url, authenticator); } #ifndef QT_NO_NETWORKPROXY @@ -1145,7 +1139,7 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac // possible solution: some tracking inside the authenticator // or a new function proxyAuthenticationSucceeded(true|false) if (proxy != backend->reply->lastProxyAuthentication) { - QNetworkAuthenticationCredential *cred = fetchCachedCredentials(proxy); + QNetworkAuthenticationCredential *cred = fetchCachedProxyCredentials(proxy); if (cred) { authenticator->setUser(cred->user); authenticator->setPassword(cred->password); @@ -1155,10 +1149,10 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac backend->reply->lastProxyAuthentication = proxy; emit q->proxyAuthenticationRequired(proxy, authenticator); - addCredentials(proxy, authenticator); + cacheProxyCredentials(proxy, authenticator); } -void QNetworkAccessManagerPrivate::addCredentials(const QNetworkProxy &p, +void QNetworkAccessManagerPrivate::cacheProxyCredentials(const QNetworkProxy &p, const QAuthenticator *authenticator) { Q_ASSERT(authenticator); @@ -1195,7 +1189,7 @@ void QNetworkAccessManagerPrivate::addCredentials(const QNetworkProxy &p, } QNetworkAuthenticationCredential * -QNetworkAccessManagerPrivate::fetchCachedCredentials(const QNetworkProxy &p, +QNetworkAccessManagerPrivate::fetchCachedProxyCredentials(const QNetworkProxy &p, const QAuthenticator *authenticator) { QNetworkProxy proxy = p; @@ -1247,7 +1241,7 @@ QList<QNetworkProxy> QNetworkAccessManagerPrivate::queryProxy(const QNetworkProx } #endif -void QNetworkAccessManagerPrivate::addCredentials(const QUrl &url, +void QNetworkAccessManagerPrivate::cacheCredentials(const QUrl &url, const QAuthenticator *authenticator) { Q_ASSERT(authenticator); diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 695842c..2c6ee10 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -91,15 +91,15 @@ public: void createCookieJar() const; void authenticationRequired(QNetworkAccessBackend *backend, QAuthenticator *authenticator); - void addCredentials(const QUrl &url, const QAuthenticator *auth); + void cacheCredentials(const QUrl &url, const QAuthenticator *auth); QNetworkAuthenticationCredential *fetchCachedCredentials(const QUrl &url, const QAuthenticator *auth = 0); #ifndef QT_NO_NETWORKPROXY void proxyAuthenticationRequired(QNetworkAccessBackend *backend, const QNetworkProxy &proxy, QAuthenticator *authenticator); - void addCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth); - QNetworkAuthenticationCredential *fetchCachedCredentials(const QNetworkProxy &proxy, + void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth); + QNetworkAuthenticationCredential *fetchCachedProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth = 0); QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query); #endif diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index d3084cf..b761af5 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -194,16 +194,12 @@ QT_BEGIN_NAMESPACE \value CookieLoadControlAttribute Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) Indicates whether to send 'Cookie' headers in the request. - This attribute is set to false by QtWebKit when creating a cross-origin XMLHttpRequest where withCredentials has not been set explicitly to true by the Javascript that created the request. - See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag}{here} for more information. - (This value was introduced in 4.7.) - \value CookieSaveControlAttribute Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) Indicates whether to save 'Cookie' headers received from the server in reply @@ -211,9 +207,7 @@ QT_BEGIN_NAMESPACE This attribute is set to false by QtWebKit when creating a cross-origin XMLHttpRequest where withCredentials has not been set explicitly to true by the Javascript that created the request. - See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information. - (This value was introduced in 4.7.) \value AuthenticationReuseAttribute @@ -225,16 +219,12 @@ QT_BEGIN_NAMESPACE This attribute is set to QNetworkRequest::Manual by QtWebKit when creating a cross-origin XMLHttpRequest where withCredentials has not been set explicitly to true by the Javascript that created the request. - See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information. - (This value was introduced in 4.7.) \omitvalue MaximumDownloadBufferSizeAttribute - (This value was introduced in 4.7.) \omitvalue DownloadBufferAttribute - (This value was introduced in 4.7.) \value User Special type. Additional information can be passed in diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index f97d833..220f7da 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -232,19 +232,21 @@ void QAuthenticator::setUser(const QString &user) //domain name is present d->realm.clear(); d->userDomain = user.left(separatorPosn); - d->user = user.mid(separatorPosn + 1); + d->extractedUser = user.mid(separatorPosn + 1); + d->user = user; } else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) { //domain name is present d->realm.clear(); d->userDomain = user.left(separatorPosn); - d->user = user.left(separatorPosn); + d->extractedUser = user.left(separatorPosn); + d->user = user; } else { + d->extractedUser = user; d->user = user; d->realm.clear(); d->userDomain.clear(); } break; - // For other auth mechanisms, domain name will be part of username default: d->user = user; break; @@ -1196,7 +1198,7 @@ static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx, Q_ASSERT(hashKey.size() == 16); // Assuming the user and domain is always unicode in challenge QByteArray message = - qStringAsUcs2Le(ctx->user.toUpper()) + + qStringAsUcs2Le(ctx->extractedUser.toUpper()) + qStringAsUcs2Le(phase3->domainStr); phase3->v2Hash = qEncodeHmacMd5(hashKey, message); @@ -1401,8 +1403,8 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas pb.domainStr = ctx->userDomain; } - offset = qEncodeNtlmString(pb.user, offset, ctx->user, unicode); - pb.userStr = ctx->user; + offset = qEncodeNtlmString(pb.user, offset, ctx->extractedUser, unicode); + pb.userStr = ctx->extractedUser; offset = qEncodeNtlmString(pb.workstation, offset, ctx->workstation, unicode); pb.workstationStr = ctx->workstation; diff --git a/src/network/kernel/qauthenticator_p.h b/src/network/kernel/qauthenticator_p.h index 4e09360..9f2e607 100644 --- a/src/network/kernel/qauthenticator_p.h +++ b/src/network/kernel/qauthenticator_p.h @@ -71,6 +71,7 @@ public: QAtomicInt ref; QString user; + QString extractedUser; QString password; QVariantHash options; Method method; diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 505db71..f03d102 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1212,6 +1212,36 @@ void QAbstractSocketPrivate::fetchConnectionParameters() #endif } + +void QAbstractSocketPrivate::pauseSocketNotifiers(QAbstractSocket *socket) +{ + QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine; + if (!socketEngine) + return; + socket->d_func()->prePauseReadSocketNotifierState = socketEngine->isReadNotificationEnabled(); + socket->d_func()->prePauseWriteSocketNotifierState = socketEngine->isWriteNotificationEnabled(); + socket->d_func()->prePauseExceptionSocketNotifierState = socketEngine->isExceptionNotificationEnabled(); + socketEngine->setReadNotificationEnabled(false); + socketEngine->setWriteNotificationEnabled(false); + socketEngine->setExceptionNotificationEnabled(false); +} + +void QAbstractSocketPrivate::resumeSocketNotifiers(QAbstractSocket *socket) +{ + QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine; + if (!socketEngine) + return; + socketEngine->setReadNotificationEnabled(socket->d_func()->prePauseReadSocketNotifierState); + socketEngine->setWriteNotificationEnabled(socket->d_func()->prePauseWriteSocketNotifierState); + socketEngine->setExceptionNotificationEnabled(socket->d_func()->prePauseExceptionSocketNotifierState); +} + +QAbstractSocketEngine* QAbstractSocketPrivate::getSocketEngine(QAbstractSocket *socket) +{ + return socket->d_func()->socketEngine; +} + + /*! \internal Constructs a new abstract socket of type \a socketType. The \a diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h index b51c301..7fba0fe 100644 --- a/src/network/socket/qabstractsocket_p.h +++ b/src/network/socket/qabstractsocket_p.h @@ -158,6 +158,13 @@ public: QAbstractSocket::SocketState state; QAbstractSocket::SocketError socketError; + + bool prePauseReadSocketNotifierState; + bool prePauseWriteSocketNotifierState; + bool prePauseExceptionSocketNotifierState; + static void pauseSocketNotifiers(QAbstractSocket*); + static void resumeSocketNotifiers(QAbstractSocket*); + static QAbstractSocketEngine* getSocketEngine(QAbstractSocket*); }; QT_END_NAMESPACE diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp index 560f5f6..c218d89 100644 --- a/src/network/socket/qlocalserver_unix.cpp +++ b/src/network/socket/qlocalserver_unix.cpp @@ -119,7 +119,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) // subsequent call to accept will not block in any case // // This change can be removed once more generic fix to select thread - // syncronization problem is implemented. + // synchronization problem is implemented. int flags = fcntl(listenSocket, F_GETFL, 0); if (-1 == flags || -1 == (fcntl(listenSocket, F_SETFL, flags | O_NONBLOCK))) { diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 477ef45..c1a4cfc 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -733,7 +733,7 @@ int QNativeSocketEnginePrivate::nativeAccept() { int acceptedDescriptor = WSAAccept(socketDescriptor, 0,0,0,0); if (acceptedDescriptor != -1 && QAbstractEventDispatcher::instance()) { - // Becuase of WSAAsyncSelect() WSAAccept returns a non blocking socket + // Because of WSAAsyncSelect() WSAAccept returns a non blocking socket // with the same attributes as the listening socket including the current // WSAAsyncSelect(). To be able to change the socket to blocking mode the // WSAAsyncSelect() call must be cancled. diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index c9f421f..a752720 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -2035,6 +2035,20 @@ void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode) q->setReadBufferSize(readBufferMaxSize); } +void QSslSocketPrivate::pauseSocketNotifiers(QSslSocket *socket) +{ + if (!socket->d_func()->plainSocket) + return; + QAbstractSocketPrivate::pauseSocketNotifiers(socket->d_func()->plainSocket); +} + +void QSslSocketPrivate::resumeSocketNotifiers(QSslSocket *socket) +{ + if (!socket->d_func()->plainSocket) + return; + QAbstractSocketPrivate::resumeSocketNotifiers(socket->d_func()->plainSocket); +} + /*! \internal */ diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 72b3ef7..94f5f39 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -142,6 +142,8 @@ public: // The socket itself, including private slots. QTcpSocket *plainSocket; void createPlainSocket(QIODevice::OpenMode openMode); + static void pauseSocketNotifiers(QSslSocket*); + static void resumeSocketNotifiers(QSslSocket*); void _q_connectedSlot(); void _q_hostFoundSlot(); void _q_disconnectedSlot(); diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index a8b8911..184ceb4 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -170,13 +170,26 @@ bool QConnmanEngine::hasIdentifier(const QString &id) void QConnmanEngine::connectToId(const QString &id) { QMutexLocker locker(&mutex); - QConnmanConnectThread *thread; - thread = new QConnmanConnectThread(this); - thread->setServicePath(serviceFromId(id)); - thread->setIdentifier(id); - connect(thread,SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), - this,SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError))); - thread->start(); + QString servicePath = serviceFromId(id); + QConnmanServiceInterface serv(servicePath); + if(!serv.isValid()) { + emit connectionError(id, QBearerEngineImpl::InterfaceLookupError); + } else { + if(serv.getType() != "cellular") { + + serv.connect(); + } else { + QOfonoManagerInterface ofonoManager(0); + QString modemPath = ofonoManager.currentModem().path(); + QOfonoDataConnectionManagerInterface dc(modemPath,0); + foreach(const QDBusObjectPath dcPath,dc.getPrimaryContexts()) { + if(dcPath.path().contains(servicePath.section("_",-1))) { + QOfonoPrimaryDataContextInterface primaryContext(dcPath.path(),0); + primaryContext.setActive(true); + } + } + } + } } void QConnmanEngine::disconnectFromId(const QString &id) @@ -791,62 +804,6 @@ bool QConnmanEngine::requiresPolling() const return false; } - -QConnmanConnectThread::QConnmanConnectThread(QObject *parent) - :QThread(parent), - servicePath(), identifier() -{ -} - -QConnmanConnectThread::~QConnmanConnectThread() -{ -} - -void QConnmanConnectThread::stop() -{ - if(currentThread() != this) { - QMetaObject::invokeMethod(this, "quit", - Qt::QueuedConnection); - } else { - quit(); - } - wait(); -} - -void QConnmanConnectThread::run() -{ - QConnmanServiceInterface serv(servicePath); - if(!serv.isValid()) { - emit connectionError(identifier, QBearerEngineImpl::InterfaceLookupError); - } else { - if(serv.getType() != "cellular") { - serv.connect(); - } else { - QOfonoManagerInterface ofonoManager(0); - QString modemPath = ofonoManager.currentModem().path(); - QOfonoDataConnectionManagerInterface dc(modemPath,0); - foreach(const QDBusObjectPath dcPath,dc.getPrimaryContexts()) { - if(dcPath.path().contains(servicePath.section("_",-1))) { - QOfonoPrimaryDataContextInterface primaryContext(dcPath.path(),0); - primaryContext.setActive(true); - } - } - } - } -} - -void QConnmanConnectThread::setServicePath(const QString &path) -{ - QMutexLocker locker(&mutex); - servicePath = path; -} - -void QConnmanConnectThread::setIdentifier(const QString &id) -{ - QMutexLocker locker(&mutex); - identifier = id; -} - QT_END_NAMESPACE #endif // QT_NO_DBUS diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h index 569bbc7..2a2308f 100644 --- a/src/plugins/bearer/connman/qconnmanengine.h +++ b/src/plugins/bearer/connman/qconnmanengine.h @@ -59,14 +59,12 @@ #include <QMap> #include <QVariant> -#include <QtCore/qthread.h> #ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE -class QConnmanConnectThread; class QConnmanEngine : public QBearerEngineImpl { Q_OBJECT @@ -141,33 +139,8 @@ private: bool isRoamingAllowed(const QString &context); protected: bool requiresPolling() const; - QConnmanConnectThread *connThread; }; -class QConnmanConnectThread : public QThread -{ - Q_OBJECT - -public: - QConnmanConnectThread(QObject *parent = 0); - ~QConnmanConnectThread(); - bool keepRunning; - void stop(); - void setServicePath(const QString &path); - void setIdentifier(const QString &id); - -Q_SIGNALS: - void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error); - -protected: - void run(); - QString servicePath; - QString identifier; - -private: - QMutex mutex; - -}; QT_END_NAMESPACE diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 549a07a..46b6e80 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -79,7 +79,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) { QLatin1String(CONNMAN_MANAGER_PATH), QLatin1String(CONNMAN_MANAGER_INTERFACE), QLatin1String("PropertyChanged"), - this,SIGNAL(propertyChanged(const QString &, const QDBusVariant & )))) { + this,SIGNAL(propertyChanged(const QString &, const QDBusVariant & ))), Qt::UniqueConnection) { qWarning() << "PropertyCHanged not connected"; } } @@ -89,7 +89,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) { QLatin1String(CONNMAN_MANAGER_PATH), QLatin1String(CONNMAN_MANAGER_INTERFACE), QLatin1String("StateChanged"), - this,SIGNAL(stateChanged(const QString&)))) { + this,SIGNAL(stateChanged(const QString&))), Qt::UniqueConnection) { qWarning() << "StateChanged not connected"; } @@ -106,7 +106,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) { QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } @@ -338,7 +338,7 @@ void QConnmanNetworkInterface::connectNotify(const char *signal) this->path(), QLatin1String(CONNMAN_NETWORK_INTERFACE), QLatin1String("PropertyChanged"), - this,SIGNAL(propertyChanged(QString,QDBusVariant))) ) { + this,SIGNAL(propertyChanged(QString,QDBusVariant))), Qt::UniqueConnection) { qWarning() << "network properties not connected"; } } @@ -350,10 +350,10 @@ void QConnmanNetworkInterface::connectNotify(const char *signal) this->path(), QLatin1String(CONNMAN_NETWORK_INTERFACE), QLatin1String("PropertyChanged"), - helper,SLOT(propertyChanged(QString,QDBusVariant))); + helper,SLOT(propertyChanged(QString,QDBusVariant))), Qt::UniqueConnection; QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } @@ -538,7 +538,7 @@ void QConnmanServiceInterface::connectNotify(const char *signal) helper,SLOT(propertyChanged(QString,QDBusVariant))); QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } @@ -569,10 +569,9 @@ QVariant QConnmanServiceInterface::getProperty(const QString &property) return var; } -// clearProperty void QConnmanServiceInterface::connect() { - QDBusReply<QVariantMap> reply = this->call(QLatin1String("Connect")); + this->asyncCall(QLatin1String("Connect")); } void QConnmanServiceInterface::disconnect() @@ -866,7 +865,7 @@ void QConnmanTechnologyInterface::connectNotify(const char *signal) helper,SLOT(propertyChanged(QString,QDBusVariant))); QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } @@ -1031,7 +1030,7 @@ void QConnmanDeviceInterface::connectNotify(const char *signal) helper,SLOT(propertyChanged(QString,QDBusVariant))); QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } diff --git a/src/plugins/bearer/connman/qofonoservice_linux.cpp b/src/plugins/bearer/connman/qofonoservice_linux.cpp index 955f4b1..52f596b 100644 --- a/src/plugins/bearer/connman/qofonoservice_linux.cpp +++ b/src/plugins/bearer/connman/qofonoservice_linux.cpp @@ -262,7 +262,7 @@ void QOfonoModemInterface::connectNotify(const char *signal) QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); }} void QOfonoModemInterface::disconnectNotify(const char *signal) @@ -385,7 +385,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) { QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } @@ -483,7 +483,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) { QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } @@ -586,7 +586,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) { QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } @@ -675,7 +675,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) { QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } @@ -794,7 +794,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) { QObject::connect(helper,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), - this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &))); + this,SIGNAL(propertyChangedContext(const QString &,const QString &,const QDBusVariant &)), Qt::UniqueConnection); } } diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index f6390bb..f494106 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -1736,10 +1736,12 @@ QScriptValue QScriptValue::construct(const QScriptValueList &args) JSC::JSValue savedException; QScriptEnginePrivate::saveException(exec, &savedException); - JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs); + JSC::JSValue result; + JSC::JSObject *newObject = JSC::construct(exec, callee, constructType, constructData, jscArgs); if (exec->hadException()) { - result = JSC::asObject(exec->exception()); + result = exec->exception(); } else { + result = newObject; QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); @@ -1796,11 +1798,12 @@ QScriptValue QScriptValue::construct(const QScriptValue &arguments) JSC::JSValue savedException; QScriptEnginePrivate::saveException(exec, &savedException); - JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs); + JSC::JSValue result; + JSC::JSObject *newObject = JSC::construct(exec, callee, constructType, constructData, applyArgs); if (exec->hadException()) { - if (exec->exception().isObject()) - result = JSC::asObject(exec->exception()); + result = exec->exception(); } else { + result = newObject; QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); diff --git a/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp b/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp index 89f608e..4a32a5a 100644 --- a/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp +++ b/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp @@ -57,7 +57,7 @@ public: public Q_SLOTS: void finishedReply(); void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail); - void challenge401(const QHttpNetworkRequest &request, QAuthenticator *authenticator, const QHttpNetworkConnection *connection); + void challenge401(const QHttpNetworkRequest &request, QAuthenticator *authenticator); #ifndef QT_NO_OPENSSL void sslErrors(const QList<QSslError> &errors); #endif @@ -175,11 +175,9 @@ void tst_QHttpNetworkConnection::head() QFETCH(QString, statusString); QFETCH(int, contentLength); - QHttpNetworkConnection connection(host); + QHttpNetworkConnection connection(host, port, encrypt); QCOMPARE(connection.port(), port); QCOMPARE(connection.hostName(), host); - if (encrypt) - connection.enableEncryption(); QCOMPARE(connection.isEncrypted(), encrypt); QHttpNetworkRequest request(protocol + host + path, QHttpNetworkRequest::Head); @@ -235,11 +233,9 @@ void tst_QHttpNetworkConnection::get() QFETCH(int, contentLength); QFETCH(int, downloadSize); - QHttpNetworkConnection connection(host); + QHttpNetworkConnection connection(host, port, encrypt); QCOMPARE(connection.port(), port); QCOMPARE(connection.hostName(), host); - if (encrypt) - connection.enableEncryption(); QCOMPARE(connection.isEncrypted(), encrypt); QHttpNetworkRequest request(protocol + host + path); @@ -315,11 +311,9 @@ void tst_QHttpNetworkConnection::put() QFETCH(QString, data); QFETCH(bool, succeed); - QHttpNetworkConnection connection(host); + QHttpNetworkConnection connection(host, port, encrypt); QCOMPARE(connection.port(), port); QCOMPARE(connection.hostName(), host); - if (encrypt) - connection.enableEncryption(); QCOMPARE(connection.isEncrypted(), encrypt); QHttpNetworkRequest request(protocol + host + path, QHttpNetworkRequest::Put); @@ -336,8 +330,6 @@ void tst_QHttpNetworkConnection::put() connect(reply, SIGNAL(finished()), SLOT(finishedReply())); connect(reply, SIGNAL(finishedWithError(QNetworkReply::NetworkError, const QString &)), SLOT(finishedWithError(QNetworkReply::NetworkError, const QString &))); - connect(&connection, SIGNAL(error(QNetworkReply::NetworkError, const QString &)), - SLOT(finishedWithError(QNetworkReply::NetworkError, const QString &))); QTime stopWatch; stopWatch.start(); @@ -407,11 +399,9 @@ void tst_QHttpNetworkConnection::post() QFETCH(int, contentLength); QFETCH(int, downloadSize); - QHttpNetworkConnection connection(host); + QHttpNetworkConnection connection(host, port, encrypt); QCOMPARE(connection.port(), port); QCOMPARE(connection.hostName(), host); - if (encrypt) - connection.enableEncryption(); QCOMPARE(connection.isEncrypted(), encrypt); QHttpNetworkRequest request(protocol + host + path, QHttpNetworkRequest::Post); @@ -496,14 +486,14 @@ void tst_QHttpNetworkConnection::_connect() } void tst_QHttpNetworkConnection::challenge401(const QHttpNetworkRequest &request, - QAuthenticator *authenticator, - const QHttpNetworkConnection *connection) + QAuthenticator *authenticator) { Q_UNUSED(request) - Q_UNUSED(connection) - QHttpNetworkConnection *c = qobject_cast<QHttpNetworkConnection*>(sender()); - if (connection) { + QHttpNetworkReply *reply = qobject_cast<QHttpNetworkReply*>(sender()); + if (reply) { + QHttpNetworkConnection *c = reply->connection(); + QVariant val = c->property("setCredentials"); if (val.toBool()) { QVariant user = c->property("username"); @@ -549,17 +539,15 @@ void tst_QHttpNetworkConnection::get401() QHttpNetworkConnection connection(host, port, encrypt); QCOMPARE(connection.port(), port); QCOMPARE(connection.hostName(), host); - if (encrypt) - connection.enableEncryption(); QCOMPARE(connection.isEncrypted(), encrypt); - connect(&connection, SIGNAL(authenticationRequired(const QHttpNetworkRequest&, QAuthenticator *, const QHttpNetworkConnection*)), - SLOT(challenge401(const QHttpNetworkRequest&, QAuthenticator *, const QHttpNetworkConnection*))); connection.setProperty("setCredentials", setCredentials); connection.setProperty("username", username); connection.setProperty("password", password); QHttpNetworkRequest request(protocol + host + path); QHttpNetworkReply *reply = connection.sendRequest(request); + connect(reply, SIGNAL(authenticationRequired(const QHttpNetworkRequest&, QAuthenticator *)), + SLOT(challenge401(const QHttpNetworkRequest&, QAuthenticator *))); finishedCalled = false; finishedWithErrorCalled = false; @@ -618,11 +606,9 @@ void tst_QHttpNetworkConnection::compression() QFETCH(bool, autoCompress); QFETCH(QString, contentCoding); - QHttpNetworkConnection connection(host); + QHttpNetworkConnection connection(host, port, encrypt); QCOMPARE(connection.port(), port); QCOMPARE(connection.hostName(), host); - if (encrypt) - connection.enableEncryption(); QCOMPARE(connection.isEncrypted(), encrypt); QHttpNetworkRequest request(protocol + host + path); @@ -668,8 +654,10 @@ void tst_QHttpNetworkConnection::sslErrors(const QList<QSslError> &errors) { Q_UNUSED(errors) - QHttpNetworkConnection *connection = qobject_cast<QHttpNetworkConnection*>(sender()); - if (connection) { + QHttpNetworkReply *reply = qobject_cast<QHttpNetworkReply*>(sender()); + if (reply) { + QHttpNetworkConnection *connection = reply->connection(); + QVariant val = connection->property("ignoreFromSignal"); if (val.toBool()) connection->ignoreSslErrors(); @@ -711,17 +699,15 @@ void tst_QHttpNetworkConnection::ignoresslerror() QHttpNetworkConnection connection(host, port, encrypt); QCOMPARE(connection.port(), port); QCOMPARE(connection.hostName(), host); - if (encrypt) - connection.enableEncryption(); if (ignoreInit) connection.ignoreSslErrors(); QCOMPARE(connection.isEncrypted(), encrypt); - connect(&connection, SIGNAL(sslErrors(const QList<QSslError>&)), - SLOT(sslErrors(const QList<QSslError>&))); connection.setProperty("ignoreFromSignal", ignoreFromSignal); QHttpNetworkRequest request(protocol + host + path); QHttpNetworkReply *reply = connection.sendRequest(request); + connect(reply, SIGNAL(sslErrors(const QList<QSslError>&)), + SLOT(sslErrors(const QList<QSslError>&))); finishedWithErrorCalled = false; @@ -769,8 +755,6 @@ void tst_QHttpNetworkConnection::nossl() QHttpNetworkConnection connection(host, port, encrypt); QCOMPARE(connection.port(), port); QCOMPARE(connection.hostName(), host); - if (encrypt) - connection.enableEncryption(); QHttpNetworkRequest request(protocol + host + path); QHttpNetworkReply *reply = connection.sendRequest(request); diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp index 83a3388..639df36 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp @@ -2739,6 +2739,31 @@ void tst_QScriptValue::construct() QVERIFY(!QScriptValue(QScriptValue::NullValue).construct().isValid()); } +void tst_QScriptValue::construct_constructorThrowsPrimitive() +{ + QScriptEngine eng; + QScriptValue fun = eng.evaluate("(function() { throw 123; })"); + QVERIFY(fun.isFunction()); + // construct(QScriptValueList) + { + QScriptValue ret = fun.construct(); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toNumber(), 123.0); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(ret.strictlyEquals(eng.uncaughtException())); + eng.clearExceptions(); + } + // construct(QScriptValue) + { + QScriptValue ret = fun.construct(eng.newArray()); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toNumber(), 123.0); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(ret.strictlyEquals(eng.uncaughtException())); + eng.clearExceptions(); + } +} + void tst_QScriptValue::lessThan_old() { QScriptEngine eng; diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.h b/tests/auto/qscriptvalue/tst_qscriptvalue.h index 8bfaa6a..462749a 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.h +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.h @@ -219,6 +219,7 @@ private slots: void getSetScriptClass(); void call(); void construct(); + void construct_constructorThrowsPrimitive(); void castToPointer(); void prettyPrinter_data(); void prettyPrinter(); |