Bug 1487113 - nsICacheInfoChannel.alternativeDataInputStream as attribute, r=valentin
☠☠ backed out by 3a8b999553a4 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 20 May 2019 15:22:47 +0000
changeset 474539 dce59b6155685fb271e2affd84e5e4b44e0ec8d5
parent 474538 e6f5797526782b2d60bac6a8a167997464751654
child 474540 41c511d9528cbabc101652c2a41c627ef8945db2
push id36042
push userdvarga@mozilla.com
push dateTue, 21 May 2019 04:19:40 +0000
treeherdermozilla-central@ca560ff55451 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvalentin
bugs1487113
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1487113 - nsICacheInfoChannel.alternativeDataInputStream as attribute, r=valentin Differential Revision: https://phabricator.services.mozilla.com/D31791
netwerk/base/nsICacheInfoChannel.idl
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/InterceptedHttpChannel.cpp
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/test/unit/test_alt-data_stream.js
netwerk/test/unit_ipc/test_alt-data_cross_process_wrap.js
--- a/netwerk/base/nsICacheInfoChannel.idl
+++ b/netwerk/base/nsICacheInfoChannel.idl
@@ -135,21 +135,20 @@ interface nsICacheInfoChannel : nsISuppo
    * Is empty string if no alternative data representation was requested, or
    * if the requested representation wasn't found in the cache.
    * Can only be called during or after OnStartRequest.
    */
   readonly attribute ACString alternativeDataType;
 
   /**
    * If preferAlternativeDataType() has been called passing deliverAltData
-   * equal to false, this method will expose the alt-data inputStream if
-   * aviable.
+   * equal to false, this attribute will expose the alt-data inputStream if
+   * avaiable.
    */
