diff options
author | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2010-02-08 07:37:48 (GMT) |
---|---|---|
committer | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2010-02-08 07:50:14 (GMT) |
commit | c6157559204b61b11537ab0c0aba16eb182b09fe (patch) | |
tree | d4ac2c233c46a36f9e6e868ffcbb07374eb632bb /src | |
parent | 2963cb346814d47fd59e04bfd9bcd5fde88d5bd8 (diff) | |
download | Qt-c6157559204b61b11537ab0c0aba16eb182b09fe.zip Qt-c6157559204b61b11537ab0c0aba16eb182b09fe.tar.gz Qt-c6157559204b61b11537ab0c0aba16eb182b09fe.tar.bz2 |
Automatically migrate in-progress transfers after roaming.
Automatically migrate in-progress transfers after roaming to a new
access point for backends that support it. Currently only works for http
transfers that do not upload data (i.e. HTTP GET).
Diffstat (limited to 'src')
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 35 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager_p.h | 4 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl.cpp | 37 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl_p.h | 2 |
4 files changed, 31 insertions, 47 deletions
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 617e398..8df580d 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -802,27 +802,6 @@ void QNetworkAccessManagerPrivate::_q_replyFinished() QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender()); if (reply) emit q->finished(reply); - - if (session && deferredMigration) { - foreach (QObject *child, q->children()) { - if (child == reply) - continue; - - QNetworkReplyImpl *replyImpl = qobject_cast<QNetworkReplyImpl *>(child); - if (!replyImpl) - continue; - - QNetworkReplyImplPrivate::State state = replyImpl->d_func()->state; - if (state == QNetworkReplyImplPrivate::Buffering || - state == QNetworkReplyImplPrivate::Working) { - return; - } - } - - deferredMigration = false; - qDebug() << "Migrating as there are no pending replies."; - session->migrate(); - } } void QNetworkAccessManagerPrivate::_q_replySslErrors(const QList<QSslError> &errors) @@ -1136,6 +1115,7 @@ void QNetworkAccessManagerPrivate::_q_sessionNewConfigurationActivated() { Q_Q(QNetworkAccessManager); +#if 0 foreach (QObject *child, q->children()) { QNetworkReplyImpl *reply = qobject_cast<QNetworkReplyImpl *>(child); if (reply) { @@ -1151,6 +1131,7 @@ void QNetworkAccessManagerPrivate::_q_sessionNewConfigurationActivated() } } } +#endif qDebug() << "Accepting new configuration."; session->accept(); @@ -1183,18 +1164,10 @@ void QNetworkAccessManagerPrivate::_q_sessionPreferredConfigurationChanged(const foreach (QObject *child, q->children()) { QNetworkReplyImpl *replyImpl = qobject_cast<QNetworkReplyImpl *>(child); - if (replyImpl) { - QNetworkReplyImplPrivate::State state = replyImpl->d_func()->state; - if (state == QNetworkReplyImplPrivate::Buffering || - state == QNetworkReplyImplPrivate::Working) { - deferredMigration = true; - return; - } - } + if (replyImpl) + replyImpl->migrateBackend(); } - deferredMigration = false; - qDebug() << "Migrating as there are no pending replies."; session->migrate(); } diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 92b2782..e916158 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -76,8 +76,7 @@ public: proxyFactory(0), #endif cookieJarCreated(false), - session(0), - deferredMigration(false) + session(0) { } ~QNetworkAccessManagerPrivate(); @@ -131,7 +130,6 @@ public: bool cookieJarCreated; QNetworkSession *session; - bool deferredMigration; // this cache can be used by individual backends to cache e.g. their TCP connections to a server // and use the connections for multiple requests. diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 0c7aca8..9721e32 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -477,6 +477,17 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) QPointer<QNetworkReplyImpl> qq = q; QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); + if (totalSize.isNull()) { + RawHeadersList::ConstIterator it = findRawHeader("Content-Range"); + if (it != rawHeaders.constEnd()) { + int index = it->second.lastIndexOf('/'); + if (index != -1) + totalSize = it->second.mid(index + 1).toLongLong() - preMigrationDownloaded; + } else { + qDebug() << "Could not find Content-Length or Content-Range header"; + } + } + if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; pauseNotificationHandling(); @@ -520,7 +531,8 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data) void QNetworkReplyImplPrivate::finished() { Q_Q(QNetworkReplyImpl); - if (state == Finished || state == Aborted) + + if (state == Finished || state == Aborted || state == WaitingForSession) return; pauseNotificationHandling(); @@ -540,11 +552,10 @@ void QNetworkReplyImplPrivate::finished() } else { qDebug() << "Download hasn't finished"; - if (q->bytesAvailable() == bytesDownloaded) { - qDebug() << "User hasn't read data from reply, we could continue after reconnect."; - error(QNetworkReply::TemporaryNetworkFailureError, q->tr("Temporary network failure.")); - } else if (q->bytesAvailable() < bytesDownloaded) { - qDebug() << "User has already read data from reply."; + if (migrateBackend()) { + return; + } else { + qDebug() << "Could not migrate backend, application needs to send another requeset."; error(QNetworkReply::TemporaryNetworkFailureError, q->tr("Temporary network failure.")); } } @@ -781,24 +792,24 @@ void QNetworkReplyImpl::migrateBackend() d->migrateBackend(); } -void QNetworkReplyImplPrivate::migrateBackend() +bool QNetworkReplyImplPrivate::migrateBackend() { Q_Q(QNetworkReplyImpl); if (state == QNetworkReplyImplPrivate::Finished || state == QNetworkReplyImplPrivate::Aborted) { qDebug() << "Network reply is already finished/aborted."; - return; + return false; } if (!qobject_cast<QNetworkAccessHttpBackend *>(backend)) { qDebug() << "Resume only support by http backend, not migrating."; - return; + return false; } if (outgoingData) { qDebug() << "Request has outgoing data, not migrating."; - return; + return false; } qDebug() << "Need to check for only cacheable content."; @@ -812,14 +823,14 @@ void QNetworkReplyImplPrivate::migrateBackend() state = QNetworkReplyImplPrivate::Reconnecting; if (backend) { - backend->deleteLater(); + delete backend; backend = 0; } RawHeadersList::ConstIterator it = findRawHeader("Accept-Ranges"); if (it == rawHeaders.constEnd() || it->second == "none") { qDebug() << "Range header not supported by server/resource."; - qFatal("Should fail with TemporaryNetworkFailure."); + return false; } cookedHeaders.clear(); @@ -841,6 +852,8 @@ void QNetworkReplyImplPrivate::migrateBackend() } else { QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); } + + return true; } QT_END_NAMESPACE diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index ac82ca0..89b976f 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -165,7 +165,7 @@ public: QIODevice *copyDevice; QAbstractNetworkCache *networkCache() const; - void migrateBackend(); + bool migrateBackend(); bool cacheEnabled; QIODevice *cacheSaveDevice; |