Backed out 2 changesets (bug 1261585) for causing website bustage.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 17 Jan 2017 23:29:11 -0500
changeset 374785 f930d9fbb4036a21045cbff90be5cc5a59958857
parent 374784 7f091f9ab43a679d08c29b74fc47691d9d380ded
child 374786 df802158c65c7368f1b261aabe5d06f7664c954c
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1261585
milestone53.0a1
backs out3b5321a426ad97d0ac43bdc4f3a05d10fb5b58e4
f6d5e6243d01ad740d5ec00659b5c9e5820a2f50
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
Backed out 2 changesets (bug 1261585) for causing website bustage. Backed out changeset 3b5321a426ad (bug 1261585) Backed out changeset f6d5e6243d01 (bug 1261585)
devtools/shared/webconsole/network-monitor.js
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/test/unit_ipc/child_tracable_listener.js
netwerk/test/unit_ipc/test_traceable_channel_decoded_data.js
netwerk/test/unit_ipc/test_traceable_channel_modify_response.js
netwerk/test/unit_ipc/xpcshell.ini
--- a/devtools/shared/webconsole/network-monitor.js
+++ b/devtools/shared/webconsole/network-monitor.js
@@ -422,19 +422,58 @@ NetworkResponseListener.prototype = {
   /**
    * See documentation at
    * https://developer.mozilla.org/En/NsIRequestObserver
    *
    * @param nsIRequest request
    * @param nsISupports context
    */
   onStartRequest: function (request) {
+    // Converter will call this again, we should just ignore that.
+    if (this.request) {
+      return;
+    }
+
     this.request = request;
     this._getSecurityInfo();
     this._findOpenResponse();
+    // We need to track the offset for the onDataAvailable calls where
+    // we pass the data from our pipe to the converter.
+    this.offset = 0;
+
+    // In the multi-process mode, the conversion happens on the child
+    // side while we can only monitor the channel on the parent
+    // side. If the content is gzipped, we have to unzip it
+    // ourself. For that we use the stream converter services.  Do not
+    // do that for Service workers as they are run in the child
+    // process.
+    let channel = this.request;
+    if (!this.httpActivity.fromServiceWorker &&
+        channel instanceof Ci.nsIEncodedChannel &&
+        channel.contentEncodings &&
+        !channel.applyConversion) {
+      let encodingHeader = channel.getResponseHeader("Content-Encoding");
+      let scs = Cc["@mozilla.org/streamConverters;1"]
+        .getService(Ci.nsIStreamConverterService);
+      let encodings = encodingHeader.split(/\s*\t*,\s*\t*/);
+      let nextListener = this;
+      let acceptedEncodings = ["gzip", "deflate", "br", "x-gzip", "x-deflate"];
+      for (let i in encodings) {
+        // There can be multiple conversions applied
+        let enc = encodings[i].toLowerCase();
+        if (acceptedEncodings.indexOf(enc) > -1) {
+          this.converter = scs.asyncConvertData(enc, "uncompressed",
+                                                nextListener, null);
+          nextListener = this.converter;
+        }
+      }
+      if (this.converter) {
+        this.converter.onStartRequest(this.request, null);
+      }
+    }
     // Asynchronously wait for the data coming from the request.
     this.setAsyncListener(this.sink.inputStream, this);
   },
 
   /**
    * Parse security state of this request and report it to the client.
    */
   _getSecurityInfo: DevToolsUtils.makeInfallible(function () {
@@ -590,16 +629,17 @@ NetworkResponseListener.prototype = {
       response,
       this.httpActivity.discardResponseBody
     );
 
     this._wrappedNotificationCallbacks = null;
     this.httpActivity = null;
     this.sink = null;
     this.inputStream = null;
+    this.converter = null;
     this.request = null;
     this.owner = null;
   },
 
   /**
    * The nsIInputStreamCallback for when the request input stream is ready -
    * either it has more data or it is closed.
    *
@@ -617,21 +657,25 @@ NetworkResponseListener.prototype = {
       // This may throw if the stream is closed normally or due to an error.
       available = stream.available();
     } catch (ex) {
       // Ignore.
     }
 
     if (available != -1) {
       if (available != 0) {
-        // Note that passing 0 as the offset here is wrong, but the
-        // onDataAvailable() method does not use the offset, so it does not
-        // matter.
-        this.onDataAvailable(this.request, null, stream, 0, available);
+        if (this.converter) {
+          this.converter.onDataAvailable(this.request, null, stream,
+                                         this.offset, available);
+        } else {
+          this.onDataAvailable(this.request, null, stream, this.offset,
+                               available);
+        }
       }
+      this.offset += available;
       this.setAsyncListener(stream, this);
     } else {
       this.onStreamClose();
       this.offset = 0;
     }
   },
 };
 
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -91,17 +91,16 @@ HttpBaseChannel::HttpBaseChannel()
   , mAllowAltSvc(true)
   , mBeConservative(false)
   , mResponseTimeoutEnabled(true)
   , mAllRedirectsSameOrigin(true)
   , mAllRedirectsPassTimingAllowCheck(true)
   , mResponseCouldBeSynthesized(false)
   , mBlockAuthPrompt(false)
   , mAllowStaleCacheContent(false)
-  , mHasListenerForTraceableChannel(false)
   , mSuspendCount(0)
   , mInitialRwin(0)
   , mProxyResolveFlags(0)
   , mProxyURI(nullptr)
   , mContentDispositionHint(UINT32_MAX)
   , mHttpHandler(gHttpHandler)
   , mReferrerPolicy(NS_GetDefaultReferrerPolicy())
   , mRedirectCount(0)
@@ -2772,17 +2771,16 @@ HttpBaseChannel::SetNewListener(nsIStrea
 
   NS_ENSURE_STATE(mListener);
   NS_ENSURE_ARG_POINTER(aListener);
 
   nsCOMPtr<nsIStreamListener> wrapper = new nsStreamListenerWrapper(mListener);
 
   wrapper.forget(_retval);
   mListener = aListener;
-  mHasListenerForTraceableChannel = true;
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpBaseChannel helpers
 //-----------------------------------------------------------------------------
 
 void
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -336,18 +336,16 @@ public: /* Necko internal use only... */
     // mListenerContext.
     nsresult DoApplyContentConversions(nsIStreamListener *aNextListener,
                                        nsIStreamListener **aNewNextListener);
 
     // Callback on main thread when NS_AsyncCopy() is finished populating
     // the new mUploadStream.
     void EnsureUploadStreamIsCloneableComplete(nsresult aStatus);
 
-    bool HasListenerForTraceableChannel() { return mHasListenerForTraceableChannel; }
-
     void SetIsTrackingResource()
     {
       mIsTrackingResource = true;
     }
 
 protected:
   nsCOMArray<nsISecurityConsoleMessage> mSecurityConsoleMessages;
 
@@ -492,18 +490,16 @@ protected:
   uint32_t                          mResponseCouldBeSynthesized : 1;
 
   uint32_t                          mBlockAuthPrompt : 1;
 
   // If true, we behave as if the LOAD_FROM_CACHE flag has been set.
   // Used to enforce that flag's behavior but not expose it externally.
   uint32_t                          mAllowStaleCacheContent : 1;
 
-  uint32_t                          mHasListenerForTraceableChannel : 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;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -175,17 +175,16 @@ HttpChannelChild::HttpChannelChild()
   , mSuspendSent(false)
   , mSynthesizedResponse(false)
   , mShouldInterceptSubsequentRedirect(false)
   , mRedirectingForSubsequentSynthesizedResponse(false)
   , mPostRedirectChannelShouldIntercept(false)
   , mPostRedirectChannelShouldUpgrade(false)
   , mShouldParentIntercept(false)
   , mSuspendParentAfterSynthesizeResponse(false)
-  , mContentDecodingWillBeCalledOnParent(false)
 {
   LOG(("Creating HttpChannelChild @%x\n", this));
 
   mChannelCreationTime = PR_Now();
   mChannelCreationTimestamp = TimeStamp::Now();
   mAsyncOpenTime = TimeStamp::Now();
   mEventQ = new ChannelEventQueue(static_cast<nsIHttpChannel*>(this));
 }
@@ -378,32 +377,29 @@ HttpChannelChild::RecvOnStartRequest(con
                                      const bool& cacheEntryAvailable,
                                      const uint32_t& cacheExpirationTime,
                                      const nsCString& cachedCharset,
                                      const nsCString& securityInfoSerialization,
                                      const NetAddr& selfAddr,
                                      const NetAddr& peerAddr,
                                      const int16_t& redirectCount,
                                      const uint32_t& cacheKey,
-                                     const nsCString& altDataType,
-                                     const bool& contentDecodingWillBeCalledOnParent)
+                                     const nsCString& altDataType)
 {
   LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this));
   // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
   // stage, as they are set in the listener's OnStartRequest.
   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
     "mFlushedForDiversion should be unset before OnStartRequest!");
   MOZ_RELEASE_ASSERT(!mDivertingToParent,
     "mDivertingToParent should be unset before OnStartRequest!");
 
 
   mRedirectCount = redirectCount;
 
