--- a/src/network/access/qnetworkaccesshttpbackend.cpp Wed Jun 23 19:07:03 2010 +0300
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp Tue Jul 06 15:10:48 2010 +0300
@@ -213,6 +213,7 @@
case QNetworkAccessManager::HeadOperation:
case QNetworkAccessManager::PutOperation:
case QNetworkAccessManager::DeleteOperation:
+ case QNetworkAccessManager::CustomOperation:
break;
default:
@@ -296,6 +297,7 @@
#ifndef QT_NO_OPENSSL
, pendingSslConfiguration(0), pendingIgnoreAllSslErrors(false)
#endif
+ , resumeOffset(0)
{
}
@@ -344,6 +346,8 @@
#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
@@ -480,10 +484,24 @@
loadedFromCache = false;
}
+static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio)
+{
+ switch (prio) {
+ case QNetworkRequest::LowPriority:
+ return QHttpNetworkRequest::LowPriority;
+ case QNetworkRequest::HighPriority:
+ return QHttpNetworkRequest::HighPriority;
+ case QNetworkRequest::NormalPriority:
+ default:
+ return QHttpNetworkRequest::NormalPriority;
+ }
+}
+
void QNetworkAccessHttpBackend::postRequest()
{
bool loadedFromCache = false;
QHttpNetworkRequest httpRequest;
+ httpRequest.setPriority(convert(request().priority()));
switch (operation()) {
case QNetworkAccessManager::GetOperation:
httpRequest.setOperation(QHttpNetworkRequest::Get);
@@ -512,6 +530,14 @@
httpRequest.setOperation(QHttpNetworkRequest::Delete);
break;
+ case QNetworkAccessManager::CustomOperation:
+ invalidateCache(); // for safety reasons, we don't know what the operation does
+ httpRequest.setOperation(QHttpNetworkRequest::Custom);
+ httpRequest.setUploadByteDevice(createUploadByteDevice());
+ httpRequest.setCustomVerb(request().attribute(
+ QNetworkRequest::CustomVerbAttribute).toByteArray());
+ break;
+
default:
break; // can't happen
}
@@ -519,6 +545,28 @@
httpRequest.setUrl(url());
QList<QByteArray> headers = request().rawHeaderList();
+ if (resumeOffset != 0) {
+ if (headers.contains("Range")) {
+ // Need to adjust resume offset for user specified range
+
+ headers.removeOne("Range");
+
+ // We've already verified that requestRange starts with "bytes=", see canResume.
+ QByteArray requestRange = request().rawHeader("Range").mid(6);
+
+ int index = requestRange.indexOf('-');
+
+ quint64 requestStartOffset = requestRange.left(index).toULongLong();
+ quint64 requestEndOffset = requestRange.mid(index + 1).toULongLong();
+
+ requestRange = "bytes=" + QByteArray::number(resumeOffset + requestStartOffset) +
+ '-' + QByteArray::number(requestEndOffset);
+
+ httpRequest.setHeaderField("Range", requestRange);
+ } else {
+ httpRequest.setHeaderField("Range", "bytes=" + QByteArray::number(resumeOffset) + '-');
+ }
+ }
foreach (const QByteArray &header, headers)
httpRequest.setHeaderField(header, request().rawHeader(header));
@@ -532,6 +580,11 @@
if (request().attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool() == true)
httpRequest.setPipeliningAllowed(true);
+ if (static_cast<QNetworkRequest::LoadControl>
+ (request().attribute(QNetworkRequest::AuthenticationReuseAttribute,
+ QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Manual)
+ httpRequest.setWithCredentials(false);
+
httpReply = http->sendRequest(httpRequest);
httpReply->setParent(this);
#ifndef QT_NO_OPENSSL
@@ -815,6 +868,12 @@
authenticationRequired(auth);
}
+void QNetworkAccessHttpBackend::httpCacheCredentials(const QHttpNetworkRequest &,
+ QAuthenticator *auth)
+{
+ cacheCredentials(auth);
+}
+
void QNetworkAccessHttpBackend::httpError(QNetworkReply::NetworkError errorCode,
const QString &errorString)
{
@@ -1093,6 +1152,31 @@
return metaData;
}
+bool QNetworkAccessHttpBackend::canResume() const
+{
+ // Only GET operation supports resuming.
+ if (operation() != QNetworkAccessManager::GetOperation)
+ return false;
+
+ // Can only resume if server/resource supports Range header.
+ if (httpReply->headerField("Accept-Ranges", "none") == "none")
+ return false;
+
+ // We only support resuming for byte ranges.
+ if (request().hasRawHeader("Range")) {
+ QByteArray range = request().rawHeader("Range");
+ if (!range.startsWith("bytes="))
+ return false;
+ }
+
+ return true;
+}
+
+void QNetworkAccessHttpBackend::setResumeOffset(quint64 offset)
+{
+ resumeOffset = offset;
+}
+
QT_END_NAMESPACE
#endif // QT_NO_HTTP