Bug 958712 part 2/3 - Allow CONTINUATIONs in PUSH_PROMISEs r=mcmanus
authorNicholas Hurley <hurley@todesschaf.org>
Fri, 30 Jan 2015 11:35:20 -0800
changeset 227035 6a529065cc9e5ddbacf78258a8adc356ae398c48
parent 227034 a93ad0ca3442dc037597685c7a2c1caaae0dbcaa
child 227036 26ad04ac4ba3fd67eb00a0be506a58c6e1c30050
push id55003
push userhurley@todesschaf.org
push dateMon, 02 Feb 2015 20:13:14 +0000
treeherdermozilla-inbound@26ad04ac4ba3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs958712
milestone38.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 958712 part 2/3 - Allow CONTINUATIONs in PUSH_PROMISEs r=mcmanus
netwerk/protocol/http/Http2Session.cpp
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -1536,17 +1536,18 @@ Http2Session::RecvSettings(Http2Session 
   }
 
   return NS_OK;
 }
 
 nsresult
 Http2Session::RecvPushPromise(Http2Session *self)
 {
-  MOZ_ASSERT(self->mInputFrameType == FRAME_TYPE_PUSH_PROMISE);
+  MOZ_ASSERT(self->mInputFrameType == FRAME_TYPE_PUSH_PROMISE ||
+             self->mInputFrameType == FRAME_TYPE_CONTINUATION);
 
   // Find out how much padding this frame has, so we can only extract the real
   // header data from the frame.
   uint16_t paddingLength = 0;
   uint8_t paddingControlBytes = 0;
 
   // If this doesn't have END_PUSH_PROMISE set on it then require the next
   // frame to be PUSH_PROMISE of the same ID
@@ -1620,19 +1621,16 @@ Http2Session::RecvPushPromise(Http2Sessi
   } else if (!gHttpHandler->AllowPush()) {
     // ENABLE_PUSH and MAX_CONCURRENT_STREAMS of 0 in settings disabled push
     LOG3(("Http2Session::RecvPushPromise Push Recevied when Disabled\n"));
     if (self->mGoAwayOnPush) {
       LOG3(("Http2Session::RecvPushPromise sending GOAWAY"));
       RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
     }
     self->GenerateRstStream(REFUSED_STREAM_ERROR, promisedID);
-  } else if (!(self->mInputFrameFlags & kFlag_END_PUSH_PROMISE)) {
-    LOG3(("Http2Session::RecvPushPromise no support for multi frame push\n"));
-    self->GenerateRstStream(REFUSED_STREAM_ERROR, promisedID);
   } else if (!associatedStream) {
     LOG3(("Http2Session::RecvPushPromise %p lookup associated ID failed.\n", self));
     self->GenerateRstStream(PROTOCOL_ERROR, promisedID);
   } else {
     nsILoadGroupConnectionInfo *loadGroupCI = associatedStream->LoadGroupConnectionInfo();
     if (loadGroupCI) {
       loadGroupCI->GetSpdyPushCache(&cache);
       if (!cache) {
@@ -1664,26 +1662,32 @@ Http2Session::RecvPushPromise(Http2Sessi
         self->mGoAwayReason = COMPRESSION_ERROR;
         return rv;
       }
     }
     self->ResetDownstreamState();
     return NS_OK;
   }
 
+  self->mDecompressBuffer.Append(self->mInputFrameBuffer + kFrameHeaderBytes + paddingControlBytes + promiseLen,
+                                 self->mInputFrameDataSize - paddingControlBytes - promiseLen - paddingLength);
+
+  if (!(self->mInputFrameFlags & kFlag_END_PUSH_PROMISE)) {
+    LOG3(("Http2Session::RecvPushPromise not finishing processing for multi-frame push\n"));
+    self->ResetDownstreamState();
+    return NS_OK;
+  }
+
   // Create the buffering transaction and push stream
   nsRefPtr<Http2PushTransactionBuffer> transactionBuffer =
     new Http2PushTransactionBuffer();
   transactionBuffer->SetConnection(self);
   Http2PushedStream *pushedStream =
     new Http2PushedStream(transactionBuffer, self, associatedStream, promisedID);
 
-  self->mDecompressBuffer.Append(self->mInputFrameBuffer + kFrameHeaderBytes + paddingControlBytes + promiseLen,
-                                 self->mInputFrameDataSize - paddingControlBytes - promiseLen - paddingLength);
-
   rv = pushedStream->ConvertPushHeaders(&self->mDecompressor,
                                         self->mDecompressBuffer,
                                         pushedStream->GetRequestString());
 
   if (rv == NS_ERROR_NOT_IMPLEMENTED) {
     LOG3(("Http2Session::PushPromise Semantics not Implemented\n"));
     self->GenerateRstStream(REFUSED_STREAM_ERROR, promisedID);
     delete pushedStream;