diff options
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 11 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 29 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel_p.h | 1 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply.cpp | 11 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply_p.h | 6 | ||||
-rw-r--r-- | src/network/access/qhttpthreaddelegate.cpp | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 72 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager_p.h | 14 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl.cpp | 19 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl_p.h | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl.cpp | 15 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl_p.h | 2 |
12 files changed, 151 insertions, 32 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index c2d986ef3d..c4cb8e65c0 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -326,7 +326,7 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair) QByteArray host; if (add.setAddress(hostName)) { if (add.protocol() == QAbstractSocket::IPv6Protocol) - host = "[" + hostName.toLatin1() + "]";//format the ipv6 in the standard way + host = '[' + hostName.toLatin1() + ']'; //format the ipv6 in the standard way else host = hostName.toLatin1(); @@ -888,8 +888,13 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) // if HTTP mandates we should close // or the reply is not finished yet, e.g. it was aborted // we have to close that connection - if (reply->d_func()->isConnectionCloseEnabled() || !reply->isFinished()) - channels[i].close(); + if (reply->d_func()->isConnectionCloseEnabled() || !reply->isFinished()) { + if (reply->isAborted()) { + channels[i].abort(); + } else { + channels[i].close(); + } + } QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); return; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 8980ed7a41..b4eda3477e 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -205,6 +205,26 @@ void QHttpNetworkConnectionChannel::close() } +void QHttpNetworkConnectionChannel::abort() +{ + if (!socket) + state = QHttpNetworkConnectionChannel::IdleState; + else if (socket->state() == QAbstractSocket::UnconnectedState) + state = QHttpNetworkConnectionChannel::IdleState; + else + state = QHttpNetworkConnectionChannel::ClosingState; + + // pendingEncrypt must only be true in between connected and encrypted states + pendingEncrypt = false; + + if (socket) { + // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while + // there is no socket yet. + socket->abort(); + } +} + + bool QHttpNetworkConnectionChannel::sendRequest() { Q_ASSERT(!protocolHandler.isNull()); @@ -252,7 +272,12 @@ bool QHttpNetworkConnectionChannel::ensureConnection() QAbstractSocket::SocketState socketState = socket->state(); // resend this request after we receive the disconnected signal - if (socketState == QAbstractSocket::ClosingState) { + // If !socket->isOpen() then we have already called close() on the socket, but there was still a + // pending connectToHost() for which we hadn't seen a connected() signal, yet. The connected() + // has now arrived (as indicated by socketState != ClosingState), but we cannot send anything on + // such a socket anymore. + if (socketState == QAbstractSocket::ClosingState || + (socketState != QAbstractSocket::UnconnectedState && !socket->isOpen())) { if (reply) resendCurrent = true; return false; @@ -1080,6 +1105,8 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors) connection->d_func()->pauseConnection(); if (pendingEncrypt && !reply) connection->d_func()->dequeueRequest(socket); + if (reply) // a reply was actually dequeued. + reply->d_func()->connectionChannel = this; // set correct channel like in sendRequest() and queueRequest(); if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP) { if (reply) emit reply->sslErrors(errors); diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 37ad6c9b0a..87329b7397 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -157,6 +157,7 @@ public: void init(); void close(); + void abort(); bool sendRequest(); diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index dd108ad5c7..a0f05523e3 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -264,6 +264,17 @@ char* QHttpNetworkReply::userProvidedDownloadBuffer() return d->userProvidedDownloadBuffer; } +void QHttpNetworkReply::abort() +{ + Q_D(QHttpNetworkReply); + d->state = QHttpNetworkReplyPrivate::Aborted; +} + +bool QHttpNetworkReply::isAborted() const +{ + return d_func()->state == QHttpNetworkReplyPrivate::Aborted; +} + bool QHttpNetworkReply::isFinished() const { return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState; diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 6e81663500..e8ed73fdac 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -121,6 +121,9 @@ public: void setUserProvidedDownloadBuffer(char*); char* userProvidedDownloadBuffer(); + void abort(); + + bool isAborted() const; bool isFinished() const; bool isPipeliningUsed() const; @@ -214,7 +217,8 @@ public: SPDYSYNSent, SPDYUploading, SPDYHalfClosed, - SPDYClosed + SPDYClosed, + Aborted } state; QHttpNetworkRequest request; diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 3fc4fa9dee..c07064fd94 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -396,6 +396,7 @@ void QHttpThreadDelegate::abortRequest() qDebug() << "QHttpThreadDelegate::abortRequest() thread=" << QThread::currentThreadId() << "sync=" << synchronous; #endif if (httpReply) { + httpReply->abort(); delete httpReply; httpReply = 0; } diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index e6fb1a09a0..086140f967 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -278,7 +278,8 @@ static void ensureInitialized() \snippet code/src_network_access_qnetworkaccessmanager.cpp 4 - Network requests can be reenabled again by calling + Network requests can be re-enabled again, and this property will resume to + reflect the actual device state by calling \snippet code/src_network_access_qnetworkaccessmanager.cpp 5 @@ -467,16 +468,12 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) #ifndef QT_NO_BEARERMANAGEMENT Q_D(QNetworkAccessManager); - if (!d->networkSessionRequired) { - // if a session is required, we track online state through - // the QNetworkSession's signals - connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), - SLOT(_q_onlineStateChanged(bool))); - } - // we would need all active configurations to check for - // d->networkConfigurationManager.isOnline(), which is asynchronous - // and potentially expensive. We can just check the configuration here - d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active); + // if a session is required, we track online state through + // the QNetworkSession's signals if a request is already made. + // we need to track current accessibility state by default + // + connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), + SLOT(_q_onlineStateChanged(bool))); #endif } @@ -946,7 +943,8 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkAccessibility accessible) { Q_D(QNetworkAccessManager); - d->defaultAccessControl = false; + + d->defaultAccessControl = accessible == NotAccessible ? false : true; if (d->networkAccessible != accessible) { NetworkAccessibility previous = networkAccessible(); @@ -965,6 +963,10 @@ void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkA QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccessible() const { Q_D(const QNetworkAccessManager); + + if (d->networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) + return UnknownAccessibility; + if (d->networkSessionRequired) { QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession()); if (networkSession) { @@ -1622,32 +1624,56 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession if (online) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { online = false; - networkAccessible = QNetworkAccessManager::NotAccessible; - emit q->networkAccessibleChanged(networkAccessible); + if (networkAccessible != QNetworkAccessManager::NotAccessible) { + networkAccessible = QNetworkAccessManager::NotAccessible; + emit q->networkAccessibleChanged(networkAccessible); + } } } else { if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { online = true; if (defaultAccessControl) - networkAccessible = QNetworkAccessManager::Accessible; - emit q->networkAccessibleChanged(networkAccessible); + if (networkAccessible != QNetworkAccessManager::Accessible) { + networkAccessible = QNetworkAccessManager::Accessible; + emit q->networkAccessibleChanged(networkAccessible); + } } } } void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) { - // if the user set a config, we only care whether this one is active. + Q_Q(QNetworkAccessManager); + // if the user set a config, we only care whether this one is active. // Otherwise, this QNAM is online if there is an online config. if (customNetworkConfiguration) { online = (networkConfiguration.state() & QNetworkConfiguration::Active); } else { - if (isOnline && online != isOnline) { - networkSessionStrongRef.clear(); - networkSessionWeakRef.clear(); + if (online != isOnline) { + if (isOnline) { + networkSessionStrongRef.clear(); + networkSessionWeakRef.clear(); + } + online = isOnline; + } + } + if (online) { + if (defaultAccessControl) { + if (networkAccessible != QNetworkAccessManager::Accessible) { + networkAccessible = QNetworkAccessManager::Accessible; + emit q->networkAccessibleChanged(networkAccessible); + } + } + } else if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) { + if (networkAccessible != QNetworkAccessManager::UnknownAccessibility) { + networkAccessible = QNetworkAccessManager::UnknownAccessibility; + emit q->networkAccessibleChanged(networkAccessible); + } + } else { + if (networkAccessible != QNetworkAccessManager::NotAccessible) { + networkAccessible = QNetworkAccessManager::NotAccessible; + emit q->networkAccessibleChanged(networkAccessible); } - - online = isOnline; } } @@ -1678,7 +1704,7 @@ QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkReq break; } // putting the boundary into quotes, recommended in RFC 2046 section 5.1.1 - contentType += "; boundary=\"" + multiPart->d_func()->boundary + "\""; + contentType += "; boundary=\"" + multiPart->d_func()->boundary + '"'; newRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType)); } diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index c715da00c1..54ae114581 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -78,7 +78,6 @@ public: customNetworkConfiguration(false), networkSessionRequired(networkConfigurationManager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired), - networkAccessible(QNetworkAccessManager::Accessible), activeReplyCount(0), online(false), initializeSession(true), @@ -86,7 +85,18 @@ public: cookieJarCreated(false), defaultAccessControl(true), authenticationManager(QSharedPointer<QNetworkAccessAuthenticationManager>::create()) - { } + { +#ifndef QT_NO_BEARERMANAGEMENT + // we would need all active configurations to check for + // d->networkConfigurationManager.isOnline(), which is asynchronous + // and potentially expensive. We can just check the configuration here + online = (networkConfiguration.state().testFlag(QNetworkConfiguration::Active)); + if (online) + networkAccessible = QNetworkAccessManager::Accessible; + else + networkAccessible = QNetworkAccessManager::NotAccessible; +#endif + } ~QNetworkAccessManagerPrivate(); void _q_replyFinished(); diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 8c0c098147..63fca2bda2 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1238,7 +1238,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData if (statusCode == 304) { #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) - qDebug() << "Received a 304 from" << url(); + qDebug() << "Received a 304 from" << request.url(); #endif QAbstractNetworkCache *nc = managerPrivate->networkCache; if (nc) { @@ -1562,7 +1562,7 @@ QNetworkCacheMetaData QNetworkReplyHttpImplPrivate::fetchCacheMetaData(const QNe } #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) - QByteArray n = rawHeader(header); + QByteArray n = q->rawHeader(header); QByteArray o; if (it != cacheHeaders.rawHeaders.constEnd()) o = (*it).second; @@ -1782,6 +1782,11 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; #endif + } else { +#ifndef QT_NO_BEARERMANAGEMENT + QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); +#endif } if (synchronous) { @@ -1950,6 +1955,16 @@ void QNetworkReplyHttpImplPrivate::_q_networkSessionConnected() } } +void QNetworkReplyHttpImplPrivate::_q_networkSessionStateChanged(QNetworkSession::State sessionState) +{ + if (sessionState == QNetworkSession::Disconnected + && (state != Idle || state != Reconnecting)) { + error(QNetworkReplyImpl::NetworkSessionFailedError, + QCoreApplication::translate("QNetworkReply", "Network session error.")); + finished(); + } +} + void QNetworkReplyHttpImplPrivate::_q_networkSessionFailed() { // Abort waiting and working replies. diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index fff88f8f2d..44d51d82a4 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -96,6 +96,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies)) #endif Q_PRIVATE_SLOT(d_func(), void _q_finished()) @@ -171,6 +172,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT void _q_networkSessionConnected(); void _q_networkSessionFailed(); + void _q_networkSessionStateChanged(QNetworkSession::State); void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies); #endif void _q_finished(); diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index a73e0ea75e..c73e6162d1 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -125,6 +125,11 @@ void QNetworkReplyImplPrivate::_q_startOperation() finished(); #endif return; + } else { +#ifndef QT_NO_BEARERMANAGEMENT + QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); +#endif } #ifndef QT_NO_BEARERMANAGEMENT @@ -309,6 +314,16 @@ void QNetworkReplyImplPrivate::_q_networkSessionConnected() } } +void QNetworkReplyImplPrivate::_q_networkSessionStateChanged(QNetworkSession::State sessionState) +{ + if (sessionState == QNetworkSession::Disconnected + && (state != Idle || state != Reconnecting)) { + error(QNetworkReplyImpl::NetworkSessionFailedError, + QCoreApplication::translate("QNetworkReply", "Network session error.")); + finished(); + } +} + void QNetworkReplyImplPrivate::_q_networkSessionFailed() { // Abort waiting and working replies. diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index 3e720ef597..209bf40b72 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -89,6 +89,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies)) #endif @@ -122,6 +123,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT void _q_networkSessionConnected(); void _q_networkSessionFailed(); + void _q_networkSessionStateChanged(QNetworkSession::State); void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies); #endif |