-  void getAltDataInputStream(in ACString type,
-                             in nsIInputStreamReceiver aReceiver);
+  readonly attribute nsIInputStream alternativeDataInputStream;
 
   /**
    * Sometimes when the channel is delivering alt-data, we may want to somehow
    * access the original content too.
    */
   readonly attribute nsIInputStream originalInputStream;
 
   /**
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -406,16 +406,17 @@ class StartRequestEvent : public NeckoTa
                     const int32_t& aCacheFetchCount,
                     const uint32_t& aCacheExpirationTime,
                     const nsCString& aCachedCharset,
                     const nsCString& aSecurityInfoSerialization,
                     const NetAddr& aSelfAddr, const NetAddr& aPeerAddr,
                     const uint32_t& aCacheKey, const nsCString& altDataType,
                     const int64_t& altDataLen, const bool& deliveringAltData,
                     already_AddRefed<nsIInputStream> originalCacheInputStream,
+                    already_AddRefed<nsIInputStream> altDataInputStream,
                     const bool& aApplyConversion, const bool& aIsResolvedByTRR,
                     const ResourceTimingStruct& aTiming)
       : NeckoTargetChannelEvent<HttpChannelChild>(aChild),
         mChannelStatus(aChannelStatus),
         mResponseHead(aResponseHead),
         mRequestHeaders(aRequestHeaders),
         mUseResponseHead(aUseResponseHead),
         mApplyConversion(aApplyConversion),
@@ -429,30 +430,31 @@ class StartRequestEvent : public NeckoTa
         mSecurityInfoSerialization(aSecurityInfoSerialization),
         mSelfAddr(aSelfAddr),
         mPeerAddr(aPeerAddr),
         mCacheKey(aCacheKey),
         mAltDataType(altDataType),
         mAltDataLen(altDataLen),
         mDeliveringAltData(deliveringAltData),
         mOriginalCacheInputStream(originalCacheInputStream),
+        mAltDataInputStream(altDataInputStream),
         mLoadInfoForwarder(loadInfoForwarder),
         mIsResolvedByTRR(aIsResolvedByTRR),
         mTiming(aTiming) {}
 
   void Run() override {
     LOG(("StartRequestEvent [this=%p]\n", mChild));
     mChild->OnStartRequest(
         mChannelStatus, mResponseHead, mUseResponseHead, mRequestHeaders,
         mLoadInfoForwarder, mIsFromCache, mIsRacing, mCacheEntryAvailable,
         mCacheEntryId, mCacheFetchCount, mCacheExpirationTime, mCachedCharset,
         mSecurityInfoSerialization, mSelfAddr, mPeerAddr, mCacheKey,
         mAltDataType, mAltDataLen, mDeliveringAltData,
-        mOriginalCacheInputStream.forget(), mApplyConversion, mIsResolvedByTRR,
-        mTiming);
+        mOriginalCacheInputStream.forget(), mAltDataInputStream.forget(),
+        mApplyConversion, mIsResolvedByTRR, mTiming);
   }
 
  private:
   nsresult mChannelStatus;
   nsHttpResponseHead mResponseHead;
   nsHttpHeaderArray mRequestHeaders;
   bool mUseResponseHead;
   bool mApplyConversion;
@@ -466,16 +468,17 @@ class StartRequestEvent : public NeckoTa
   nsCString mSecurityInfoSerialization;
   NetAddr mSelfAddr;
   NetAddr mPeerAddr;
   uint32_t mCacheKey;
   nsCString mAltDataType;
   int64_t mAltDataLen;
   bool mDeliveringAltData;
   nsCOMPtr<nsIInputStream> mOriginalCacheInputStream;
+  nsCOMPtr<nsIInputStream> mAltDataInputStream;
   ParentLoadInfoForwarderArgs mLoadInfoForwarder;
   bool mIsResolvedByTRR;
   ResourceTimingStruct mTiming;
 };
 
 mozilla::ipc::IPCResult HttpChannelChild::RecvOnStartRequest(
     const nsresult& channelStatus, const nsHttpResponseHead& responseHead,
     const bool& useResponseHead, const nsHttpHeaderArray& requestHeaders,
@@ -484,41 +487,45 @@ mozilla::ipc::IPCResult HttpChannelChild
     const bool& cacheEntryAvailable, const uint64_t& cacheEntryId,
     const int32_t& cacheFetchCount, 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 int64_t& altDataLen,
     const bool& deliveringAltData,
     const Maybe<IPCStream>& aOriginalCacheInputStream,
-    const bool& aApplyConversion, const bool& aIsResolvedByTRR,
-    const ResourceTimingStruct& aTiming) {
+    const Maybe<IPCStream>& aAltDataInputStream, const bool& aApplyConversion,
+    const bool& aIsResolvedByTRR, const ResourceTimingStruct& aTiming) {
   AUTO_PROFILER_LABEL("HttpChannelChild::RecvOnStartRequest", NETWORK);
   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;
 
   nsCOMPtr<nsIInputStream> originalCacheInputStream =
       DeserializeIPCStream(aOriginalCacheInputStream);
 
+  nsCOMPtr<nsIInputStream> altDataInputStream =
+      DeserializeIPCStream(aAltDataInputStream);
+
   mEventQ->RunOrEnqueue(new StartRequestEvent(
       this, channelStatus, responseHead, useResponseHead, requestHeaders,
       loadInfoForwarder, isFromCache, isRacing, cacheEntryAvailable,
       cacheEntryId, cacheFetchCount, cacheExpirationTime, cachedCharset,
       securityInfoSerialization, selfAddr, peerAddr, cacheKey, altDataType,
       altDataLen, deliveringAltData, originalCacheInputStream.forget(),
-      aApplyConversion, aIsResolvedByTRR, aTiming));
+      altDataInputStream.forget(), aApplyConversion, aIsResolvedByTRR,
+      aTiming));
 
   {
     // Child's mEventQ is to control the execution order of the IPC messages
     // from both main thread IPDL and PBackground IPDL.
     // To guarantee the ordering, PBackground IPC messages that are sent after
     // OnStartRequest will be throttled until OnStartRequest hits the Child's
     // mEventQ.
     MutexAutoLock lock(mBgChildMutex);
@@ -543,30 +550,32 @@ void HttpChannelChild::OnStartRequest(
     const bool& isFromCache, const bool& isRacing,
     const bool& cacheEntryAvailable, const uint64_t& cacheEntryId,
     const int32_t& cacheFetchCount, const uint32_t& cacheExpirationTime,
     const nsCString& cachedCharset, const nsCString& securityInfoSerialization,
     const NetAddr& selfAddr, const NetAddr& peerAddr, const uint32_t& cacheKey,
     const nsCString& altDataType, const int64_t& altDataLen,
     const bool& deliveringAltData,
     already_AddRefed<nsIInputStream> originalCacheInputStream,
+    already_AddRefed<nsIInputStream> altDataInputStream,
     const bool& aApplyConversion, const bool& aIsResolvedByTRR,
     const ResourceTimingStruct& aTiming) {
   LOG(("HttpChannelChild::OnStartRequest [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!");
 
   mOriginalCacheInputStream = originalCacheInputStream;
+  mAltDataInputStream = altDataInputStream;
 
   // If this channel was aborted by ActorDestroy, then there may be other
   // OnStartRequest/OnStopRequest/OnDataAvailable IPC messages that need to
   // be handled. In that case we just ignore them to avoid calling the listener
   // twice.
   if (mOnStartRequestCalled && mIPCActorDeleted) {
     return;
   }
@@ -3261,44 +3270,25 @@ HttpChannelChild::GetOriginalInputStream
 
   nsCOMPtr<nsIInputStream> is = mOriginalCacheInputStream;
   is.forget(aInputStream);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HttpChannelChild::GetAltDataInputStream(const nsACString& aType,
-                                        nsIInputStreamReceiver* aReceiver) {
-  if (aReceiver == nullptr) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  if (!mIPCOpen) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  mAltDataInputStreamReceiver = aReceiver;
-  Unused << SendOpenAltDataCacheInputStream(nsCString(aType));
+HttpChannelChild::GetAlternativeDataInputStream(nsIInputStream** aInputStream) {
+  NS_ENSURE_ARG_POINTER(aInputStream);
+
+  nsCOMPtr<nsIInputStream> is = mAltDataInputStream;
+  is.forget(aInputStream);
 
   return NS_OK;
 }
 
-mozilla::ipc::IPCResult HttpChannelChild::RecvAltDataCacheInputStreamAvailable(
-    const Maybe<IPCStream>& aStream) {
-  nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(aStream);
-  nsCOMPtr<nsIInputStreamReceiver> receiver;
-  receiver.swap(mAltDataInputStreamReceiver);
-  if (receiver) {
-    receiver->OnInputStreamReady(stream);
-  }
-
-  return IPC_OK();
-}
-
 //-----------------------------------------------------------------------------
 // HttpChannelChild::nsIResumableChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpChannelChild::ResumeAt(uint64_t startPos, const nsACString& entityID) {
   LOG(("HttpChannelChild::ResumeAt [this=%p]\n", this));
   ENSURE_CALLED_BEFORE_CONNECT();
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -142,17 +142,18 @@ class HttpChannelChild final : public PH
       const bool& cacheEntryAvailable, const uint64_t& cacheEntryId,
       const int32_t& cacheFetchCount, 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 int64_t& altDataLen, const bool& deliveringAltData,
       const Maybe<IPCStream>& originalCacheInputStream,
-      const bool& aApplyConversion, const bool& aIsResolvedByTRR,
+      const Maybe<IPCStream>& altDataInputStream, const bool& aApplyConversion,
+      const bool& aIsResolvedByTRR,
       const ResourceTimingStruct& aTiming) override;
   mozilla::ipc::IPCResult RecvFailedAsyncOpen(const nsresult& status) override;
   mozilla::ipc::IPCResult RecvRedirect1Begin(
       const uint32_t& registrarId, const URIParams& newURI,
       const uint32_t& newLoadFlags, const uint32_t& redirectFlags,
       const ParentLoadInfoForwarderArgs& loadInfoForwarder,
       const nsHttpResponseHead& responseHead,
       const nsCString& securityInfoSerialization, const uint64_t& channelId,
@@ -173,19 +174,16 @@ class HttpChannelChild final : public PH
 
   mozilla::ipc::IPCResult RecvAttachStreamFilter(
       Endpoint<extensions::PStreamFilterParent>&& aEndpoint) override;
 
   mozilla::ipc::IPCResult RecvCancelDiversion() override;
 
   mozilla::ipc::IPCResult RecvCancelRedirected() override;
 
-  mozilla::ipc::IPCResult RecvAltDataCacheInputStreamAvailable(
-      const Maybe<IPCStream>& aStream) override;
-
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual void DoNotifyListenerCleanup() override;
 
   virtual void DoAsyncAbort(nsresult aStatus) override;
 
   nsresult AsyncCall(
       void (HttpChannelChild::*funcPtr)(),
@@ -344,17 +342,17 @@ class HttpChannelChild final : public PH
   RequestHeaderTuples mClientSetRequestHeaders;
   RefPtr<nsInputStreamPump> mSynthesizedResponsePump;
   nsCOMPtr<nsIInputStream> mSynthesizedInput;
   nsCOMPtr<nsIInterceptedBodyCallback> mSynthesizedCallback;
   nsCOMPtr<nsICacheInfoChannel> mSynthesizedCacheInfo;
   RefPtr<ChannelEventQueue> mEventQ;
 
   nsCOMPtr<nsIInputStream> mOriginalCacheInputStream;
-  nsCOMPtr<nsIInputStreamReceiver> mAltDataInputStreamReceiver;
+  nsCOMPtr<nsIInputStream> mAltDataInputStream;
 
   // Used to ensure atomicity of mBgChild and mBgInitFailCallback
   Mutex mBgChildMutex;
 
   // Associated HTTP background channel
   RefPtr<HttpBackgroundChannelChild> mBgChild;
 
   // Error handling procedure if failed to establish PBackground IPC
@@ -473,16 +471,17 @@ class HttpChannelChild final : public PH
       const bool& cacheEntryAvailable, const uint64_t& cacheEntryId,
       const int32_t& cacheFetchCount, const uint32_t& cacheExpirationTime,
       const nsCString& cachedCharset,
       const nsCString& securityInfoSerialization, const NetAddr& selfAddr,
       const NetAddr& peerAddr, const uint32_t& cacheKey,
       const nsCString& altDataType, const int64_t& altDataLen,
       const bool& deliveringAltData,
       already_AddRefed<nsIInputStream> originalCacheInputStream,
+      already_AddRefed<nsIInputStream> altDataInputStream,
       const bool& aApplyConversion, const bool& aIsResolvedByTRR,
       const ResourceTimingStruct& aTiming);
   void MaybeDivertOnData(const nsCString& data, const uint64_t& offset,
                          const uint32_t& count);
   void OnTransportAndData(const nsresult& channelStatus, const nsresult& status,
                           const uint64_t& offset, const uint32_t& count,
                           const nsCString& data);
   void OnStopRequest(const nsresult& channelStatus,
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1463,37 +1463,54 @@ HttpChannelParent::OnStartRequest(nsIReq
 
   ResourceTimingStruct timing;
   GetTimingAttributes(mChannel, timing);
 
   bool isResolvedByTRR = false;
   chan->GetIsResolvedByTRR(&isResolvedByTRR);
 
   AutoIPCStream originalCacheInputStream(true /* delay start */);