-  mContentDecodingWillBeCalledOnParent = contentDecodingWillBeCalledOnParent;
-
   mEventQ->RunOrEnqueue(new StartRequestEvent(this, channelStatus, responseHead,
                                               useResponseHead, requestHeaders,
                                               isFromCache, cacheEntryAvailable,
                                               cacheExpirationTime,
                                               cachedCharset,
                                               securityInfoSerialization,
                                               selfAddr, peerAddr, cacheKey,
                                               altDataType));
@@ -554,36 +550,16 @@ HttpChannelChild::DoOnStartRequest(nsIRe
     return;
   }
   nsresult rv = mListener->OnStartRequest(aRequest, aContext);
   if (NS_FAILED(rv)) {
     Cancel(rv);
     return;
   }
 
-  if (mContentDecodingWillBeCalledOnParent) {
-    // Whether we need to do a data conversion or not is decided during
-    // OnStartRequest call. nsURILoader and nsExternalHelperAppService are
-    // making this decision on the child.
-    // If the parent channel has a listener for the TracableChannel interface,
-    // we need to convert the data before giving it to the listent, e.g. we
-    // need to convert the data on the parent.
-    //
-    // After calling OnStartRequest check if we need to do a data conversion or
-    // not and inform the parent about the decision.
-    bool doContentConversion;
-    GetApplyConversion(&doContentConversion);
-    SetApplyConversion(false);
-    SendApplyConversion(doContentConversion);
-    mContentDecodingWillBeCalledOnParent = false;
-    LOG(("HttpChannelChild::DoOnStartRequest [this=%p] doing content decoding"
-         " on the parent; doContentEncoding=%d \n",
-         this, doContentConversion));
-  }
-
   if (mDivertingToParent) {
     mListener = nullptr;
     mListenerContext = nullptr;
     mCompressListener = nullptr;
     if (mLoadGroup) {
       mLoadGroup->RemoveRequest(this, nullptr, mStatus);
     }
 
@@ -1848,22 +1824,16 @@ HttpChannelChild::OnRedirectVerifyCallba
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpChannelChild::Cancel(nsresult status)
 {
   LOG(("HttpChannelChild::Cancel [this=%p]\n", this));
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mContentDecodingWillBeCalledOnParent) {
-    LOG(("HttpChannelChild::Cancel call SendApplyConversion [this=%p]\n", this));
-    SendApplyConversion(false);
-    mContentDecodingWillBeCalledOnParent = false;
-  }
-
   if (!mCanceled) {
     // If this cancel occurs before nsHttpChannel has been set up, AsyncOpen
     // is responsible for cleaning up.
     mCanceled = true;
     mStatus = status;
     if (RemoteChannelExists())
       SendCancel(status);
     if (mSynthesizedResponsePump) {
@@ -2791,22 +2761,16 @@ HttpChannelChild::DivertToParent(Channel
   HttpChannelDiverterArgs args;
   args.mChannelChild() = this;
   args.mApplyConversion() = mApplyConversion;
 
   PChannelDiverterChild* diverter =
     gNeckoChild->SendPChannelDiverterConstructor(args);
   MOZ_RELEASE_ASSERT(diverter);
 
-  // When a request is diverted to the parent, OnStartRequest of all listeners
-  // are called on the parent (and of course the end decision whether data
-  // should be converted or not is made on the parent), therefore just clear
-  // mContentDecodingWillBeCalledOnParent and do not send SendApplyConversion.
-  mContentDecodingWillBeCalledOnParent = false;
-
   *aChild = static_cast<ChannelDiverterChild*>(diverter);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelChild::UnknownDecoderInvolvedKeepData()
 {
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -118,18 +118,17 @@ protected:
                                              const bool& cacheEntryAvailable,
                                              const uint32_t& cacheExpirationTime,
                                              const nsCString& cachedCharset,
                                              const nsCString& securityInfoSerialization,
                                              const NetAddr& selfAddr,
                                              const NetAddr& peerAddr,
                                              const int16_t& redirectCount,
                                              const uint32_t& cacheKey,
-                                             const nsCString& altDataType,
-                                             const bool& contentDecodingWillBeCalledOnParent) override;
+                                             const nsCString& altDataType) override;
   mozilla::ipc::IPCResult RecvOnTransportAndData(const nsresult& channelStatus,
                                                  const nsresult& status,
                                                  const uint64_t& progress,
                                                  const uint64_t& progressMax,
                                                  const uint64_t& offset,
                                                  const uint32_t& count,
                                                  const nsCString& data) override;
   mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& statusCode, const ResourceTimingStruct& timing) override;
@@ -271,18 +270,16 @@ private:
   // Set if the corresponding parent channel should force an interception to occur
   // before the network transaction is initiated.
   bool mShouldParentIntercept;
 
   // Set if the corresponding parent channel should suspend after a response
   // is synthesized.
   bool mSuspendParentAfterSynthesizeResponse;
 
-  bool mContentDecodingWillBeCalledOnParent;
-
   // Needed to call AsyncOpen in FinishInterceptedRedirect
   nsCOMPtr<nsIStreamListener> mInterceptedRedirectListener;
   nsCOMPtr<nsISupports> mInterceptedRedirectContext;
   // Needed to call CleanupRedirectingChannel in FinishInterceptedRedirect
   RefPtr<HttpChannelChild> mInterceptingChannel;
   // Used to call OverrideWithSynthesizedResponse in FinishInterceptedRedirect
   RefPtr<OverrideRunnable> mOverrideRunnable;
 
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -62,17 +62,16 @@ HttpChannelParent::HttpChannelParent(con
   , mLoadContext(aLoadContext)
   , mStatus(NS_OK)
   , mPendingDiversion(false)
   , mDivertingFromChild(false)
   , mDivertedOnStartRequest(false)
   , mSuspendedForDiversion(false)
   , mSuspendAfterSynthesizeResponse(false)
   , mWillSynthesizeResponse(false)
-  , mWaitingForApplyConversionResponse(false)
   , mNestedFrameId(0)
 {
   LOG(("Creating HttpChannelParent [this=%p]\n", this));
 
   // Ensure gHttpHandler is initialized: we need the atom table up and running.
   nsCOMPtr<nsIHttpProtocolHandler> dummyInitializer =
     do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http");
 
@@ -812,32 +811,16 @@ HttpChannelParent::RecvMarkOfflineCacheE
   if (mOfflineForeignMarker) {
     mOfflineForeignMarker->MarkAsForeign();
     mOfflineForeignMarker = 0;
   }
 
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult
-HttpChannelParent::RecvApplyConversion(const bool& aApply)
-{
-  LOG(("HttpChannelParent::RecvApplyConversion [this=%p, aApply=%d, "
-       "mWaitingForApplyConversionResponse=%d]",
-       this, aApply, mWaitingForApplyConversionResponse));
-  MOZ_ASSERT(mChannel->HasListenerForTraceableChannel());
-  if (mWaitingForApplyConversionResponse) {
-    mWaitingForApplyConversionResponse = false;
-    mChannel->SetApplyConversion(aApply);
-    mChannel->ApplyContentConversions();
-    mChannel->Resume();
-  }
-  return IPC_OK();
-}
-
 class DivertDataAvailableEvent : public ChannelEvent
 {
 public:
   DivertDataAvailableEvent(HttpChannelParent* aParent,
                            const nsCString& data,
                            const uint64_t& offset,
                            const uint32_t& count)
   : mParent(aParent)
@@ -1150,16 +1133,20 @@ HttpChannelParent::OnStartRequest(nsIReq
     appCache->GetClientID(appCacheClientId);
     if (mIPCClosed ||
         !SendAssociateApplicationCache(appCacheGroupId, appCacheClientId))
     {
       return NS_ERROR_UNEXPECTED;
     }
   }
 
+  nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(aRequest);
+  if (encodedChannel)
+    encodedChannel->SetApplyConversion(false);
+
   // Keep the cache entry for future use in RecvSetCacheTokenCachedCharset().
   // It could be already released by nsHttpChannel at that time.
   nsCOMPtr<nsISupports> cacheEntry;
   chan->GetCacheToken(getter_AddRefs(cacheEntry));
   mCacheEntry = do_QueryInterface(cacheEntry);
 
   nsresult channelStatus = NS_OK;
   chan->GetStatus(&channelStatus);
@@ -1183,54 +1170,32 @@ HttpChannelParent::OnStartRequest(nsIReq
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
 
   nsAutoCString altDataType;
   chan->GetAlternativeDataType(altDataType);
 
-  nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(aRequest);
-  if (encodedChannel) {
-    encodedChannel->SetApplyConversion(false);
-    if (mChannel->HasListenerForTraceableChannel()) {
-      LOG(("HttpChannelParent::OnStartRequest - suspend channel until we know "
-           "whether we need to apply conversions [this=%p]\n", this));
-      // We have a traceableChannel listener so we need to do a data conversion
-      // on the parent.
-      // The correct decision whether we need to convert the data is made on
-      // the child process during OnStartRequest call, therefore we will
-      // suspend the channel here and wait for the decision result from the
-      // child (we are waiting for RecvApplyConversion).
-      mWaitingForApplyConversionResponse = NS_SUCCEEDED(mChannel->Suspend()) ?
-                                           true : false;
-    }
-  }
-
   // !!! We need to lock headers and please don't forget to unlock them !!!
   requestHead->Enter();
   nsresult rv = NS_OK;
   if (mIPCClosed ||
       !SendOnStartRequest(channelStatus,
                           responseHead ? *responseHead : nsHttpResponseHead(),
                           !!responseHead,
                           requestHead->Headers(),
                           isFromCache,
                           mCacheEntry ? true : false,
                           expirationTime, cachedCharset, secInfoSerialization,
                           chan->GetSelfAddr(), chan->GetPeerAddr(),
                           redirectCount,
                           cacheKeyValue,
-                          altDataType,
-                          mWaitingForApplyConversionResponse))
+                          altDataType))
   {
-    if (mWaitingForApplyConversionResponse) {
-      mChannel->Resume();
-      mWaitingForApplyConversionResponse = false;
-    }
     rv = NS_ERROR_UNEXPECTED;
   }
   requestHead->Exit();
   return rv;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
@@ -1658,35 +1623,24 @@ HttpChannelParent::StartDiversion()
         mChannel->Cancel(rv);
       }
       mStatus = rv;
     }
   }
   mDivertedOnStartRequest = true;
 
   // After OnStartRequest has been called, setup content decoders if needed.
-  if (mWaitingForApplyConversionResponse) {
-    // If we are mWaitingForApplyConversionResponse, means that mChannel is
-    // suspended right after OnStartRequest, therefore we can apply content
-    // conversion directly on the top of mChannel and Tracable Listeners will
-    // get decoded data.
-    if (NS_SUCCEEDED(mStatus)) {
-      mChannel->ApplyContentConversions();
-    }
-    mWaitingForApplyConversionResponse = false;
-    mChannel->Resume();
-  } else {
-    // Create a content conversion chain based on mDivertListener and update
-    // mDivertListener.
-    nsCOMPtr<nsIStreamListener> converterListener;
-    mChannel->DoApplyContentConversions(mDivertListener,
-                                        getter_AddRefs(converterListener));
-    if (converterListener) {
-      mDivertListener = converterListener.forget();
-    }
+  //
+  // Create a content conversion chain based on mDivertListener and update
+  // mDivertListener.
+  nsCOMPtr<nsIStreamListener> converterListener;
+  mChannel->DoApplyContentConversions(mDivertListener,
+                                      getter_AddRefs(converterListener));
+  if (converterListener) {
+    mDivertListener = converterListener.forget();
   }
 
   // Now mParentListener can be diverted to mDivertListener.
   DebugOnly<nsresult> rvdbg = mParentListener->DivertTo(mDivertListener);
   MOZ_ASSERT(NS_SUCCEEDED(rvdbg));
   mDivertListener = nullptr;
 
   if (NS_WARN_IF(mIPCClosed || !SendFlushedForDiversion())) {
@@ -1747,21 +1701,16 @@ HttpChannelParent::NotifyDiversionFailed
        this, aErrorCode));
   MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
   MOZ_RELEASE_ASSERT(mDivertingFromChild);
   MOZ_RELEASE_ASSERT(mParentListener);
   MOZ_RELEASE_ASSERT(mChannel);
 
   mChannel->Cancel(aErrorCode);
 
-  if (mWaitingForApplyConversionResponse) {
-    mWaitingForApplyConversionResponse = false;
-    mChannel->Resume();
-  }
-
   mChannel->ForcePending(false);
 
   bool isPending = false;
   nsresult rv = mChannel->IsPending(&isPending);
   MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
 
   // Resume only if we suspended earlier.
   if (mSuspendedForDiversion) {
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -170,17 +170,16 @@ protected:
   virtual mozilla::ipc::IPCResult RecvMarkOfflineCacheEntryAsForeign() override;
   virtual mozilla::ipc::IPCResult RecvDivertOnDataAvailable(const nsCString& data,
                                          const uint64_t& offset,
                                          const uint32_t& count) override;
   virtual mozilla::ipc::IPCResult RecvDivertOnStopRequest(const nsresult& statusCode) override;
   virtual mozilla::ipc::IPCResult RecvDivertComplete() override;
   virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(const URIParams& uri,
                                                                     const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;
-  virtual mozilla::ipc::IPCResult RecvApplyConversion(const bool& applyConversion)  override;
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   // Supporting function for ADivertableParentChannel.
   nsresult ResumeForDiversion();
 
   // Asynchronously calls NotifyDiversionFailed.
   void FailDiversion(nsresult aErrorCode, bool aSkipResume = true);
 
@@ -256,36 +255,16 @@ private:
 
   bool mSuspendedForDiversion;
 
   // Set if this channel should be suspended after synthesizing a response.
   bool mSuspendAfterSynthesizeResponse;
   // Set if this channel will synthesize its response.
   bool mWillSynthesizeResponse;
 
-  // Whether we need to apply a data conversion or not is decided during
-  // a OnStartRequest call on the last channel listener. This is perform on the
-  // child and conversion is perform on the child process as well.
-  // If the http channel has a TracableChannel listener we need to perform
-  // the data conversion, if needed, on the parent, but still the decision
-  // whether to perform the conversion or not is made during OnStartRequest on
-  // the child process. Using a parameter in SendOnStartRequest we will request
-  // from the child to send us the final decision (Send/RecvApplyConversion
-  // with parameter aApply true or false). The mChannel will be suspended until
-  // the responce is received.
-  // If the channel gets canceled we will just set the ApplyConversion to
-  // false and resume mChannel.
-  //
-  // If DivertToParent is performed, the OnStartRequest call on the last
-  // channel listener is performed on the parent and the child process does not
-  // need to send Send/RecvApplyConversion. ApplyContentConversions will be
-  // called after the OnStartRequest has been called (This is in the
-  // StartDiversion function on the parent).
-  bool mWaitingForApplyConversionResponse;
-
   dom::TabId mNestedFrameId;
 
   RefPtr<ChannelEventQueue> mEventQ;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelParent,
                               HTTP_CHANNEL_PARENT_IID)
 
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -86,36 +86,33 @@ parent:
   // to remove any matching entry from the CORS preflight cache.
   async RemoveCorsPreflightCacheEntry(URIParams uri,
                                       PrincipalInfo requestingPrincipal);
 
   // After receiving this message, the parent calls SendDeleteSelf, and makes
   // sure not to send any more messages after that.
   async DeletingChannel();
 
-  async ApplyConversion(bool applyConversion);
-
   async __delete__();
 
 child:
   async OnStartRequest(nsresult            channelStatus,
                        nsHttpResponseHead  responseHead,
                        bool                useResponseHead,
                        nsHttpHeaderArray   requestHeaders,
                        bool                isFromCache,
                        bool                cacheEntryAvailable,
                        uint32_t            cacheExpirationTime,
                        nsCString           cachedCharset,
                        nsCString           securityInfoSerialization,
                        NetAddr             selfAddr,
                        NetAddr             peerAddr,
                        int16_t             redirectCount,
                        uint32_t            cacheKey,
-                       nsCString           altDataType,
-                       bool                contentDecodingWillBeCalledOnParent);
+                       nsCString           altDataType);
 
   // Combines a single OnDataAvailable and its associated OnProgress &
   // OnStatus calls into one IPDL message
   async OnTransportAndData(nsresult  channelStatus,
                            nsresult  transportStatus,
                            uint64_t  progress,
                            uint64_t  progressMax,
                            uint64_t  offset,
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1210,33 +1210,16 @@ EnsureMIMEOfScript(nsIURI* aURI, nsHttpR
         return NS_OK;
     }
 
     // script load has unknown type
     Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 0);
     return NS_OK;
 }
 
