QNAM HTTP: Do zero-copy for small HTTP replies by default
authorMarkus Goetz <Markus.Goetz@nokia.com>
Tue, 12 Jul 2011 10:45:02 +0000 (12:45 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 12 Jul 2011 11:57:14 +0000 (13:57 +0200)
Task-Number: QTBUG-19046

Change-Id: I34bf432c81d94787524124b7d110a00305a660c1
Reviewed-on: http://codereview.qt.nokia.com/1516
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Petersson <Martin.Petersson@nokia.com>
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
src/network/access/qhttpnetworkconnectionchannel.cpp
src/network/access/qhttpnetworkreply.cpp
src/network/access/qnetworkreplyhttpimpl.cpp

index b8ed8ee..aafdbf7 100644 (file)
@@ -448,12 +448,17 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
                // the buffer in that size.
                // note that this call will read only from the still buffered data
                qint64 haveRead = replyPrivate->readBodyVeryFast(socket, replyPrivate->userProvidedDownloadBuffer + replyPrivate->totalProgress);
-               bytes += haveRead;
-               replyPrivate->totalProgress += haveRead;
-
-               // the user will get notified of it via progress signal
-               if (haveRead > 0)
+               if (haveRead > 0) {
+                   bytes += haveRead;
+                   replyPrivate->totalProgress += haveRead;
+                   // the user will get notified of it via progress signal
                    emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
+               } else if (haveRead == 0) {
+                   // Happens since this called in a loop. Currently no bytes available.
+               } else if (haveRead < 0) {
+                   connection->d_func()->emitReplyError(socket, reply, QNetworkReply::RemoteHostClosedError);
+                   break;
+               }
            } else if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress
                  && replyPrivate->bodyLength > 0) {
                  // bulk files like images should fulfill these properties and
index 00653b6..04bcd06 100644 (file)
@@ -211,7 +211,7 @@ void QHttpNetworkReply::setDownstreamLimited(bool dsl)
 bool QHttpNetworkReply::supportsUserProvidedDownloadBuffer()
 {
     Q_D(QHttpNetworkReply);
-    return (!d->isChunked() && !d->autoDecompress && d->bodyLength > 0);
+    return (!d->isChunked() && !d->autoDecompress && d->bodyLength > 0 && d->statusCode == 200);
 }
 
 void QHttpNetworkReply::setUserProvidedDownloadBuffer(char* b)
@@ -672,7 +672,7 @@ qint64 QHttpNetworkReplyPrivate::readBodyVeryFast(QAbstractSocket *socket, char
     qint64 haveRead = 0;
     haveRead = socket->read(b, bodyLength - contentRead);
     if (haveRead == -1) {
-        return 0; // ### error checking here;
+        return -1;
     }
     contentRead += haveRead;
 
index df0a32d..52cbaae 100644 (file)
@@ -777,8 +777,16 @@ void QNetworkReplyHttpImplPrivate::postRequest()
 
     if (!synchronous) {
         // Tell our zerocopy policy to the delegate
-        delegate->downloadBufferMaximumSize =
-                request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute).toLongLong();
+        QVariant downloadBufferMaximumSizeAttribute = request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute);
+        if (downloadBufferMaximumSizeAttribute.isValid()) {
+            delegate->downloadBufferMaximumSize = downloadBufferMaximumSizeAttribute.toLongLong();
+        } else {
+            // If there is no MaximumDownloadBufferSizeAttribute set (which is for the majority
+            // of QNetworkRequest) then we can assume we'll do it anyway for small HTTP replies.
+            // This helps with performance and memory fragmentation.
+            delegate->downloadBufferMaximumSize = 128*1024;
+        }
+
 
         // These atomic integers are used for signal compression
         delegate->pendingDownloadData = pendingDownloadDataEmissions;