+  AutoIPCStream altDataInputStream(true /* delay start */);
+
   if (mCacheEntry) {
-    nsCOMPtr<nsIInputStream> inputStream;
-    nsresult rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
-    if (NS_SUCCEEDED(rv)) {
-      PContentParent* pcp = Manager()->Manager();
-      Unused << originalCacheInputStream.Serialize(
-          inputStream, static_cast<ContentParent*>(pcp));
+    PContentParent* pcp = Manager()->Manager();
+
+    {
+      nsCOMPtr<nsIInputStream> inputStream;
+      nsresult rv =
+          mCacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
+      if (NS_SUCCEEDED(rv)) {
+        Unused << originalCacheInputStream.Serialize(
+            inputStream, static_cast<ContentParent*>(pcp));
+      }
+    }
+
+    if (!altDataType.IsEmpty()) {
+      nsCOMPtr<nsIInputStream> inputStream;
+      nsresult rv = mCacheEntry->OpenAlternativeInputStream(
+          altDataType, getter_AddRefs(inputStream));
+      if (NS_SUCCEEDED(rv)) {
+        Unused << altDataInputStream.Serialize(
+            inputStream, static_cast<ContentParent*>(pcp));
+      }
     }
   }
 
   rv = NS_OK;
   if (mIPCClosed ||
       !SendOnStartRequest(
           channelStatus, *responseHead, useResponseHead,
           cleanedUpRequest ? cleanedUpRequestHeaders : requestHead->Headers(),
           loadInfoForwarderArg, isFromCache, isRacing,
           mCacheEntry ? true : false, cacheEntryId, fetchCount, expirationTime,
           cachedCharset, secInfoSerialization, chan->GetSelfAddr(),
           chan->GetPeerAddr(), redirectCount, cacheKey, altDataType, altDataLen,
           deliveringAltData, originalCacheInputStream.TakeOptionalValue(),
-          applyConversion, isResolvedByTRR, timing)) {
+          altDataInputStream.TakeOptionalValue(), applyConversion,
+          isResolvedByTRR, timing)) {
     rv = NS_ERROR_UNEXPECTED;
   }
   requestHead->Exit();
 
   // OnStartRequest is sent to content process successfully.
   // Notify PHttpBackgroundChannelChild that all following IPC mesasges
   // should be run after OnStartRequest is handled.
   if (NS_SUCCEEDED(rv)) {
@@ -1699,38 +1716,16 @@ mozilla::ipc::IPCResult HttpChannelParen
     mSuspendedForFlowControl = false;
 
     mResumedTimestamp = TimeStamp::Now();
   }
   mSendWindowSize += aCount;
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult HttpChannelParent::RecvOpenAltDataCacheInputStream(
-    const nsCString& aType) {
-  if (mIPCClosed) {
-    return IPC_OK();
-  }
-  AutoIPCStream autoStream;
-  if (mCacheEntry) {
-    nsCOMPtr<nsIInputStream> inputStream;
-    nsresult rv = mCacheEntry->OpenAlternativeInputStream(
-        aType, getter_AddRefs(inputStream));
-    if (NS_SUCCEEDED(rv)) {
-      PContentParent* pcp = Manager()->Manager();
-      Unused << autoStream.Serialize(inputStream,
-                                     static_cast<ContentParent*>(pcp));
-    }
-  }
-
-  Unused << SendAltDataCacheInputStreamAvailable(
-      autoStream.TakeOptionalValue());
-  return IPC_OK();
-}
-
 //-----------------------------------------------------------------------------
 // HttpChannelParent::nsIProgressEventSink
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpChannelParent::OnProgress(nsIRequest* aRequest, nsISupports* aContext,
                               int64_t aProgress, int64_t aProgressMax) {
   LOG(("HttpChannelParent::OnStatus [this=%p progress=%" PRId64 "max=%" PRId64
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -200,18 +200,16 @@ class HttpChannelParent final : public n
       const nsresult& statusCode) override;
   virtual mozilla::ipc::IPCResult RecvDivertComplete() override;
   virtual mozilla::ipc::IPCResult RecvCrossProcessRedirectDone(
       const nsresult& aResult) override;
   virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(
       const URIParams& uri,
       const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;
   virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override;
-  virtual mozilla::ipc::IPCResult RecvOpenAltDataCacheInputStream(
-      const nsCString& aType) override;
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   // Supporting function for ADivertableParentChannel.
   MOZ_MUST_USE nsresult ResumeForDiversion();
 
   // Asynchronously calls NotifyDiversionFailed.
   void FailDiversion(nsresult aErrorCode);
 
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
@@ -1287,20 +1287,20 @@ NS_IMETHODIMP
 InterceptedHttpChannel::GetOriginalInputStream(nsIInputStream** aStream) {
   if (mSynthesizedCacheInfo) {
     return mSynthesizedCacheInfo->GetOriginalInputStream(aStream);
   }
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
-InterceptedHttpChannel::GetAltDataInputStream(
-    const nsACString& aType, nsIInputStreamReceiver* aReceiver) {
+InterceptedHttpChannel::GetAlternativeDataInputStream(
+    nsIInputStream** aInputStream) {
   if (mSynthesizedCacheInfo) {
-    return mSynthesizedCacheInfo->GetAltDataInputStream(aType, aReceiver);
+    return mSynthesizedCacheInfo->GetAlternativeDataInputStream(aInputStream);
   }
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
 InterceptedHttpChannel::GetCacheKey(uint32_t* key) {
   if (mSynthesizedCacheInfo) {
     return mSynthesizedCacheInfo->GetCacheKey(key);
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -89,19 +89,16 @@ 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();
 
-  // Called to get the input stream when altData is available.
-  async OpenAltDataCacheInputStream(nsCString aType);
-
   // Tell the parent the amount bytes read by child for the e10s back pressure
   // flow control
   async BytesRead(int32_t count);
 
   async __delete__();
 
 child:
   async OnStartRequest(nsresult            channelStatus,
@@ -120,16 +117,17 @@ child:
                        NetAddr             selfAddr,
                        NetAddr             peerAddr,
                        int16_t             redirectCount,
                        uint32_t            cacheKey,
                        nsCString           altDataType,
                        int64_t             altDataLength,
                        bool                deliveringAltData,
                        IPCStream?          originalCacheInputStream,
+                       IPCStream?          altDataInputStream,
                        bool                applyConversion,
                        bool                isResolvedByTRR,
                        ResourceTimingStruct timing);
 
   // Used to cancel child channel if we hit errors during creating and
   // AsyncOpen of nsHttpChannel on the parent.
   async FailedAsyncOpen(nsresult status);
 
@@ -178,18 +176,16 @@ child:
                             nsString url,
                             nsString contentType);
 
   async AttachStreamFilter(Endpoint<PStreamFilterParent> aEndpoint);
 
   // See ADivertableParentChannel::CancelDiversion
   async CancelDiversion();
 
-  async AltDataCacheInputStreamAvailable(IPCStream? stream);
-
 both:
   // After receiving this message, the parent also calls
   // SendFinishInterceptedRedirect, and makes sure not to send any more messages
   // after that. When receiving this message, the child will call
   // Send__delete__() and complete the steps required to finish the redirect.
   async FinishInterceptedRedirect();
 
   async SetPriority(int16_t priority);
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -8624,32 +8624,33 @@ nsHttpChannel::GetOriginalInputStream(ns
     nsresult rv = cacheEntry->OpenInputStream(0, aInputStream);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHttpChannel::GetAltDataInputStream(const nsACString& aType,
-                                     nsIInputStreamReceiver* aReceiver) {
-  if (aReceiver == nullptr) {
-    return NS_ERROR_INVALID_ARG;
-  }
-  nsCOMPtr<nsIInputStream> inputStream;
+nsHttpChannel::GetAlternativeDataInputStream(nsIInputStream** aInputStream) {
+  NS_ENSURE_ARG_POINTER(aInputStream);
+
+  *aInputStream = nullptr;
+
+  if (!mAfterOnStartRequestBegun) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
 
   nsCOMPtr<nsICacheEntry> cacheEntry =
       mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
-  if (cacheEntry) {
+  if (!mAvailableCachedAltDataType.IsEmpty() && cacheEntry) {
     nsresult rv = cacheEntry->OpenAlternativeInputStream(
-        aType, getter_AddRefs(inputStream));
+        mAvailableCachedAltDataType, aInputStream);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  aReceiver->OnInputStreamReady(inputStream);
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpChannel::nsICachingChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
--- a/netwerk/test/unit/test_alt-data_stream.js
+++ b/netwerk/test/unit/test_alt-data_stream.js
@@ -139,15 +139,11 @@ var originalListener = {
     Assert.equal(this.buffer.length, responseContent.length);
     Assert.equal(this.buffer, responseContent);
     testAltDataStream(cc);
   },
 };
 
 function testAltDataStream(cc)
 {
-  cc.getAltDataInputStream(altContentType, {
-    onInputStreamReady: function(aInputStream) {
-      Assert.ok(!!aInputStream);
-      httpServer.stop(do_test_finished);
-    }
-  });
+  Assert.ok(!!cc.alternativeDataInputStream);
+  httpServer.stop(do_test_finished);
 }
--- a/netwerk/test/unit_ipc/test_alt-data_cross_process_wrap.js
+++ b/netwerk/test/unit_ipc/test_alt-data_cross_process_wrap.js
@@ -4,22 +4,16 @@ const {Services} = ChromeUtils.import("r
 var cacheFlushObserver = { observe: function() {
   cacheFlushObserver = null;
   do_send_remote_message('flushed');
 }};
 
 // We get this from the child a bit later
 var URL = null;
 
-// needs to be rooted
-var cacheFlushObserver2 = { observe: function() {
-  cacheFlushObserver2 = null;
-  openAltChannel();
-}};
-
 function run_test() {
   do_get_profile();
   do_await_remote_message('flush').then(() => {
     Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(cacheFlushObserver);
   });
 
   do_await_remote_message('done').then(() => { sendCommand("URL;", load_channel); });
 
@@ -45,36 +39,12 @@ function readTextData(request, buffer)
   // Since we are in a different process from what that generated the alt-data,
   // we should receive the original data, not processed content.
   Assert.equal(cc.alternativeDataType, "");
   Assert.equal(buffer, "response body");
 
   // Now let's generate some alt-data in the parent, and make sure we can get it
   var altContent = "altContentParentGenerated";
   executeSoon(() => {
-    var os = cc.openAlternativeOutputStream("text/parent-binary", altContent.length);
-    os.write(altContent, altContent.length);
-    os.close();
-
-    executeSoon(() => {
-      Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(cacheFlushObserver2);
-    });
+    Assert.throws(() => cc.openAlternativeOutputStream("text/parent-binary", altContent.length), /NS_ERROR_NOT_AVAILABLE/);
+    do_send_remote_message('finish');
   });
 }
-
-function openAltChannel() {
-  var chan = make_channel(URL);
-  var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType("text/parent-binary", "", true);
-  chan.asyncOpen(new ChannelListener(readAltData, null));
-}
-
-function readAltData(request, buffer)
-{
-  var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
-
-  // This was generated in the parent, so it's OK to get it.
-  Assert.equal(buffer, "altContentParentGenerated");
-  Assert.equal(cc.alternativeDataType, "text/parent-binary");
-
-  // FINISH
-  do_send_remote_message('finish');
-}