bug 1196882 - dont enforce h1 framing on non 2xx r=bagder
authorPatrick McManus <mcmanus@ducksong.com>
Fri, 28 Aug 2015 10:57:16 -0400
changeset 260504 9620db5a619d412bfd712d59242634fb53569266
parent 260503 3ae72a41c99eb082447194e3ddcaa25abc3644cb
child 260527 af087b6d30d70c00cdb902e3f902d399f2d0d71f
push id64515
push usermcmanus@ducksong.com
push dateWed, 02 Sep 2015 12:27:07 +0000
treeherdermozilla-inbound@9620db5a619d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbagder
bugs1196882
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1196882 - dont enforce h1 framing on non 2xx r=bagder
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
netwerk/test/unit/test_content_length_underrun.js
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -102,16 +102,17 @@ nsHttpTransaction::nsHttpTransaction()
     , mStatus(NS_OK)
     , mPriority(0)
     , mRestartCount(0)
     , mCaps(0)
     , mClassification(CLASS_GENERAL)
     , mPipelinePosition(0)
     , mCapsToClear(0)
     , mHttpVersion(NS_HTTP_VERSION_UNKNOWN)
+    , mHttpResponseCode(0)
     , mClosed(false)
     , mConnected(false)
     , mHaveStatusLine(false)
     , mHaveAllHeaders(false)
     , mTransactionDone(false)
     , mResponseIsComplete(false)
     , mDidContentStart(false)
     , mNoContent(false)
@@ -976,17 +977,18 @@ nsHttpTransaction::Close(nsresult reason
         }
     }
 
     if ((mChunkedDecoder || (mContentLength >= int64_t(0))) &&
         (NS_SUCCEEDED(reason) && !mResponseIsComplete)) {
 
         NS_WARNING("Partial transfer, incomplete HTTP response received");
 
-        if (mHttpVersion >= NS_HTTP_VERSION_1_1) {
+        if ((mHttpResponseCode / 100 == 2) &&
+            (mHttpVersion >= NS_HTTP_VERSION_1_1)) {
             FrameCheckLevel clevel = gHttpHandler->GetEnforceH1Framing();
             if (clevel >= FRAMECHECK_BARELY) {
                 if ((clevel == FRAMECHECK_STRICT) ||
                     (mChunkedDecoder && mChunkedDecoder->GetChunkRemaining()) ||
                     (!mChunkedDecoder && !mContentDecoding && mContentDecodingCheck) ) {
                     reason = NS_ERROR_NET_PARTIAL_TRANSFER;
                     LOG(("Partial transfer, incomplete HTTP response received: %s",
                          mChunkedDecoder ? "broken chunk" : "c-l underrun"));
@@ -1529,16 +1531,17 @@ nsHttpTransaction::HandleContentStart()
             mResponseHead->Flatten(headers, false);
             LogHeaders(headers.get());
             LOG3(("]\n"));
         }
 
         // Save http version, mResponseHead isn't available anymore after
         // TakeResponseHead() is called
         mHttpVersion = mResponseHead->Version();
+        mHttpResponseCode = mResponseHead->Status();
 
         // notify the connection, give it a chance to cause a reset.
         bool reset = false;
         if (!mRestartInProgressVerifier.IsSetup())
             mConnection->OnHeadersAvailable(this, mRequestHead, mResponseHead, &reset);
 
         // looks like we should ignore this response, resetting...
         if (reset) {
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -268,16 +268,17 @@ private:
     // redundant requests on the network. The member itself is atomic, but
     // access to it from the networking thread may happen either before or
     // after the main thread modifies it. To deal with raciness, only unsetting
     // bitfields should be allowed: 'lost races' will thus err on the
     // conservative side, e.g. by going ahead with a 2nd DNS refresh.
     Atomic<uint32_t>                mCapsToClear;
 
     nsHttpVersion                   mHttpVersion;
+    uint16_t                        mHttpResponseCode;
 
     // state flags, all logically boolean, but not packed together into a
     // bitfield so as to avoid bitfield-induced races.  See bug 560579.
     bool                            mClosed;
     bool                            mConnected;
     bool                            mHaveStatusLine;
     bool                            mHaveAllHeaders;
     bool                            mTransactionDone;
--- a/netwerk/test/unit/test_content_length_underrun.js
+++ b/netwerk/test/unit/test_content_length_underrun.js
@@ -121,16 +121,39 @@ function handler1(metadata, response)
   response.write(body);
   response.finish();
 }
 
 function completeTest1(request, data, ctx)
 {
   do_check_eq(request.status, Components.results.NS_ERROR_NET_PARTIAL_TRANSFER);
 
+  run_test_number(11);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test 11: PASS because of Content-Length underrun with HTTP 1.1 but non 2xx
+test_flags[11] = CL_IGNORE_CL;
+
+function handler11(metadata, response)
+{
+  var body = "blablabla";
+
+  response.seizePower();
+  response.write("HTTP/1.1 404 NotOK\r\n");
+  response.write("Content-Type: text/plain\r\n");
+  response.write("Content-Length: 556677\r\n");
+  response.write("\r\n");
+  response.write(body);
+  response.finish();
+}
+
+function completeTest11(request, data, ctx)
+{
+  do_check_eq(request.status, Components.results.NS_OK);
   run_test_number(2);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Test 2: Succeed because Content-Length underrun is with HTTP 1.0
 
 test_flags[2] = CL_IGNORE_CL;