bug 1204614 - backout 0bf012ea842f on aurora (gecko 43) r=backout a=lizzard
authorPatrick McManus <mcmanus@ducksong.com>
Thu, 08 Oct 2015 15:34:03 -0400
changeset 298071 9eff48aef36afba02753193fd1f44caf9fe080b6
parent 298070 725efd9e78e05c59afcd40a857074d15af4754a4
child 298072 b1e93301c3cfea89f7e38bdcb1f3244200af784c
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout, lizzard
bugs1204614
milestone43.0a2
bug 1204614 - backout 0bf012ea842f on aurora (gecko 43) r=backout a=lizzard
modules/libpref/init/all.js
netwerk/ipc/NeckoChannelParams.ipdlh
netwerk/protocol/http/ASpdySession.h
netwerk/protocol/http/Http2Session.cpp
netwerk/protocol/http/Http2Session.h
netwerk/protocol/http/Http2Stream.cpp
netwerk/protocol/http/Http2Stream.h
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/nsAHttpConnection.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
netwerk/protocol/http/nsIHttpChannelInternal.idl
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1402,18 +1402,17 @@ pref("network.http.spdy.enforce-tls-prof
 pref("network.http.spdy.chunk-size", 16000);
 pref("network.http.spdy.timeout", 180);
 pref("network.http.spdy.coalesce-hostnames", true);
 pref("network.http.spdy.persistent-settings", false);
 pref("network.http.spdy.ping-threshold", 58);
 pref("network.http.spdy.ping-timeout", 8);
 pref("network.http.spdy.send-buffer-size", 131072);
 pref("network.http.spdy.allow-push", true);
-pref("network.http.spdy.push-allowance", 131072);   // 128KB
-pref("network.http.spdy.pull-allowance", 12582912); // 12MB
+pref("network.http.spdy.push-allowance", 131072);
 pref("network.http.spdy.default-concurrent", 100);
 
 // alt-svc allows separation of transport routing from
 // the origin host without using a proxy.
 pref("network.http.altsvc.enabled", true);
 pref("network.http.altsvc.oe", true);
 
 pref("network.http.diagnostics", false);
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -103,17 +103,16 @@ struct HttpChannelOpenArgs
   bool                        allowAltSvc;
   OptionalFileDescriptorSet   fds;
   OptionalLoadInfoArgs        loadInfo;
   OptionalHttpResponseHead    synthesizedResponseHead;
   nsCString                   synthesizedSecurityInfoSerialization;
   uint32_t                    cacheKey;
   nsCString                   schedulingContextID;
   OptionalCorsPreflightArgs   preflightArgs;
-  uint32_t                    initialRwin;
 };
 
 struct HttpChannelConnectArgs
 {
   uint32_t channelId;
   bool shouldIntercept;
 };
 
--- a/netwerk/protocol/http/ASpdySession.h
+++ b/netwerk/protocol/http/ASpdySession.h
@@ -46,19 +46,21 @@ public:
     return true;
   }
 
   virtual void SendPing() = 0;
 
   const static uint32_t kSendingChunkSize = 4095;
   const static uint32_t kTCPSendBufferSize = 131072;
 
