summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron McCarthy <aaron.mccarthy@nokia.com>2010-02-08 07:37:48 (GMT)
committerAaron McCarthy <aaron.mccarthy@nokia.com>2010-02-08 07:50:14 (GMT)
commitc6157559204b61b11537ab0c0aba16eb182b09fe (patch)
treed4ac2c233c46a36f9e6e868ffcbb07374eb632bb /src
parent2963cb346814d47fd59e04bfd9bcd5fde88d5bd8 (diff)
downloadQt-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.cpp35
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h4
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp37
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h2
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;