QNam: try to read the last CRLF when chunked encoding is used.
authorMartin Petersson <Martin.Petersson@nokia.com>
Tue, 27 Mar 2012 08:29:57 +0000 (10:29 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 28 Mar 2012 11:22:11 +0000 (13:22 +0200)
When chunked encoding is used we should try to read the last CRLF after
the last zero-lenght chunk, with chunk size coded as 0.

Task-number: QTBUG-19480
Task-number: QTBUG-20924
Change-Id: Ida40593fec8788bff713a31cfe6a7c2d86354a91
Reviewed-by: Jonas Gastal <jgastal@profusion.mobi>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
src/network/access/qhttpnetworkreply.cpp
src/network/access/qhttpnetworkreply_p.h

index 85463ee..3920416 100644 (file)
@@ -257,6 +257,7 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
       chunkedTransferEncoding(false),
       connectionCloseEnabled(true),
       forceConnectionCloseEnabled(false),
+      lastChunkRead(false),
       currentChunkSize(0), currentChunkRead(0), connection(0),
       autoDecompress(false), responseData(), requestIsPrepared(false)
       ,pipeliningUsed(false), downstreamLimited(false)
@@ -277,6 +278,7 @@ void QHttpNetworkReplyPrivate::clearHttpLayerInformation()
     totalProgress = 0;
     currentChunkSize = 0;
     currentChunkRead = 0;
+    lastChunkRead = false;
     connectionCloseEnabled = true;
 #ifndef QT_NO_COMPRESS
     if (autoDecompress)
@@ -721,7 +723,7 @@ qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QAbstractSocket *socket, Q
 {
     qint64 bytes = 0;
     while (socket->bytesAvailable()) {
-        if (currentChunkRead >= currentChunkSize) {
+        if (!lastChunkRead && currentChunkRead >= currentChunkSize) {
             // For the first chunk and when we're done with a chunk
             currentChunkSize = 0;
             currentChunkRead = 0;
@@ -744,8 +746,23 @@ qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QAbstractSocket *socket, Q
                 break;
         }
         // if the chunk size is 0, end of the stream
-        if (currentChunkSize == 0) {
-            state = AllDoneState;
+        if (currentChunkSize == 0 || lastChunkRead) {
+            lastChunkRead = true;
+            // try to read the "\r\n" after the chunk
+            char crlf[2];
+            qint64 haveRead = socket->read(crlf, 2);
+            if (haveRead > 0)
+                bytes += haveRead;
+
+            if ((haveRead == 2 && crlf[0] == '\r' && crlf[1] == '\n') || (haveRead == 1 && crlf[0] == '\n'))
+                state = AllDoneState;
+            else if (haveRead == 1 && crlf[0] == '\r')
+                break; // Still waiting for the last \n
+            else if (haveRead > 0) {
+                // If we read something else then CRLF, we need to close the channel.
+                forceConnectionCloseEnabled = true;
+                state = AllDoneState;
+            }
             break;
         }
 
index 04e4569..97fefc6 100644 (file)
@@ -217,6 +217,7 @@ public:
     bool chunkedTransferEncoding;
     bool connectionCloseEnabled;
     bool forceConnectionCloseEnabled;
+    bool lastChunkRead;
     qint64 currentChunkSize;
     qint64 currentChunkRead;
     QPointer<QHttpNetworkConnection> connection;