-  // This is roughly the amount of data a suspended channel will have to
-  // buffer before h2 flow control kicks in.
-  const static uint32_t kInitialRwin = 12 * 1024 * 1024; // 12MB
+  // until we have an API that can push back on receiving data (right now
+  // WriteSegments is obligated to accept data and buffer) there is no
+  // reason to throttle with the rwin other than in server push
+  // scenarios.
+  const static uint32_t kInitialRwin = 256 * 1024 * 1024;
 
   const static uint32_t kDefaultMaxConcurrent = 100;
 
   // soft errors are errors that terminate a stream without terminating the
   // connection. In general non-network errors are stream errors as well
   // as network specific items like cancels.
   bool SoftStreamError(nsresult code)
   {
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -99,17 +99,16 @@ Http2Session::Http2Session(nsISocketTran
   , mPeerGoAwayReason(UNASSIGNED)
   , mGoAwayID(0)
   , mOutgoingGoAwayID(0)
   , mConcurrent(0)
   , mServerPushedResources(0)
   , mServerInitialStreamWindow(kDefaultRwin)
   , mLocalSessionWindow(kDefaultRwin)
   , mServerSessionWindow(kDefaultRwin)
-  , mInitialRwin(ASpdySession::kInitialRwin)
   , mOutputQueueSize(kDefaultQueueSize)
   , mOutputQueueUsed(0)
   , mOutputQueueSent(0)
   , mLastReadEpoch(PR_IntervalNow())
   , mPingSentEpoch(0)
   , mPreviousUsed(false)
   , mWaitingForSettingsAck(false)
   , mGoAwayOnPush(false)
@@ -123,17 +122,16 @@ Http2Session::Http2Session(nsISocketTran
   LOG3(("Http2Session::Http2Session %p serial=0x%X\n", this, mSerial));
 
   mInputFrameBuffer = new char[mInputFrameBufferSize];
   mOutputQueueBuffer = new char[mOutputQueueSize];
   mDecompressBuffer.SetCapacity(kDefaultBufferSize);
   mDecompressor.SetCompressor(&mCompressor);
 
   mPushAllowance = gHttpHandler->SpdyPushAllowance();
-  mInitialRwin = std::max(gHttpHandler->SpdyPullAllowance(), mPushAllowance);
   mMaxConcurrent = gHttpHandler->DefaultSpdyConcurrent();
   mSendingChunkSize = gHttpHandler->SpdySendingChunkSize();
   SendHello();
 
   mLastDataReadEpoch = mLastReadEpoch;
 
   mPingThreshold = gHttpHandler->SpdyPingThreshold();
   mPreviousPingThreshold = mPingThreshold;
@@ -891,20 +889,20 @@ Http2Session::SendHello()
   MOZ_ASSERT(numberOfEntries <= maxSettings);
   uint32_t dataLen = 6 * numberOfEntries;
   CreateFrameHeader(packet, dataLen, FRAME_TYPE_SETTINGS, 0, 0);
   mOutputQueueUsed += kFrameHeaderBytes + dataLen;
 
   LogIO(this, nullptr, "Generate Settings", packet, kFrameHeaderBytes + dataLen);
 
   // now bump the local session window from 64KB
-  uint32_t sessionWindowBump = mInitialRwin - kDefaultRwin;
-  if (kDefaultRwin < mInitialRwin) {
+  uint32_t sessionWindowBump = ASpdySession::kInitialRwin - kDefaultRwin;
+  if (kDefaultRwin < ASpdySession::kInitialRwin) {
     // send a window update for the session (Stream 0) for something large
-    mLocalSessionWindow = mInitialRwin;
+    mLocalSessionWindow = ASpdySession::kInitialRwin;
 
     packet = mOutputQueueBuffer.get() + mOutputQueueUsed;
     CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, 0);
     mOutputQueueUsed += kFrameHeaderBytes + 4;
     NetworkEndian::writeUint32(packet + kFrameHeaderBytes, sessionWindowBump);
 
     LOG3(("Session Window increase at start of session %p %u\n",
           this, sessionWindowBump));
@@ -1106,18 +1104,17 @@ static void RemoveStreamFromQueue(Http2S
   }
 }
 
 void
 Http2Session::RemoveStreamFromQueues(Http2Stream *aStream)
 {
   RemoveStreamFromQueue(aStream, mReadyForWrite);
   RemoveStreamFromQueue(aStream, mQueuedStreams);
-  RemoveStreamFromQueue(aStream, mPushesReadyForRead);
-  RemoveStreamFromQueue(aStream, mSlowConsumersReadyForRead);
+  RemoveStreamFromQueue(aStream, mReadyForRead);
 }
 
 void
 Http2Session::CloseStream(Http2Stream *aStream, nsresult aResult)
 {
   MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
   LOG3(("Http2Session::CloseStream %p %p 0x%x %X\n",
         this, aStream, aStream->StreamID(), aResult));
@@ -2457,30 +2454,45 @@ Http2Session::WriteSegments(nsAHttpSegme
     return rv;
 
   SetWriteCallbacks();
 
   // If there are http transactions attached to a push stream with filled buffers
   // trigger that data pump here. This only reads from buffers (not the network)
   // so mDownstreamState doesn't matter.
   Http2Stream *pushConnectedStream =
-    static_cast<Http2Stream *>(mPushesReadyForRead.PopFront());
+    static_cast<Http2Stream *>(mReadyForRead.PopFront());
   if (pushConnectedStream) {
-    return ProcessConnectedPush(pushConnectedStream, writer, count, countWritten);
-  }
-
-  // feed gecko channels that previously stopped consuming data
-  // only take data from stored buffers
-  Http2Stream *slowConsumer =
-    static_cast<Http2Stream *>(mSlowConsumersReadyForRead.PopFront());
-  if (slowConsumer) {
-    internalStateType savedState = mDownstreamState;
-    mDownstreamState = NOT_USING_NETWORK;
-    rv = ProcessSlowConsumer(slowConsumer, writer, count, countWritten);
-    mDownstreamState = savedState;
+    LOG3(("Http2Session::WriteSegments %p processing pushed stream 0x%X\n",
+          this, pushConnectedStream->StreamID()));
+    mSegmentWriter = writer;
+    rv = pushConnectedStream->WriteSegments(this, count, countWritten);
+    mSegmentWriter = nullptr;
+
+    // The pipe in nsHttpTransaction rewrites CLOSED error codes into OK
+    // so we need this check to determine the truth.
+    if (NS_SUCCEEDED(rv) && !*countWritten &&
+        pushConnectedStream->PushSource() &&
+        pushConnectedStream->PushSource()->GetPushComplete()) {
+      rv = NS_BASE_STREAM_CLOSED;
+    }
+
+    if (rv == NS_BASE_STREAM_CLOSED) {
+      CleanupStream(pushConnectedStream, NS_OK, CANCEL_ERROR);
+      rv = NS_OK;
+    }
+
+    // if we return OK to nsHttpConnection it will use mSocketInCondition
+    // to determine whether to schedule more reads, incorrectly
+    // assuming that nsHttpConnection::OnSocketWrite() was called.
+    if (NS_SUCCEEDED(rv) || rv == NS_BASE_STREAM_WOULD_BLOCK) {
+      rv = NS_BASE_STREAM_WOULD_BLOCK;
+      ResumeRecv();
+    }
+
     return rv;
   }
 
   // The BUFFERING_OPENING_SETTINGS state is just like any BUFFERING_FRAME_HEADER
   // except the only frame type it will allow is SETTINGS
 
   // The session layer buffers the leading 8 byte header of every frame.
   // Non-Data frames are then buffered for their full length, but data
@@ -2819,79 +2831,16 @@ Http2Session::WriteSegments(nsAHttpSegme
              mDownstreamState != BUFFERING_CONTROL_FRAME,
              "Control Handler returned OK but did not change state");
 
   if (mShouldGoAway && !mStreamTransactionHash.Count())
     Close(NS_OK);
   return rv;
 }
 
-nsresult
-Http2Session::ProcessConnectedPush(Http2Stream *pushConnectedStream,
-                                   nsAHttpSegmentWriter * writer,
-                                   uint32_t count, uint32_t *countWritten)
-{
-  LOG3(("Http2Session::ProcessConnectedPush %p 0x%X\n",
-        this, pushConnectedStream->StreamID()));
-  mSegmentWriter = writer;
-  nsresult rv = pushConnectedStream->WriteSegments(this, count, countWritten);
-  mSegmentWriter = nullptr;
-
-  // The pipe in nsHttpTransaction rewrites CLOSED error codes into OK
-  // so we need this check to determine the truth.
-  if (NS_SUCCEEDED(rv) && !*countWritten &&
-      pushConnectedStream->PushSource() &&
-      pushConnectedStream->PushSource()->GetPushComplete()) {
-    rv = NS_BASE_STREAM_CLOSED;
-  }
-
-  if (rv == NS_BASE_STREAM_CLOSED) {
-    CleanupStream(pushConnectedStream, NS_OK, CANCEL_ERROR);
-    rv = NS_OK;
-  }
-
-  // if we return OK to nsHttpConnection it will use mSocketInCondition
-  // to determine whether to schedule more reads, incorrectly
-  // assuming that nsHttpConnection::OnSocketWrite() was called.
-  if (NS_SUCCEEDED(rv) || rv == NS_BASE_STREAM_WOULD_BLOCK) {
-    rv = NS_BASE_STREAM_WOULD_BLOCK;
-    ResumeRecv();
-  }
-  return rv;
-}
-
-nsresult
-Http2Session::ProcessSlowConsumer(Http2Stream *slowConsumer,
-                                  nsAHttpSegmentWriter * writer,
-                                  uint32_t count, uint32_t *countWritten)
-{
-  LOG3(("Http2Session::ProcessSlowConsumer %p 0x%X\n",
-        this, slowConsumer->StreamID()));
-  mSegmentWriter = writer;
-  nsresult rv = slowConsumer->WriteSegments(this, count, countWritten);
-  mSegmentWriter = nullptr;
-  LOG3(("Http2Session::ProcessSlowConsumer Writesegments %p 0x%X rv %X %d\n",
-        this, slowConsumer->StreamID(), rv, *countWritten));
-  if (NS_SUCCEEDED(rv) && !*countWritten && slowConsumer->RecvdFin()) {
-    rv = NS_BASE_STREAM_CLOSED;
-  }
-
-  if (NS_SUCCEEDED(rv)) {
-    UpdateLocalRwin(slowConsumer, 0);
-    ConnectSlowConsumer(slowConsumer);
-  }
-
-  if (rv == NS_BASE_STREAM_CLOSED) {
-    CleanupStream(slowConsumer, NS_OK, CANCEL_ERROR);
-    rv = NS_OK;
-  }
-
-  return rv;
-}
-
 void
 Http2Session::UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes)
 {
   if (!stream) // this is ok - it means there was a data frame for a rst stream
     return;
 
   // If this data packet was not for a valid or live stream then there
   // is no reason to mess with the flow control
@@ -2956,22 +2905,22 @@ Http2Session::UpdateLocalSessionWindow(u
 
   mLocalSessionWindow -= bytes;
 
   LOG3(("Http2Session::UpdateLocalSessionWindow this=%p newbytes=%u "
         "localWindow=%lld\n", this, bytes, mLocalSessionWindow));
 
   // Don't necessarily ack every data packet. Only do it
   // after a significant amount of data.
-  if ((mLocalSessionWindow > (mInitialRwin - kMinimumToAck)) &&
+  if ((mLocalSessionWindow > (ASpdySession::kInitialRwin - kMinimumToAck)) &&
       (mLocalSessionWindow > kEmergencyWindowThreshold))
     return;
 
   // Only send max  bits of window updates at a time.
-  uint64_t toack64 = mInitialRwin - mLocalSessionWindow;
+  uint64_t toack64 = ASpdySession::kInitialRwin - mLocalSessionWindow;
   uint32_t toack = (toack64 <= 0x7fffffffU) ? toack64 : 0x7fffffffU;
 
   LOG3(("Http2Session::UpdateLocalSessionWindow Ack this=%p acksize=%u\n",
         this, toack));
   mLocalSessionWindow += toack;
 
   if (toack == 0) {
     // Ensure we never send an illegal 0 window update
@@ -3172,20 +3121,16 @@ Http2Session::OnWriteSegment(char *buf,
   nsresult rv;
 
   if (!mSegmentWriter) {
     // the only way this could happen would be if Close() were called on the
     // stack with WriteSegments()
     return NS_ERROR_FAILURE;
   }
 
-  if (mDownstreamState == NOT_USING_NETWORK) {
-    return NS_BASE_STREAM_WOULD_BLOCK;
-  }
-
   if (mDownstreamState == PROCESSING_DATA_FRAME) {
 
     if (mInputFrameFinal &&
         mInputFrameDataRead == mInputFrameDataSize) {
       *countWritten = 0;
       SetNeedsCleanup();
       return NS_BASE_STREAM_CLOSED;
     }
@@ -3273,26 +3218,17 @@ Http2Session::SetNeedsCleanup()
   MOZ_ASSERT(!mNeedsCleanup, "mNeedsCleanup unexpectedly set");
   mNeedsCleanup = mInputFrameDataStream;
   ResetDownstreamState();
 }
 
 void
 Http2Session::ConnectPushedStream(Http2Stream *stream)
 {
-  mPushesReadyForRead.Push(stream);
-  ForceRecv();
-}
-
-void
-Http2Session::ConnectSlowConsumer(Http2Stream *stream)
-{
-  LOG3(("Http2Session::ConnectSlowConsumer %p 0x%X\n",
-        this, stream->StreamID()));
-  mSlowConsumersReadyForRead.Push(stream);
+  mReadyForRead.Push(stream);
   ForceRecv();
 }
 
 uint32_t
 Http2Session::FindTunnelCount(nsHttpConnectionInfo *aConnInfo)
 {
   MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
   uint32_t rv = 0;
@@ -3538,35 +3474,17 @@ Http2Session::TransactionHasDataToWrite(
 
   mReadyForWrite.Push(stream);
   SetWriteCallbacks();
 
   // NSPR poll will not poll the network if there are non system PR_FileDesc's
   // that are ready - so we can get into a deadlock waiting for the system IO
   // to come back here if we don't force the send loop manually.
   ForceSend();
-}
-
-void
-Http2Session::TransactionHasDataToRecv(nsAHttpTransaction *caller)
-{
-  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-  LOG3(("Http2Session::TransactionHasDataToRecv %p trans=%p", this, caller));
-
-  // a signal from the http transaction to the connection that it will consume more
-  Http2Stream *stream = mStreamTransactionHash.Get(caller);
-  if (!stream || !VerifyStream(stream)) {
-    LOG3(("Http2Session::TransactionHasDataToRecv %p caller %p not found",
-          this, caller));
-    return;
-  }
-
-  LOG3(("Http2Session::TransactionHasDataToRecv %p ID is 0x%X\n",
-        this, stream->StreamID()));
-  ConnectSlowConsumer(stream);
+
 }
 
 void
 Http2Session::TransactionHasDataToWrite(Http2Stream *stream)
 {
   MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
   LOG3(("Http2Session::TransactionHasDataToWrite %p stream=%p ID=0x%x",
         this, stream, stream->StreamID()));
--- a/netwerk/protocol/http/Http2Session.h
+++ b/netwerk/protocol/http/Http2Session.h
@@ -187,50 +187,47 @@ public:
   void CreateFrameHeader(charType dest, uint16_t frameLength,
                          uint8_t frameType, uint8_t frameFlags,
                          uint32_t streamID);
 
   // For writing the data stream to LOG4
   static void LogIO(Http2Session *, Http2Stream *, const char *,
                     const char *, uint32_t);
 
-  // overload of nsAHttpConnection
+  // an overload of nsAHttpConnection
   void TransactionHasDataToWrite(nsAHttpTransaction *) override;
-  void TransactionHasDataToRecv(nsAHttpTransaction *) override;
 
   // a similar version for Http2Stream
   void TransactionHasDataToWrite(Http2Stream *);
 
   // an overload of nsAHttpSegementReader
   virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) override;
   nsresult BufferOutput(const char *, uint32_t, uint32_t *);
   void     FlushOutputQueue();
   uint32_t AmountOfOutputBuffered() { return mOutputQueueUsed - mOutputQueueSent; }
 
   uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
 
   bool TryToActivate(Http2Stream *stream);
   void ConnectPushedStream(Http2Stream *stream);
-  void ConnectSlowConsumer(Http2Stream *stream);
 
   nsresult ConfirmTLSProfile();
   static bool ALPNCallback(nsISupports *securityInfo);
 
   uint64_t Serial() { return mSerial; }
 
   void PrintDiagnostics (nsCString &log) override;
 
   // Streams need access to these
   uint32_t SendingChunkSize() { return mSendingChunkSize; }
   uint32_t PushAllowance() { return mPushAllowance; }
   Http2Compressor *Compressor() { return &mCompressor; }
   nsISocketTransport *SocketTransport() { return mSocketTransport; }
   int64_t ServerSessionWindow() { return mServerSessionWindow; }
   void DecrementServerSessionWindow (uint32_t bytes) { mServerSessionWindow -= bytes; }
-  uint32_t InitialRwin() { return mInitialRwin; }
 
   void SendPing() override;
   bool MaybeReTunnel(nsAHttpTransaction *) override;
   bool UseH2Deps() { return mUseH2Deps; }
 
 private:
 
   // These internal states do not correspond to the states of the HTTP/2 specification
@@ -238,18 +235,17 @@ private:
     BUFFERING_OPENING_SETTINGS,
     BUFFERING_FRAME_HEADER,
     BUFFERING_CONTROL_FRAME,
     PROCESSING_DATA_FRAME_PADDING_CONTROL,
     PROCESSING_DATA_FRAME,
     DISCARDING_DATA_FRAME_PADDING,
     DISCARDING_DATA_FRAME,
     PROCESSING_COMPLETE_HEADERS,
-    PROCESSING_CONTROL_RST_STREAM,
-    NOT_USING_NETWORK
+    PROCESSING_CONTROL_RST_STREAM
   };
 
   static const uint8_t kMagicHello[24];
 
   nsresult    ResponseHeadersComplete();
   uint32_t    GetWriteQueueSize();
   void        ChangeDownstreamState(enum internalStateType);
   void        ResetDownstreamState();
@@ -266,21 +262,16 @@ private:
   void        SendHello();
   void        RemoveStreamFromQueues(Http2Stream *);
   nsresult    ParsePadding(uint8_t &, uint16_t &);
 
   void        SetWriteCallbacks();
   void        RealignOutputQueue();
 
   void        ProcessPending();
-  nsresult    ProcessConnectedPush(Http2Stream *, nsAHttpSegmentWriter *,
-                                   uint32_t, uint32_t *);
-  nsresult    ProcessSlowConsumer(Http2Stream *, nsAHttpSegmentWriter *,
-                                  uint32_t, uint32_t *);
-
   nsresult    SetInputFrameDataStream(uint32_t);
   void        CreatePriorityNode(uint32_t, uint32_t, uint8_t, const char *);
   bool        VerifyStream(Http2Stream *, uint32_t);
   void        SetNeedsCleanup();
 
   void        UpdateLocalRwin(Http2Stream *stream, uint32_t bytes);
   void        UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes);
   void        UpdateLocalSessionWindow(uint32_t bytes);
@@ -339,18 +330,17 @@ private:
   // by the nsClassHashtable implementation when they are removed from
   // the transaction hash.
   nsDataHashtable<nsUint32HashKey, Http2Stream *>     mStreamIDHash;
   nsClassHashtable<nsPtrHashKey<nsAHttpTransaction>,
     Http2Stream>                                      mStreamTransactionHash;
 
   nsDeque                                             mReadyForWrite;
   nsDeque                                             mQueuedStreams;
-  nsDeque                                             mPushesReadyForRead;
-  nsDeque                                             mSlowConsumersReadyForRead;
+  nsDeque                                             mReadyForRead;
   nsTArray<Http2PushedStream *>                       mPushedStreams;
 
   // Compression contexts for header transport.
   // HTTP/2 compresses only HTTP headers and does not reset the context in between
   // frames. Even data that is not associated with a stream (e.g invalid
   // stream ID) is passed through these contexts to keep the compression
   // context correct.
   Http2Compressor     mCompressor;
@@ -457,19 +447,16 @@ private:
   // signed because asynchronous changes via SETTINGS can drive it negative.
   int64_t              mLocalSessionWindow;
 
   // The Remote Session Window is how much data the client is allowed to send
   // (across all streams) without receiving a window update to stream 0. It is
   // signed because asynchronous changes via SETTINGS can drive it negative.
   int64_t              mServerSessionWindow;
 
-  // The initial value of the local stream and session window
-  uint32_t             mInitialRwin;
-
   // This is a output queue of bytes ready to be written to the SSL stream.
   // When that streams returns WOULD_BLOCK on direct write the bytes get
   // coalesced together here. This results in larger writes to the SSL layer.
   // The buffer is not dynamically grown to accomodate stream writes, but
   // does expand to accept infallible session wide frames like GoAway and RST.
   uint32_t             mOutputQueueSize;
   uint32_t             mOutputQueueUsed;
   uint32_t             mOutputQueueSent;
--- a/netwerk/protocol/http/Http2Stream.cpp
+++ b/netwerk/protocol/http/Http2Stream.cpp
@@ -22,17 +22,16 @@
 #include "TunnelUtils.h"
 
 #include "mozilla/Telemetry.h"
 #include "nsAlgorithm.h"
 #include "nsHttp.h"
 #include "nsHttpHandler.h"
 #include "nsHttpRequestHead.h"
 #include "nsIClassOfService.h"
-#include "nsIPipe.h"
 #include "nsISocketTransport.h"
 #include "nsStandardURL.h"
 #include "prnetdb.h"
 
 #ifdef DEBUG
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 #endif
@@ -59,17 +58,16 @@ Http2Stream::Http2Stream(nsAHttpTransact
   , mRequestBlockedOnRead(0)
   , mRecvdFin(0)
   , mRecvdReset(0)
   , mSentReset(0)
   , mCountAsActive(0)
   , mSentFin(0)
   , mSentWaitingFor(0)
   , mSetTCPSocketBuffer(0)
-  , mBypassInputBuffer(0)
   , mTxInlineFrameSize(Http2Session::kDefaultBufferSize)
   , mTxInlineFrameUsed(0)
   , mTxStreamFrameSize(0)
   , mRequestBodyLenRemaining(0)
   , mLocalUnacked(0)
   , mBlockedOnRwin(false)
   , mTotalSent(0)
   , mTotalRead(0)
@@ -233,79 +231,16 @@ Http2Stream::ReadSegments(nsAHttpSegment
   default:
     MOZ_ASSERT(false, "Http2Stream::ReadSegments unknown state");
     break;
   }
 
   return rv;
 }
 
-static bool
-IsDataAvailable(nsIInputStream *stream)
-{
-  if (!stream) {
-    return false;
-  }
-  uint64_t avail;
-  if (NS_FAILED(stream->Available(&avail))) {
-    return false;
-  }
-  return (avail > 0);
-}
-
-uint64_t
-Http2Stream::LocalUnAcked()
-{
-  // reduce unacked by the amount of undelivered data
-  // to help assert flow control
-  uint64_t undelivered = 0;
-  if (mInputBufferIn) {
-    mInputBufferIn->Available(&undelivered);
-  }
-
-  if (undelivered > mLocalUnacked) {
-    return 0;
-  }
-  return mLocalUnacked - undelivered;
-}
-
-nsresult
-Http2Stream::BufferInput(uint32_t count, uint32_t *countWritten)
-{
-  static const uint32_t segmentSize = 32768;
-  char buf[segmentSize];
-
-  count = std::min(segmentSize, count);
-  if (!mInputBufferOut) {
-    NS_NewPipe(getter_AddRefs(mInputBufferIn), getter_AddRefs(mInputBufferOut),
-               segmentSize, UINT32_MAX);
-    if (!mInputBufferOut) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-  }
-  mBypassInputBuffer = 1;
-  nsresult rv = mSegmentWriter->OnWriteSegment(buf, count, countWritten);
-  mBypassInputBuffer = 0;
-  if (NS_SUCCEEDED(rv)) {
-    uint32_t buffered;
-    rv = mInputBufferOut->Write(buf, *countWritten, &buffered);
-    if (NS_SUCCEEDED(rv) && (buffered != *countWritten)) {
-      rv = NS_ERROR_OUT_OF_MEMORY;
-    }
-  }
-  return rv;
-}
-
-bool
-Http2Stream::DeferCleanup(nsresult status)
-{
-  // do not cleanup a stream that has data buffered for the transaction
-  return (NS_SUCCEEDED(status) && IsDataAvailable(mInputBufferIn));
-}
-
 // WriteSegments() is used to read data off the socket. Generally this is
 // just a call through to the associated nsHttpTransaction for this stream
 // for the remaining data bytes indicated by the current DATA frame.
 
 nsresult
 Http2Stream::WriteSegments(nsAHttpSegmentWriter *writer,
                            uint32_t count,
                            uint32_t *countWritten)
@@ -313,26 +248,18 @@ Http2Stream::WriteSegments(nsAHttpSegmen
   MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
   MOZ_ASSERT(!mSegmentWriter, "segment writer in progress");
 
   LOG3(("Http2Stream::WriteSegments %p count=%d state=%x",
         this, count, mUpstreamState));
 
   mSegmentWriter = writer;
   nsresult rv = mTransaction->WriteSegments(this, count, countWritten);
+  mSegmentWriter = nullptr;
 
-  if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
-    // consuming transaction won't take data. but we need to read it into a buffer so that it
-    // won't block other streams. but we should not advance the flow control window
-    // so that we'll eventually push back on the sender.
-
-    // stash this data
-    rv = BufferInput(count, countWritten);
-  }
-  mSegmentWriter = nullptr;
   return rv;
 }
 
 nsresult
 Http2Stream::MakeOriginURL(const nsACString &origin, nsRefPtr<nsStandardURL> &url)
 {
   nsAutoCString scheme;
   nsresult rv = net_ExtractURLScheme(origin, nullptr, nullptr, &scheme);
@@ -691,47 +618,36 @@ Http2Stream::AdjustInitialWindow()
       return;
   }
 
   if (stream->mState == RESERVED_BY_REMOTE) {
     // h2-14 prevents sending a window update in this state
     return;
   }
 
-  // right now mClientReceiveWindow is the lower push limit
-  // bump it up to the pull limit set by the channel or session
-  // don't allow windows less than push
-  uint32_t bump = 0;
-  nsHttpTransaction *trans = mTransaction->QueryHttpTransaction();
-  if (trans && trans->InitialRwin()) {
-    bump = (trans->InitialRwin() > mClientReceiveWindow) ?
-      (trans->InitialRwin() - mClientReceiveWindow) : 0;
-  } else {
-    MOZ_ASSERT(mSession->InitialRwin() >= mClientReceiveWindow);
-    bump = mSession->InitialRwin() - mClientReceiveWindow;
-  }
-
-  LOG3(("AdjustInitialwindow increased flow control window %p 0x%X %u\n",
-        this, stream->mStreamID, bump));
+  MOZ_ASSERT(mClientReceiveWindow <= ASpdySession::kInitialRwin);
+  uint32_t bump = ASpdySession::kInitialRwin - mClientReceiveWindow;
   if (!bump) { // nothing to do
     return;
   }
 
   uint8_t *packet = mTxInlineFrame.get() + mTxInlineFrameUsed;
   EnsureBuffer(mTxInlineFrame, mTxInlineFrameUsed + Http2Session::kFrameHeaderBytes + 4,
                mTxInlineFrameUsed, mTxInlineFrameSize);
   mTxInlineFrameUsed += Http2Session::kFrameHeaderBytes + 4;
 
   mSession->CreateFrameHeader(packet, 4,
                               Http2Session::FRAME_TYPE_WINDOW_UPDATE,
                               0, stream->mStreamID);
 
   mClientReceiveWindow += bump;
   bump = PR_htonl(bump);
   memcpy(packet + Http2Session::kFrameHeaderBytes, &bump, 4);
+  LOG3(("AdjustInitialwindow increased flow control window %p 0x%X\n",
+        this, stream->mStreamID));
 }
 
 void
 Http2Stream::AdjustPushedPriority()
 {
   // >0 even numbered IDs are pushed streams. odd numbered IDs are pulled streams.
   // 0 is the sink for a pushed stream.
 
@@ -1397,44 +1313,26 @@ Http2Stream::OnWriteSegment(char *buf,
                             uint32_t *countWritten)
 {
   LOG3(("Http2Stream::OnWriteSegment %p count=%d state=%x 0x%X\n",
         this, count, mUpstreamState, mStreamID));
 
   MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
   MOZ_ASSERT(mSegmentWriter);
 
-  if (mPushSource) {
-    nsresult rv;
-    rv = mPushSource->GetBufferedData(buf, count, countWritten);
-    if (NS_FAILED(rv))
-      return rv;
-
-    mSession->ConnectPushedStream(this);
-    return NS_OK;
-  }
+  if (!mPushSource)
+    return mSegmentWriter->OnWriteSegment(buf, count, countWritten);
 
-  // sometimes we have read data from the network and stored it in a pipe
-  // so that other streams can proceed when the gecko caller is not processing
-  // data events fast enough and flow control hasn't caught up yet. This
-  // gets the stored data out of that pipe
-  if (!mBypassInputBuffer && IsDataAvailable(mInputBufferIn)) {
-    nsresult rv = mInputBufferIn->Read(buf, count, countWritten);
-    LOG3(("Http2Stream::OnWriteSegment read from flow control buffer %p %x %d\n",
-          this, mStreamID, *countWritten));
-    if (!IsDataAvailable(mInputBufferIn)) {
-      // drop the pipe if we don't need it anymore
-      mInputBufferIn = nullptr;
-      mInputBufferOut = nullptr;
-    }
+  nsresult rv;
+  rv = mPushSource->GetBufferedData(buf, count, countWritten);
+  if (NS_FAILED(rv))
     return rv;
-  }
 
-  // read from the network
-  return mSegmentWriter->OnWriteSegment(buf, count, countWritten);
+  mSession->ConnectPushedStream(this);
+  return NS_OK;
 }
 
 /// connect tunnels
 
 void
 Http2Stream::ClearTransactionsBlockedOnTunnel()
 {
   MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
--- a/netwerk/protocol/http/Http2Stream.h
+++ b/netwerk/protocol/http/Http2Stream.h
@@ -47,17 +47,17 @@ public:
   uint32_t StreamID() { return mStreamID; }
   Http2PushedStream *PushSource() { return mPushSource; }
 
   stateType HTTPState() { return mState; }
   void SetHTTPState(stateType val) { mState = val; }
 
   virtual nsresult ReadSegments(nsAHttpSegmentReader *,  uint32_t, uint32_t *);
   virtual nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *);
-  virtual bool DeferCleanup(nsresult status);
+  virtual bool DeferCleanup(nsresult status) { return false; }
 
   // The consumer stream is the synthetic pull stream hooked up to this stream
   // http2PushedStream overrides it
   virtual Http2Stream *GetConsumerStream() { return nullptr; };
 
   const nsAFlatCString &Origin() const { return mOrigin; }
   const nsAFlatCString &Host() const { return mHeaderHost; }
   const nsAFlatCString &Path() const { return mHeaderPath; }
@@ -119,17 +119,17 @@ public:
     mLocalUnacked += delta;
   }
 
   void IncrementClientReceiveWindow(uint32_t delta) {
     mClientReceiveWindow += delta;
     mLocalUnacked -= delta;
   }
 
-  uint64_t LocalUnAcked();
+  uint64_t LocalUnAcked() { return mLocalUnacked; }
   int64_t  ClientReceiveWindow()  { return mClientReceiveWindow; }
 
   bool     BlockedOnRwin() { return mBlockedOnRwin; }
 
   uint32_t Priority() { return mPriority; }
   void SetPriority(uint32_t);
   void SetPriorityDependency(uint32_t, uint8_t, bool);
   void UpdatePriorityDependency();
@@ -205,18 +205,16 @@ private:
   nsresult ParseHttpRequestHeaders(const char *, uint32_t, uint32_t *);
   nsresult GenerateOpen();
 
   void     AdjustPushedPriority();
   void     AdjustInitialWindow();
   nsresult TransmitFrame(const char *, uint32_t *, bool forceCommitment);
   void     GenerateDataFrameHeader(uint32_t, bool);
 
-  nsresult BufferInput(uint32_t , uint32_t *);
-
   // The underlying HTTP transaction. This pointer is used as the key
   // in the Http2Session mStreamTransactionHash so it is important to
   // keep a reference to it as long as this stream is a member of that hash.
   // (i.e. don't change it or release it after it is set in the ctor).
   nsRefPtr<nsAHttpTransaction> mTransaction;
 
   // The underlying socket transport object is needed to propogate some events
   nsISocketTransport         *mSocketTransport;
@@ -255,20 +253,16 @@ private:
   uint32_t                     mSentFin              : 1;
 
   // Flag is set after the WAITING_FOR Transport event has been generated
   uint32_t                     mSentWaitingFor       : 1;
 
   // Flag is set after TCP send autotuning has been disabled
   uint32_t                     mSetTCPSocketBuffer   : 1;
 
-  // Flag is set when OnWriteSegment is being called directly from stream instead
-  // of transaction
-  uint32_t                     mBypassInputBuffer   : 1;
-
   // The InlineFrame and associated data is used for composing control
   // frames and data frame headers.
   nsAutoArrayPtr<uint8_t>      mTxInlineFrame;
   uint32_t                     mTxInlineFrameSize;
   uint32_t                     mTxInlineFrameUsed;
 
   // mTxStreamFrameSize tracks the progress of
   // transmitting a request body data frame. The data frame itself
@@ -313,21 +307,16 @@ private:
 
   // For Progress Events
   uint64_t                     mTotalSent;
   uint64_t                     mTotalRead;
 
   // For Http2Push
   Http2PushedStream *mPushSource;
 
-  // A pipe used to store stream data when the transaction cannot keep up
-  // and flow control has not yet kicked in.
-  nsCOMPtr<nsIInputStream> mInputBufferIn;
-  nsCOMPtr<nsIOutputStream> mInputBufferOut;
-
 /// connect tunnels
 public:
   bool IsTunnel() { return mIsTunnel; }
 private:
   void ClearTransactionsBlockedOnTunnel();
   void MapStreamToPlainText();
   void MapStreamToHttpConnection();
 
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -74,17 +74,16 @@ HttpBaseChannel::HttpBaseChannel()
   , mTimingEnabled(false)
   , mAllowSpdy(true)
   , mAllowAltSvc(true)
   , mResponseTimeoutEnabled(true)
   , mAllRedirectsSameOrigin(true)
   , mAllRedirectsPassTimingAllowCheck(true)
   , mResponseCouldBeSynthesized(false)
   , mSuspendCount(0)
-  , mInitialRwin(0)
   , mProxyResolveFlags(0)
   , mProxyURI(nullptr)
   , mContentDispositionHint(UINT32_MAX)
   , mHttpHandler(gHttpHandler)
   , mReferrerPolicy(REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE)
   , mRedirectCount(0)
   , mForcePending(false)
   , mCorsIncludeCredentials(false)
@@ -2053,34 +2052,16 @@ HttpBaseChannel::GetResponseTimeoutEnabl
 NS_IMETHODIMP
 HttpBaseChannel::SetResponseTimeoutEnabled(bool aEnable)
 {
   mResponseTimeoutEnabled = aEnable;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HttpBaseChannel::GetInitialRwin(uint32_t *aRwin)
-{
-  if (NS_WARN_IF(!aRwin)) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  *aRwin = mInitialRwin;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-HttpBaseChannel::SetInitialRwin(uint32_t aRwin)
-{
-  ENSURE_CALLED_BEFORE_CONNECT();
-  mInitialRwin = aRwin;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 HttpBaseChannel::ForcePending(bool aForcePending)
 {
   mForcePending = aForcePending;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetLastModifiedTime(PRTime* lastModifiedTime)
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -183,18 +183,16 @@ public:
   NS_IMETHOD SetAllowSpdy(bool aAllowSpdy) override;
   NS_IMETHOD GetAllowAltSvc(bool *aAllowAltSvc) override;
   NS_IMETHOD SetAllowAltSvc(bool aAllowAltSvc) override;
   NS_IMETHOD GetApiRedirectToURI(nsIURI * *aApiRedirectToURI) override;
   virtual nsresult AddSecurityMessage(const nsAString &aMessageTag, const nsAString &aMessageCategory);
   NS_IMETHOD TakeAllSecurityMessages(nsCOMArray<nsISecurityConsoleMessage> &aMessages) override;
   NS_IMETHOD GetResponseTimeoutEnabled(bool *aEnable) override;
   NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable) override;
-  NS_IMETHOD GetInitialRwin(uint32_t* aRwin) override;
-  NS_IMETHOD SetInitialRwin(uint32_t aRwin) override;
   NS_IMETHOD GetNetworkInterfaceId(nsACString& aNetworkInterfaceId) override;
   NS_IMETHOD SetNetworkInterfaceId(const nsACString& aNetworkInterfaceId) override;
   NS_IMETHOD ForcePending(bool aForcePending) override;
   NS_IMETHOD GetLastModifiedTime(PRTime* lastModifiedTime) override;
   NS_IMETHOD GetCorsIncludeCredentials(bool* aInclude) override;
   NS_IMETHOD SetCorsIncludeCredentials(bool aInclude) override;
   NS_IMETHOD GetCorsMode(uint32_t* aCorsMode) override;
   NS_IMETHOD SetCorsMode(uint32_t aCorsMode) override;
@@ -394,19 +392,16 @@ protected:
   uint32_t                          mAllRedirectsPassTimingAllowCheck : 1;
 
   // True if this channel was intercepted and could receive a synthesized response.
   uint32_t                          mResponseCouldBeSynthesized : 1;
 
   // Current suspension depth for this channel object
   uint32_t                          mSuspendCount;
 
-  // Per channel transport window override (0 means no override)
-  uint32_t                          mInitialRwin;
-
   nsCOMPtr<nsIURI>                  mAPIRedirectToURI;
   nsAutoPtr<nsTArray<nsCString> >   mRedirectedCachekeys;
 
   uint32_t                          mProxyResolveFlags;
   nsCOMPtr<nsIURI>                  mProxyURI;
 
   uint32_t                          mContentDispositionHint;
   nsAutoPtr<nsString>               mContentDispositionFilename;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1720,17 +1720,16 @@ HttpChannelChild::ContinueAsyncOpen()
   openArgs.thirdPartyFlags() = mThirdPartyFlags;
   openArgs.resumeAt() = mSendResumeAt;
   openArgs.startPos() = mStartPos;
   openArgs.entityID() = mEntityID;
   openArgs.chooseApplicationCache() = mChooseApplicationCache;
   openArgs.appCacheClientID() = appCacheClientId;
   openArgs.allowSpdy() = mAllowSpdy;
   openArgs.allowAltSvc() = mAllowAltSvc;
-  openArgs.initialRwin() = mInitialRwin;
 
   uint32_t cacheKey = 0;
   if (mCacheKey) {
     nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(mCacheKey);
     if (!container) {
       return NS_ERROR_ILLEGAL_VALUE;
     }
 
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -122,18 +122,17 @@ HttpChannelParent::Init(const HttpChanne
                        a.requestMethod(), a.uploadStream(),
                        a.uploadStreamHasHeaders(), a.priority(), a.classOfService(),
                        a.redirectionLimit(), a.allowPipelining(), a.allowSTS(),
                        a.thirdPartyFlags(), a.resumeAt(), a.startPos(),
                        a.entityID(), a.chooseApplicationCache(),
                        a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.fds(),
                        a.loadInfo(), a.synthesizedResponseHead(),
                        a.synthesizedSecurityInfoSerialization(),
-                       a.cacheKey(), a.schedulingContextID(), a.preflightArgs(),
-                       a.initialRwin());
+                       a.cacheKey(), a.schedulingContextID(), a.preflightArgs());
   }
   case HttpChannelCreationArgs::THttpChannelConnectArgs:
   {
     const HttpChannelConnectArgs& cArgs = aArgs.get_HttpChannelConnectArgs();
     return ConnectChannel(cArgs.channelId(), cArgs.shouldIntercept());
   }
   default:
     NS_NOTREACHED("unknown open type");
@@ -282,18 +281,17 @@ HttpChannelParent::DoAsyncOpen(  const U
                                  const bool&                allowSpdy,
                                  const bool&                allowAltSvc,
                                  const OptionalFileDescriptorSet& aFds,
                                  const OptionalLoadInfoArgs& aLoadInfoArgs,
                                  const OptionalHttpResponseHead& aSynthesizedResponseHead,
                                  const nsCString&           aSecurityInfoSerialization,
                                  const uint32_t&            aCacheKey,
                                  const nsCString&           aSchedulingContextID,
-                                 const OptionalCorsPreflightArgs& aCorsPreflightArgs,
-                                 const uint32_t&            aInitialRwin)
+                                 const OptionalCorsPreflightArgs& aCorsPreflightArgs)
 {
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   if (!uri) {
     // URIParams does MOZ_ASSERT if null, but we need to protect opt builds from
     // null deref here.
     return false;
   }
   nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI);
@@ -451,17 +449,16 @@ HttpChannelParent::DoAsyncOpen(  const U
     mChannel->SetClassFlags(classOfService);
   }
   mChannel->SetRedirectionLimit(redirectionLimit);
   mChannel->SetAllowPipelining(allowPipelining);
   mChannel->SetAllowSTS(allowSTS);
   mChannel->SetThirdPartyFlags(thirdPartyFlags);
   mChannel->SetAllowSpdy(allowSpdy);
   mChannel->SetAllowAltSvc(allowAltSvc);
-  mChannel->SetInitialRwin(aInitialRwin);
 
   nsCOMPtr<nsIApplicationCacheChannel> appCacheChan =
     do_QueryObject(mChannel);
   nsCOMPtr<nsIApplicationCacheService> appCacheService =
     do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);
 
   bool setChooseApplicationCache = chooseApplicationCache;
   if (appCacheChan && appCacheService) {
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -116,18 +116,17 @@ protected:
                    const bool&                allowSpdy,
                    const bool&                allowAltSvc,
                    const OptionalFileDescriptorSet& aFds,
                    const OptionalLoadInfoArgs& aLoadInfoArgs,
                    const OptionalHttpResponseHead& aSynthesizedResponseHead,
                    const nsCString&           aSecurityInfoSerialization,
                    const uint32_t&            aCacheKey,
                    const nsCString&           aSchedulingContextID,
-                   const OptionalCorsPreflightArgs& aCorsPreflightArgs,
-                   const uint32_t&            aInitialRwin);
+                   const OptionalCorsPreflightArgs& aCorsPreflightArgs);
 
   virtual bool RecvSetPriority(const uint16_t& priority) override;
   virtual bool RecvSetClassOfService(const uint32_t& cos) override;
   virtual bool RecvSetCacheTokenCachedCharset(const nsCString& charset) override;
   virtual bool RecvSuspend() override;
   virtual bool RecvResume() override;
   virtual bool RecvCancel(const nsresult& status) override;
   virtual bool RecvRedirect2Verify(const nsresult& result,
--- a/netwerk/protocol/http/nsAHttpConnection.h
+++ b/netwerk/protocol/http/nsAHttpConnection.h
@@ -65,25 +65,17 @@ public:
     // multiplexed protocols like SPDY - plain HTTP or pipelined HTTP
     // implicitly have this information in a 1:1 relationship with the
     // transaction(s) they manage.
     virtual void TransactionHasDataToWrite(nsAHttpTransaction *)
     {
         // by default do nothing - only multiplexed protocols need to overload
         return;
     }
-
-    // This is the companion to *HasDataToWrite() for the case
-    // when a gecko caller has called ResumeRecv() after being paused
-    virtual void TransactionHasDataToRecv(nsAHttpTransaction *)
-    {
-        // by default do nothing - only multiplexed protocols need to overload
-        return;
-    }
-
+    //
     // called by the connection manager to close a transaction being processed
     // by this connection.
     //
     // @param transaction
     //        the transaction being closed.
     // @param reason
     //        the reason for closing the transaction.  NS_BASE_STREAM_CLOSED
     //        is equivalent to NS_OK.
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -192,17 +192,16 @@ nsHttpHandler::nsHttpHandler()
     , mCoalesceSpdy(true)
     , mSpdyPersistentSettings(false)
     , mAllowPush(true)
     , mEnableAltSvc(false)
     , mEnableAltSvcOE(false)
     , mSpdySendingChunkSize(ASpdySession::kSendingChunkSize)
     , mSpdySendBufferSize(ASpdySession::kTCPSendBufferSize)
     , mSpdyPushAllowance(32768)
-    , mSpdyPullAllowance(ASpdySession::kInitialRwin)
     , mDefaultSpdyConcurrent(ASpdySession::kDefaultMaxConcurrent)
     , mSpdyPingThreshold(PR_SecondsToInterval(58))
     , mSpdyPingTimeout(PR_SecondsToInterval(8))
     , mConnectTimeout(90000)
     , mParallelSpeculativeConnectLimit(6)
     , mRequestTokenBucketEnabled(true)
     , mRequestTokenBucketMinParallelism(6)
     , mRequestTokenBucketHz(100)
@@ -1311,24 +1310,16 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
         rv = prefs->GetIntPref(HTTP_PREF("spdy.push-allowance"), &val);
         if (NS_SUCCEEDED(rv)) {
             mSpdyPushAllowance =
                 static_cast<uint32_t>
                 (clamped(val, 1024, static_cast<int32_t>(ASpdySession::kInitialRwin)));
         }
     }
 
-    if (PREF_CHANGED(HTTP_PREF("spdy.pull-allowance"))) {
-        rv = prefs->GetIntPref(HTTP_PREF("spdy.pull-allowance"), &val);
-        if (NS_SUCCEEDED(rv)) {
-            mSpdyPullAllowance =
-                static_cast<uint32_t>(clamped(val, 1024, 0x7fffffff));
-        }
-    }
-
     if (PREF_CHANGED(HTTP_PREF("spdy.default-concurrent"))) {
         rv = prefs->GetIntPref(HTTP_PREF("spdy.default-concurrent"), &val);
         if (NS_SUCCEEDED(rv)) {
             mDefaultSpdyConcurrent =
                 static_cast<uint32_t>(std::max<int32_t>(std::min<int32_t>(val, 9999), 1));
         }
     }
 
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -106,17 +106,16 @@ public:
     bool           IsSpdyV31Enabled() { return mSpdyV31; }
     bool           IsHttp2Enabled() { return mHttp2Enabled; }
     bool           EnforceHttp2TlsProfile() { return mEnforceHttp2TlsProfile; }
     bool           CoalesceSpdy() { return mCoalesceSpdy; }
     bool           UseSpdyPersistentSettings() { return mSpdyPersistentSettings; }
     uint32_t       SpdySendingChunkSize() { return mSpdySendingChunkSize; }
     uint32_t       SpdySendBufferSize()      { return mSpdySendBufferSize; }
     uint32_t       SpdyPushAllowance()       { return mSpdyPushAllowance; }
-    uint32_t       SpdyPullAllowance()       { return mSpdyPullAllowance; }
     uint32_t       DefaultSpdyConcurrent()   { return mDefaultSpdyConcurrent; }
     PRIntervalTime SpdyPingThreshold() { return mSpdyPingThreshold; }
     PRIntervalTime SpdyPingTimeout() { return mSpdyPingTimeout; }
     bool           AllowPush()   { return mAllowPush; }
     bool           AllowAltSvc() { return mEnableAltSvc; }
     bool           AllowAltSvcOE() { return mEnableAltSvcOE; }
     uint32_t       ConnectTimeout()  { return mConnectTimeout; }
     uint32_t       ParallelSpeculativeConnectLimit() { return mParallelSpeculativeConnectLimit; }
@@ -498,17 +497,16 @@ private:
     uint32_t           mEnableAltSvcOE : 1;
 
     // Try to use SPDY features instead of HTTP/1.1 over SSL
     SpdyInformation    mSpdyInfo;
 
     uint32_t       mSpdySendingChunkSize;
     uint32_t       mSpdySendBufferSize;
     uint32_t       mSpdyPushAllowance;
-    uint32_t       mSpdyPullAllowance;
     uint32_t       mDefaultSpdyConcurrent;
     PRIntervalTime mSpdyPingThreshold;
     PRIntervalTime mSpdyPingTimeout;
 
     // The maximum amount of time to wait for socket transport to be
     // established. In milliseconds.
     uint32_t       mConnectTimeout;
 
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -93,17 +93,16 @@ nsHttpTransaction::nsHttpTransaction()
     , mRequestSize(0)
     , mConnection(nullptr)
     , mRequestHead(nullptr)
     , mResponseHead(nullptr)
     , mContentLength(-1)
     , mContentRead(0)
     , mInvalidResponseBytesRead(0)
     , mPushedStream(nullptr)
-    , mInitialRwin(0)
     , mChunkedDecoder(nullptr)
     , mStatus(NS_OK)
     , mPriority(0)
     , mRestartCount(0)
     , mCaps(0)
     , mClassification(CLASS_GENERAL)
     , mPipelinePosition(0)
     , mCapsToClear(0)
@@ -266,17 +265,16 @@ nsHttpTransaction::Init(uint32_t caps,
     nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
         do_QueryInterface(eventsink);
     if (httpChannelInternal) {
         rv = httpChannelInternal->GetResponseTimeoutEnabled(
             &mResponseTimeoutEnabled);
         if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
         }
-        httpChannelInternal->GetInitialRwin(&mInitialRwin);
     }
 
     // create transport event sink proxy. it coalesces consecutive
     // events of the same status type.
     rv = net_NewTransportEventSinkProxy(getter_AddRefs(mTransportSink),
                                         eventsink, target);
 
     if (NS_FAILED(rv)) return rv;
@@ -2192,17 +2190,16 @@ nsHttpTransaction::OnInputStreamReady(ns
 // nsHttpTransaction::nsIOutputStreamCallback
 //-----------------------------------------------------------------------------
 
 // called on the socket thread
 NS_IMETHODIMP
 nsHttpTransaction::OnOutputStreamReady(nsIAsyncOutputStream *out)
 {
     if (mConnection) {
-        mConnection->TransactionHasDataToRecv(this);
         nsresult rv = mConnection->ResumeRecv();
         if (NS_FAILED(rv))
             NS_ERROR("ResumeRecv failed");
     }
     return NS_OK;
 }
 
 // nsHttpTransaction::RestartVerifier
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -135,17 +135,16 @@ public:
     Http2PushedStream *GetPushedStream() { return mPushedStream; }
     Http2PushedStream *TakePushedStream()
     {
         Http2PushedStream *r = mPushedStream;
         mPushedStream = nullptr;
         return r;
     }
     void SetPushedStream(Http2PushedStream *push) { mPushedStream = push; }
-    uint32_t InitialRwin() const { return mInitialRwin; };
 
     // Locked methods to get and set timing info
     const TimingStruct Timings();
     void SetDomainLookupStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
     void SetDomainLookupEnd(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
     void SetConnectStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
     void SetConnectEnd(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
     void SetRequestStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
@@ -244,17 +243,16 @@ private:
     // After a 304/204 or other "no-content" style response we will skip over
     // up to MAX_INVALID_RESPONSE_BODY_SZ bytes when looking for the next
     // response header to deal with servers that actually sent a response
     // body where they should not have. This member tracks how many bytes have
     // so far been skipped.
     uint32_t                        mInvalidResponseBytesRead;
 
     Http2PushedStream               *mPushedStream;
-    uint32_t                        mInitialRwin;
 
     nsHttpChunkedDecoder            *mChunkedDecoder;
 
     TimingStruct                    mTimings;
 
     nsresult                        mStatus;
 
     int16_t                         mPriority;
--- a/netwerk/protocol/http/nsIHttpChannelInternal.idl
+++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl
@@ -34,17 +34,17 @@ interface nsIHttpUpgradeListener : nsISu
                               in nsIAsyncOutputStream aSocketOut);
 };
 
 /**
  * Dumping ground for http.  This interface will never be frozen.  If you are
  * using any feature exposed by this interface, be aware that this interface
  * will change and you will be broken.  You have been warned.
  */
-[scriptable, uuid(5f019a6f-6f6f-4b5c-8994-70cdbc40258e)]
+[scriptable, uuid(46ef729f-4c9b-4084-b9e2-498992a31aee)]
 
 interface nsIHttpChannelInternal : nsISupports
 {
     /**
      * An http channel can own a reference to the document URI
      */
     attribute nsIURI documentURI;
 
@@ -198,23 +198,16 @@ interface nsIHttpChannelInternal : nsISu
 
     /**
      * This attribute en/disables the timeout for the first byte of an HTTP
      * response. Enabled by default.
      */
     attribute boolean responseTimeoutEnabled;
 
     /**
-     * If the underlying transport supports RWIN manipulation, this is the
-     * intiial window value for the channel. HTTP/2 implements this.
-     * 0 means no override from system default. Set before opening channel.
-     */
-    attribute unsigned long initialRwin;
-
-    /**
      * Get value of the URI passed to nsIHttpChannel.redirectTo() if any.
      * May return null when redirectTo() has not been called.
      */
     readonly attribute nsIURI apiRedirectToURI;
 
     /**
      * Enable/Disable use of Alternate Services with this channel.
      * The network.http.altsvc.enabled preference is still a pre-requisite.