-void
-nsHttpChannel::ApplyContentConversions()
-{
-    nsCOMPtr<nsIStreamListener> listener;
-    nsISupports *ctxt = mListenerContext;
-    nsresult rv = DoApplyContentConversions(mListener,
-                                            getter_AddRefs(listener),
-                                            ctxt);
-    if (NS_FAILED(rv)) {
-        AsyncAbort(rv);
-    }
-
-    if (listener) {
-        mListener = listener;
-        mCompressListener = listener;
-    }
-}
 
 nsresult
 nsHttpChannel::CallOnStartRequest()
 {
     MOZ_RELEASE_ASSERT(!(mRequireCORSPreflight &&
                          mInterceptCache != INTERCEPTED) ||
                        mIsCorsPreflightDone,
                        "CORS preflight must have been finished by the time we "
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -173,18 +173,16 @@ public:
     NS_IMETHOD OnPreflightFailed(nsresult aError) override;
 
     nsresult AddSecurityMessage(const nsAString& aMessageTag,
                                 const nsAString& aMessageCategory) override;
 
     void SetWarningReporter(HttpChannelSecurityWarningReporter* aReporter)
       { mWarningReporter = aReporter; }
 
-    void ApplyContentConversions();
-
 public: /* internal necko use only */
 
     void InternalSetUploadStream(nsIInputStream *uploadStream)
       { mUploadStream = uploadStream; }
     void SetUploadStreamHasHeaders(bool hasHeaders)
       { mUploadStreamHasHeaders = hasHeaders; }
 
     nsresult SetReferrerWithPolicyInternal(nsIURI *referrer,
deleted file mode 100644
--- a/netwerk/test/unit_ipc/child_tracable_listener.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Send HTTP requests and check if the received content is correct.
- */
-
-Cu.import("resource://gre/modules/NetUtil.jsm");
-
-let shouldQuit = false;
-
-function run_test() {
-  // keep the event loop busy and the test alive until a "finish" command
-  // is issued by parent
-  do_timeout(100, function keepAlive() {
-    if (!shouldQuit) {
-      do_timeout(100, keepAlive);
-    }
-  });
-}
-
-var expectedResponse;
-
-function makeRequest(uri, response) {
-  let requestChannel = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true});
-
-  expectedResponse = response;
-  requestChannel.asyncOpen2(new ChannelListener(checkResponse, null, CL_EXPECT_GZIP));
-}
-
-function checkResponse(request, buffer) {
-  do_check_eq(expectedResponse, buffer);
-
-  do_send_remote_message(`response`);
-}
-
-function finish() {
-  shouldQuit = true;
-}
deleted file mode 100644
--- a/netwerk/test/unit_ipc/test_traceable_channel_decoded_data.js
+++ /dev/null
@@ -1,172 +0,0 @@
-// Test nsITraceableChannel interface.
-//
-// The test checks that content-encoded responses are received decoded by a
-// tracing listener.
-
-Cu.import("resource://testing-common/httpd.js");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-
-const DEBUG = false;
-
-function debug(msg) {
-  if (DEBUG) {
-    dump(msg);
-  }
-}
-
-var httpserver = new HttpServer();
-httpserver.start(-1);
-const PORT = httpserver.identity.primaryPort;
-
-var originalBody = "original http response body";
-
-var body = [
-  0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xcb, 0x2f, 0xca, 0x4c, 0xcf, 0xcc,
-  0x4b, 0xcc, 0x51, 0xc8, 0x28, 0x29, 0x29, 0x50, 0x28, 0x4a, 0x2d, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e,
-  0x55, 0x48, 0xca, 0x4f, 0xa9, 0x04, 0x00, 0x94, 0xde, 0x94, 0x9c, 0x1b, 0x00, 0x00, 0x00];
-
-var observer;
-
-function TracingListener() {}
-
-TracingListener.prototype = {
-  gotOnStartRequest: false,
-  pipe: null,
-  streamSink: null,
-  listener: null,
-
-  // Replace received response body.
-  onDataAvailable: function(request, context, inputStream,
-                           offset, count) {
-    debug("*** tracing listener onDataAvailable\n");
-  },
-
-  onStartRequest: function(request, context) {
-    debug("*** tracing listener onStartRequest\n");
-
-    this.gotOnStartRequest = true;
-
-    request.QueryInterface(Components.interfaces.nsIHttpChannelInternal);
-
-    do_check_eq(request.localAddress, "127.0.0.1");
-    do_check_eq(request.localPort > 0, true);
-    do_check_neq(request.localPort, PORT);
-    do_check_eq(request.remoteAddress, "127.0.0.1");
-    do_check_eq(request.remotePort, PORT);
-  },
-
-  onStopRequest: function(request, context, statusCode) {
-    debug("*** tracing listener onStopRequest\n");
-
-    var sin = Components.classes["@mozilla.org/scriptableinputstream;1"].
-                createInstance(Ci.nsIScriptableInputStream);
-
-    this.streamSink.close();
-    var input = this.pipe.inputStream;
-    sin.init(input);
-    do_check_eq(sin.available(), originalBody.length);
-
-    var result = sin.read(originalBody.length);
-    do_check_eq(result, originalBody);
-
-    input.close();
-
-    do_check_eq(this.gotOnStartRequest, true);
-
-    let message = `response`;
-    do_await_remote_message(message).then(() => {
-      sendCommand("finish();", stopServer);
-    });
-  },
-
-  QueryInterface: function(iid) {
-    if (iid.equals(Components.interfaces.nsIStreamListener) ||
-        iid.equals(Components.interfaces.nsIRequestObserver) ||
-        iid.equals(Components.interfaces.nsISupports)
-        )
-      return this;
-    throw Components.results.NS_NOINTERFACE;
-  }
-}
-
-function HttpResponseExaminer() {}
-
-HttpResponseExaminer.prototype = {
-  register: function() {
-    Cc["@mozilla.org/observer-service;1"].
-      getService(Components.interfaces.nsIObserverService).
-      addObserver(this, "http-on-examine-response", true);
-    debug("Did HttpResponseExaminer.register\n");
-  },
-
-  unregister: function() {
-    Cc["@mozilla.org/observer-service;1"].
-      getService(Components.interfaces.nsIObserverService).
-      removeObserver(this, "http-on-examine-response", true);
-    debug("Did HttpResponseExaminer.unregister\n");
-  },
-
-  // Replace channel's listener.
-  observe: function(subject, topic, data) {
-    debug("In HttpResponseExaminer.observe\n");
-
-    try {
-      subject.QueryInterface(Components.interfaces.nsITraceableChannel);
-
-      var tee = Cc["@mozilla.org/network/stream-listener-tee;1"].
-          createInstance(Ci.nsIStreamListenerTee);
-      var newListener = new TracingListener();
-      newListener.pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
-      newListener.pipe.init(false, false, 0, 0xffffffff, null);
-      newListener.streamSink = newListener.pipe.outputStream;
-
-      var originalListener = subject.setNewListener(tee);
-      tee.init(originalListener, newListener.streamSink, newListener);
-    } catch(e) {
-      do_throw("can't replace listener " + e);
-    }
-
-    debug("Did HttpResponseExaminer.observe\n");
-  },
-
-  QueryInterface: function(iid) {
-    if (iid.equals(Components.interfaces.nsIObserver) ||
-        iid.equals(Components.interfaces.nsISupportsWeakReference) ||
-        iid.equals(Components.interfaces.nsISupports))
-      return this;
-    throw Components.results.NS_NOINTERFACE;
-  }
-}
-
-function test_handlerContentEncoded(metadata, response) {
-  response.setStatusLine(metadata.httpVersion, 200, "OK");
-  response.setHeader("Content-Type", "text/plain", false);
-  response.setHeader("Content-Encoding", "gzip", false);
-  response.setHeader("Content-Length", "" + body.length, false);
-
-  var bos = Components.classes["@mozilla.org/binaryoutputstream;1"]
-    .createInstance(Components.interfaces.nsIBinaryOutputStream);
-  bos.setOutputStream(response.bodyOutputStream);
-
-  response.processAsync();
-  bos.writeByteArray(body, body.length);
-  response.finish();
-}
-
-function test_contentEncoded() {
-  sendCommand(`makeRequest("http://localhost:${PORT}/testContentEncoded", "${originalBody}");`);
-}
-
-function stopServer() {
-  observer.unregister();
-  httpserver.stop(do_test_finished)
-}
-
-function run_test() {
-
-  observer = new HttpResponseExaminer();
-  observer.register();
-
-  httpserver.registerPathHandler("/testContentEncoded", test_handlerContentEncoded);
-  run_test_in_child("child_tracable_listener.js", test_contentEncoded);
-}
deleted file mode 100644
--- a/netwerk/test/unit_ipc/test_traceable_channel_modify_response.js
+++ /dev/null
@@ -1,186 +0,0 @@
-// Test nsITraceableChannel interface.
-//
-// The test checks that a tracing listener can modifies the body of a HTTP
-// response.
-// This test also check that it is not possible to set a tracableLisener after
-// onStartRequest is called.
-
-Cu.import("resource://testing-common/httpd.js");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-
-const DEBUG = false;
-
-function debug(msg) {
-  if (DEBUG) {
-    dump(msg);
-  }
-}
-
-var httpserver = new HttpServer();
-httpserver.start(-1);
-const PORT = httpserver.identity.primaryPort;
-
-var originalBody = "original http response body";
-var replacedBody = "replaced http response body";
-
-var observer;
-
-function TracingListener() {}
-
-TracingListener.prototype = {
-  gotOnStartRequest: false,
-  pipe: null,
-  streamSink: null,
-  listener: null,
-  onDataAvailableCalled: false,
-
-  // Replace received response body.
-  onDataAvailable: function(request, context, inputStream,
-                           offset, count) {
-    debug("*** tracing listener onDataAvailable\n");
-
-    var binaryInputStream = Cc["@mozilla.org/binaryinputstream;1"].
-      createInstance(Components.interfaces.nsIBinaryInputStream);
-    binaryInputStream.setInputStream(inputStream);
-
-    var data = binaryInputStream.readBytes(count);
-    var origBody = originalBody.substr(offset, count);
-
-    do_check_eq(origBody, data);
-
-    if (!this.onDataAvailableCalled) {
-      this.onDataAvailableCalled = true;
-      var storageStream = Cc["@mozilla.org/storagestream;1"].
-        createInstance(Components.interfaces.nsIStorageStream);
-      var binaryOutputStream = Cc["@mozilla.org/binaryoutputstream;1"].
-        createInstance(Components.interfaces.nsIBinaryOutputStream);
-
-      storageStream.init(8192, 100, null);
-      binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));
-
-      var newBody = replacedBody.substr(offset, count);
-      binaryOutputStream.writeBytes(newBody, newBody.length);
-
-      this.listener.onDataAvailable(request, context,
-                                    storageStream.newInputStream(0), 0,
-                                    replacedBody.length);
-    }
-  },
-
-  onStartRequest: function(request, context) {
-    debug("*** tracing listener onStartRequest\n");
-
-    this.listener.onStartRequest(request, context);
-
-    this.gotOnStartRequest = true;
-
-    request.QueryInterface(Components.interfaces.nsIHttpChannelInternal);
-
-    do_check_eq(request.localAddress, "127.0.0.1");
-    do_check_eq(request.localPort > 0, true);
-    do_check_neq(request.localPort, PORT);
-    do_check_eq(request.remoteAddress, "127.0.0.1");
-    do_check_eq(request.remotePort, PORT);
-
-    // Make sure listener can't be replaced after OnStartRequest was called.
-    request.QueryInterface(Components.interfaces.nsITraceableChannel);
-    try {
-      var newListener = new TracingListener();
-      newListener.listener = request.setNewListener(newListener);
-    } catch(e) {
-      do_check_true(true, "TracingListener.onStartRequest swallowing exception: " + e + "\n");
-      return; // OK
-    }
-    do_throw("replaced channel's listener during onStartRequest.");
-  },
-
-  onStopRequest: function(request, context, statusCode) {
-    debug("*** tracing listener onStopRequest\n");
-
-
-    this.listener.onStopRequest(request, context, statusCode)
-
-    do_check_eq(this.gotOnStartRequest, true);
-
-    let message = `response`;
-    do_await_remote_message(message).then(() => {
-      sendCommand("finish();", stopServer);
-    });
-  },
-
-  QueryInterface: function(iid) {
-    if (iid.equals(Components.interfaces.nsIStreamListener) ||
-        iid.equals(Components.interfaces.nsIRequestObserver) ||
-        iid.equals(Components.interfaces.nsISupports)
-        )
-      return this;
-    throw Components.results.NS_NOINTERFACE;
-  }
-}
-
-function HttpResponseExaminer() {}
-
-HttpResponseExaminer.prototype = {
-  register: function() {
-    Cc["@mozilla.org/observer-service;1"].
-      getService(Components.interfaces.nsIObserverService).
-      addObserver(this, "http-on-examine-response", true);
-    debug("Did HttpResponseExaminer.register\n");
-  },
-
-  unregister: function() {
-    Cc["@mozilla.org/observer-service;1"].
-      getService(Components.interfaces.nsIObserverService).
-      removeObserver(this, "http-on-examine-response", true);
-    debug("Did HttpResponseExaminer.unregister\n");
-  },
-
-  // Replace channel's listener.
-  observe: function(subject, topic, data) {
-    debug("In HttpResponseExaminer.observe\n");
-
-    try {
-      subject.QueryInterface(Components.interfaces.nsITraceableChannel);
-      var newListener = new TracingListener();
-      newListener.listener = subject.setNewListener(newListener);
-    } catch(e) {
-      do_throw("can't replace listener " + e);
-    }
-
-    debug("Did HttpResponseExaminer.observe\n");
-  },
-
-  QueryInterface: function(iid) {
-    if (iid.equals(Components.interfaces.nsIObserver) ||
-        iid.equals(Components.interfaces.nsISupportsWeakReference) ||
-        iid.equals(Components.interfaces.nsISupports))
-      return this;
-    throw Components.results.NS_NOINTERFACE;
-  }
-}
-
-function test_handlerSimple(metadata, response) {
-  response.setHeader("Content-Type", "text/html", false);
-  response.setStatusLine(metadata.httpVersion, 200, "OK");
-  response.bodyOutputStream.write(originalBody, originalBody.length);
-}
-
-function test_modify() { 
-  sendCommand(`makeRequest("http://localhost:${PORT}/testSimple", "${replacedBody}");`);
-}
-
-
-function stopServer() {
-  observer.unregister();
-  httpserver.stop(do_test_finished)
-}
-
-function run_test() {
-
-  observer = new HttpResponseExaminer();
-  observer.register();
-
-  httpserver.registerPathHandler("/testSimple", test_handlerSimple);
-
-  run_test_in_child("child_tracable_listener.js", test_modify);
-}
--- a/netwerk/test/unit_ipc/xpcshell.ini
+++ b/netwerk/test/unit_ipc/xpcshell.ini
@@ -1,15 +1,14 @@
 [DEFAULT]
 head = head_channels_clone.js head_cc.js
 tail =
 skip-if = toolkit == 'android'
 support-files =
   child_channel_id.js
-  child_tracable_listener.js
   !/netwerk/test/unit/test_XHR_redirects.js
   !/netwerk/test/unit/test_bug248970_cookie.js
   !/netwerk/test/unit/test_bug528292.js
   !/netwerk/test/unit/test_cache_jar.js
   !/netwerk/test/unit/test_cacheflags.js
   !/netwerk/test/unit/test_channel_close.js
   !/netwerk/test/unit/test_cookie_header.js
   !/netwerk/test/unit/test_cookiejars.js
@@ -94,12 +93,10 @@ skip-if = true
 [test_XHR_redirects.js]
 [test_redirect_history_wrap.js]
 [test_reply_without_content_type_wrap.js]
 [test_getHost_wrap.js]
 [test_alt-data_simple_wrap.js]
 [test_alt-data_stream_wrap.js]
 [test_original_sent_received_head_wrap.js]
 [test_channel_id.js]
-[test_traceable_channel_modify_response.js]
-[test_traceable_channel_decoded_data.js]
 [test_trackingProtection_annotateChannels_wrap1.js]
 [test_trackingProtection_annotateChannels_wrap2.js]