Backed out 2 changesets (bug 1487100) for XPCShell failures in netwerk/test/unit_ipc/test_alt-data_simple_wrap.js
authorDorel Luca <dluca@mozilla.com>
Thu, 18 Oct 2018 05:51:42 +0300
changeset 500311 856c528a098312ad0ee77b5c6960993974ed19f4
parent 500310 8f1ae707ff7ba362c9931054c9f927141b20a2f7
child 500312 afdfeb4c004cbba91d4d9e30a0e80e6dfb0dce60
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1487100
milestone64.0a1
backs out7f9d03c29a6ffd82c1b5e17c14e27a2ae9d64434
dd1c31ea78c2b15d14750d137037a54d50719997
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 1487100) for XPCShell failures in netwerk/test/unit_ipc/test_alt-data_simple_wrap.js Backed out changeset 7f9d03c29a6f (bug 1487100) Backed out changeset dd1c31ea78c2 (bug 1487100)
dom/fetch/FetchDriver.cpp
dom/script/ScriptLoader.cpp
dom/serviceworkers/ServiceWorkerEvents.cpp
dom/serviceworkers/ServiceWorkerPrivate.cpp
netwerk/base/nsICacheInfoChannel.idl
netwerk/cache2/CacheEntry.cpp
netwerk/cache2/CacheEntry.h
netwerk/cache2/CacheFile.cpp
netwerk/cache2/CacheFile.h
netwerk/cache2/OldWrappers.cpp
netwerk/cache2/OldWrappers.h
netwerk/cache2/nsICacheEntry.idl
netwerk/ipc/NeckoChannelParams.ipdlh
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/InterceptedHttpChannel.cpp
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/PHttpChannelParams.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/protocol/viewsource/nsViewSourceChannel.h
netwerk/test/unit/test_alt-data_cross_process.js
netwerk/test/unit/test_alt-data_overwrite.js
netwerk/test/unit/test_alt-data_simple.js
netwerk/test/unit/test_alt-data_stream.js
netwerk/test/unit/test_cache-entry-id.js
netwerk/test/unit_ipc/test_alt-data_cross_process_wrap.js
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -729,17 +729,17 @@ FetchDriver::HttpFetch(const nsACString&
   }
 
   // if the preferred alternative data type in InternalRequest is not empty, set
   // the data type on the created channel and also create a AlternativeDataStreamListener
   // to be the stream listener of the channel.
   if (!aPreferredAlternativeDataType.IsEmpty()) {
     nsCOMPtr<nsICacheInfoChannel> cic = do_QueryInterface(chan);
     if (cic) {
-      cic->PreferAlternativeDataType(aPreferredAlternativeDataType, EmptyCString());
+      cic->PreferAlternativeDataType(aPreferredAlternativeDataType);
       MOZ_ASSERT(!mAltDataListener);
       mAltDataListener =
         new AlternativeDataStreamListener(this, chan, aPreferredAlternativeDataType);
       rv = chan->AsyncOpen2(mAltDataListener);
     } else {
       rv = chan->AsyncOpen2(this);
     }
   } else {
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -1104,26 +1104,26 @@ ScriptLoader::StartLoad(ScriptLoadReques
   nsCOMPtr<nsICacheInfoChannel> cic(do_QueryInterface(channel));
   if (cic && nsContentUtils::IsBytecodeCacheEnabled() &&
       // Bug 1436400: no bytecode cache support for modules yet.
       !aRequest->IsModuleRequest()) {
     if (!aRequest->IsLoadingSource()) {
       // Inform the HTTP cache that we prefer to have information coming from the
       // bytecode cache instead of the sources, if such entry is already registered.
       LOG(("ScriptLoadRequest (%p): Maybe request bytecode", aRequest));
-      cic->PreferAlternativeDataType(nsContentUtils::JSBytecodeMimeType(), EmptyCString());
+      cic->PreferAlternativeDataType(nsContentUtils::JSBytecodeMimeType());
     } else {
       // If we are explicitly loading from the sources, such as after a
       // restarted request, we might still want to save the bytecode after.
       //
       // The following tell the cache to look for an alternative data type which
       // does not exist, such that we can later save the bytecode with a
       // different alternative data type.
       LOG(("ScriptLoadRequest (%p): Request saving bytecode later", aRequest));
-      cic->PreferAlternativeDataType(kNullMimeType, EmptyCString());
+      cic->PreferAlternativeDataType(kNullMimeType);
     }
   }
 
   LOG(("ScriptLoadRequest (%p): mode=%u tracking=%d",
        aRequest, unsigned(aRequest->mScriptMode), aRequest->IsTracking()));
 
   nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(channel));
   if (cos) {
--- a/dom/serviceworkers/ServiceWorkerEvents.cpp
+++ b/dom/serviceworkers/ServiceWorkerEvents.cpp
@@ -338,19 +338,18 @@ public:
     }
 
     auto castLoadInfo = static_cast<mozilla::net::LoadInfo*>(loadInfo.get());
     castLoadInfo->SynthesizeServiceWorkerTainting(mInternalResponse->GetTainting());
 
     // Get the preferred alternative data type of outter channel
     nsAutoCString preferredAltDataType(EmptyCString());
     nsCOMPtr<nsICacheInfoChannel> outerChannel = do_QueryInterface(underlyingChannel);
-    if (outerChannel && !outerChannel->PreferredAlternativeDataTypes().IsEmpty()) {
-      // TODO: handle multiple types properly.
-      preferredAltDataType.Assign(mozilla::Get<0>(outerChannel->PreferredAlternativeDataTypes()[0]));
+    if (outerChannel) {
+      outerChannel->GetPreferredAlternativeDataType(preferredAltDataType);
     }
 
     // Get the alternative data type saved in the InternalResponse
     nsAutoCString altDataType;
     nsCOMPtr<nsICacheInfoChannel> cacheInfoChannel =
       mInternalResponse->TakeCacheInfoChannel().get();
     if (cacheInfoChannel) {
       cacheInfoChannel->GetAlternativeDataType(altDataType);
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -1582,21 +1582,21 @@ private:
     internalReq->SetBody(mUploadStream, mUploadStreamContentLength);
     // For Telemetry, note that this Request object was created by a Fetch event.
     internalReq->SetCreatedByFetchEvent();
 
     nsCOMPtr<nsIChannel> channel;
     nsresult rv = mInterceptedChannel->GetChannel(getter_AddRefs(channel));
     NS_ENSURE_SUCCESS(rv, false);
 
+    nsAutoCString alternativeDataType;
     nsCOMPtr<nsICacheInfoChannel> cic = do_QueryInterface(channel);
-    if (cic && !cic->PreferredAlternativeDataTypes().IsEmpty()) {
-      // TODO: the internal request probably needs all the preferred types.
-      nsAutoCString alternativeDataType;
-      alternativeDataType.Assign(mozilla::Get<0>(cic->PreferredAlternativeDataTypes()[0]));
+    if (cic &&
+        NS_SUCCEEDED(cic->GetPreferredAlternativeDataType(alternativeDataType)) &&
+        !alternativeDataType.IsEmpty()) {
       internalReq->SetPreferredAlternativeDataType(alternativeDataType);
     }
 
     nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(globalObj.GetAsSupports());
     if (NS_WARN_IF(!global)) {
       return false;
     }
 
--- a/netwerk/base/nsICacheInfoChannel.idl
+++ b/netwerk/base/nsICacheInfoChannel.idl
@@ -1,30 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIOutputStream;
-interface nsIInputStream;
-
-%{C++
-namespace mozilla {
-template<typename... Elements> class Tuple;
-} // namespace mozilla
-%}
-
-[ref] native ConstPreferenceArray(const nsTArray<mozilla::Tuple<nsCString, nsCString>>);
-
-[scriptable, uuid(1fb8ccf2-5fa5-45ec-bc57-8c8022a5d0d3)]
-interface nsIInputStreamReceiver : nsISupports
-{
-  void onInputStreamReady(in nsIInputStream aStream);
-};
 
 [scriptable, uuid(72c34415-c6eb-48af-851f-772fa9ee5972)]
 interface nsICacheInfoChannel : nsISupports
 {
   /**
    * Get the number of times the cache entry has been opened. This attribute is
    * equivalent to nsICachingChannel.cacheToken.fetchCount.
    *
@@ -89,53 +74,37 @@ interface nsICacheInfoChannel : nsISuppo
    * channel being the default load group's channel.
    */
   attribute boolean allowStaleCacheContent;
 
   /**
    * Calling this method instructs the channel to serve the alternative data
    * if that was previously saved in the cache, otherwise it will serve the
    * real data.
-   * @param type
-   *        a string identifying the alt-data format
-   * @param contentType
-   *        the contentType for which the preference applies.
-   *        an empty contentType means the preference applies for ANY contentType
-   *
-   * The method may be called several times, with different type and contentType.
-   *
    * Must be called before AsyncOpen.
    */
-  void preferAlternativeDataType(in ACString type, in ACString contentType);
+  void preferAlternativeDataType(in ACString type);
 
   /**
    * Get the preferred alternative data type set by preferAlternativeDataType().
-   * The returned types stand for the desired data type instead of the type of the
+   * This attribute stands for the desired data type instead of the type of the
    * information retrieved from the network stack.
    */
-  [noscript, notxpcom, nostdcall]
-  ConstPreferenceArray preferredAlternativeDataTypes();
+  readonly attribute ACString preferredAlternativeDataType;
 
   /**
    * Holds the type of the alternative data representation that the channel
    * is returning.
    * 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;
 
   /**
-   * Sometimes when the channel is delivering alt-data, we may want to somehow
-   * access the original content too. This method asynchronously opens the
-   * input stream and delivers it to the receiver.
-   */
-  void getOriginalInputStream(in nsIInputStreamReceiver aReceiver);
-
-  /**
    * Opens and returns an output stream that a consumer may use to save an
    * alternate representation of the data.
    * Must be called after the OnStopRequest that delivered the real data.
    * The consumer may choose to replace the saved alt representation.
    * Opening the output stream will fail if there are any open input streams
    * reading the already saved alt representation.
    *
    * @param type
--- a/netwerk/cache2/CacheEntry.cpp
+++ b/netwerk/cache2/CacheEntry.cpp
@@ -1270,21 +1270,16 @@ nsresult CacheEntry::OpenOutputStream(in
 
 nsresult CacheEntry::OpenAlternativeOutputStream(const nsACString & type, int64_t predictedSize, nsIOutputStream * *_retval)
 {
   LOG(("CacheEntry::OpenAlternativeOutputStream [this=%p, type=%s]", this,
        PromiseFlatCString(type).get()));
 
   nsresult rv;
 
-  if (type.IsEmpty()) {
-    // The empty string is reserved to mean no alt-data available.
-    return NS_ERROR_INVALID_ARG;
-  }
-
   mozilla::MutexAutoLock lock(mLock);
 
   if (!mHasData || mState < READY || mOutputStream || mIsDoomed) {
     LOG(("  entry not in state to write alt-data"));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (mFile->EntryWouldExceedLimit(0, predictedSize, true)) {
@@ -1554,33 +1549,26 @@ nsresult CacheEntry::GetDataSize(int64_t
     LOG(("  write in progress (stream active)"));
     return NS_ERROR_IN_PROGRESS;
   }
 
   LOG(("  size=%" PRId64, *aDataSize));
   return NS_OK;
 }
 
+
 nsresult CacheEntry::GetAltDataSize(int64_t *aDataSize)
 {
   LOG(("CacheEntry::GetAltDataSize [this=%p]", this));
   if (NS_FAILED(mFileStatus)) {
     return mFileStatus;
   }
   return mFile->GetAltDataSize(aDataSize);
 }
 
-nsresult CacheEntry::GetAltDataType(nsACString &aType)
-{
-  LOG(("CacheEntry::GetAltDataType [this=%p]", this));
-  if (NS_FAILED(mFileStatus)) {
-    return mFileStatus;
-  }
-  return mFile->GetAltDataType(aType);
-}
 
 nsresult CacheEntry::MarkValid()
 {
   // NOT IMPLEMENTED ACTUALLY
   return NS_OK;
 }
 
 nsresult CacheEntry::MaybeMarkValid()
--- a/netwerk/cache2/CacheEntry.h
+++ b/netwerk/cache2/CacheEntry.h
@@ -88,17 +88,16 @@ public:
   nsresult SetMetaDataElement(const char * key, const char * value);
   nsresult VisitMetaData(nsICacheEntryMetaDataVisitor *visitor);
   nsresult MetaDataReady(void);
   nsresult SetValid(void);
   nsresult GetDiskStorageSizeInKB(uint32_t *aDiskStorageSizeInKB);
   nsresult Recreate(bool aMemoryOnly, nsICacheEntry * *_retval);
   nsresult GetDataSize(int64_t *aDataSize);
   nsresult GetAltDataSize(int64_t *aAltDataSize);
-  nsresult GetAltDataType(nsACString &aAltDataType);
   nsresult OpenAlternativeOutputStream(const nsACString & type, int64_t predictedSize, nsIOutputStream * *_retval);
   nsresult OpenAlternativeInputStream(const nsACString & type, nsIInputStream * *_retval);
   nsresult GetLoadContextInfo(nsILoadContextInfo * *aLoadContextInfo);
   nsresult Close(void);
   nsresult MarkValid(void);
   nsresult MaybeMarkValid(void);
   nsresult HasWriteAccess(bool aWriteAllowed, bool *_retval);
 
@@ -457,17 +456,16 @@ public:
   NS_IMETHOD SetMetaDataElement(const char * key, const char * value) override { return mEntry->SetMetaDataElement(key, value); }
   NS_IMETHOD VisitMetaData(nsICacheEntryMetaDataVisitor *visitor) override { return mEntry->VisitMetaData(visitor); }
   NS_IMETHOD MetaDataReady(void) override { return mEntry->MetaDataReady(); }
   NS_IMETHOD SetValid(void) override { return mEntry->SetValid(); }
   NS_IMETHOD GetDiskStorageSizeInKB(uint32_t *aDiskStorageSizeInKB) override { return mEntry->GetDiskStorageSizeInKB(aDiskStorageSizeInKB); }
   NS_IMETHOD Recreate(bool aMemoryOnly, nsICacheEntry * *_retval) override { return mEntry->Recreate(aMemoryOnly, _retval); }
   NS_IMETHOD GetDataSize(int64_t *aDataSize) override { return mEntry->GetDataSize(aDataSize); }
   NS_IMETHOD GetAltDataSize(int64_t *aAltDataSize) override { return mEntry->GetAltDataSize(aAltDataSize); }
-  NS_IMETHOD GetAltDataType(nsACString &aType) override { return mEntry->GetAltDataType(aType); }
   NS_IMETHOD OpenAlternativeOutputStream(const nsACString & type, int64_t predictedSize, nsIOutputStream * *_retval) override { return mEntry->OpenAlternativeOutputStream(type, predictedSize, _retval); }
   NS_IMETHOD OpenAlternativeInputStream(const nsACString & type, nsIInputStream * *_retval) override { return mEntry->OpenAlternativeInputStream(type, _retval); }
   NS_IMETHOD GetLoadContextInfo(nsILoadContextInfo * *aLoadContextInfo) override { return mEntry->GetLoadContextInfo(aLoadContextInfo); }
   NS_IMETHOD Close(void) override { return mEntry->Close(); }
   NS_IMETHOD MarkValid(void) override { return mEntry->MarkValid(); }
   NS_IMETHOD MaybeMarkValid(void) override { return mEntry->MaybeMarkValid(); }
   NS_IMETHOD HasWriteAccess(bool aWriteAllowed, bool *_retval) override { return mEntry->HasWriteAccess(aWriteAllowed, _retval); }
 
--- a/netwerk/cache2/CacheFile.cpp
+++ b/netwerk/cache2/CacheFile.cpp
@@ -642,23 +642,22 @@ CacheFile::OnMetadataRead(nsresult aResu
     mDataSize = mMetadata->Offset();
     if (mDataSize == 0 && mMetadata->ElementsSize() == 0) {
       isNew = true;
       mMetadata->MarkDirty();
     } else {
       const char *altData = mMetadata->GetElement(CacheFileUtils::kAltDataKey);
       if (altData &&
           (NS_FAILED(CacheFileUtils::ParseAlternativeDataInfo(
-            altData, &mAltDataOffset, &mAltDataType)) ||
+            altData, &mAltDataOffset, nullptr)) ||
           (mAltDataOffset > mDataSize))) {
         // alt-metadata cannot be parsed or alt-data offset is invalid
         mMetadata->InitEmptyMetadata();
         isNew = true;
         mAltDataOffset = -1;
-        mAltDataType.Truncate();
         mDataSize = 0;
       } else {
         CacheFileAutoLock lock(this);
         PreloadChunks(0);
       }
     }
 
     InitIndexEntry();
@@ -797,16 +796,18 @@ nsresult
 CacheFile::OpenAlternativeInputStream(nsICacheEntry *aEntryHandle,
                                       const char *aAltDataType,
                                       nsIInputStream **_retval)
 {
   CacheFileAutoLock lock(this);
 
   MOZ_ASSERT(mHandle || mMemoryOnly || mOpeningFile);
 
+  nsresult rv;
+
   if (NS_WARN_IF(!mReady)) {
     LOG(("CacheFile::OpenAlternativeInputStream() - CacheFile is not ready "
          "[this=%p]", this));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (mAltDataOffset == -1) {
     LOG(("CacheFile::OpenAlternativeInputStream() - Alternative data is not "
@@ -822,23 +823,45 @@ CacheFile::OpenAlternativeInputStream(ns
     // a failed state.  This is the only way to protect consumers correctly
     // from reading a broken entry.  When the file is in the failed state,
     // it's also doomed, so reopening the entry won't make any difference -
     // data will still be inaccessible anymore.  Note that for just doomed
     // files, we must allow reading the data.
     return mStatus;
   }
 
-  if (mAltDataType != aAltDataType) {
+  const char *altData = mMetadata->GetElement(CacheFileUtils::kAltDataKey);
+  MOZ_ASSERT(altData, "alt-metadata should exist but was not found!");
+  if (NS_WARN_IF(!altData)) {
+    LOG(("CacheFile::OpenAlternativeInputStream() - alt-metadata not found but "
+         "alt-data exists according to mAltDataOffset! [this=%p, ]", this));
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  int64_t offset;
+  nsCString availableAltData;
+  rv = CacheFileUtils::ParseAlternativeDataInfo(altData, &offset,
+                                                &availableAltData);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    MOZ_ASSERT(false, "alt-metadata unexpectedly failed to parse");
+    LOG(("CacheFile::OpenAlternativeInputStream() - Cannot parse alternative "
+         "metadata! [this=%p]", this));
+    return rv;
+  }
+
+  if (availableAltData != aAltDataType) {
     LOG(("CacheFile::OpenAlternativeInputStream() - Alternative data is of a "
          "different type than requested [this=%p, availableType=%s, "
-         "requestedType=%s]", this, mAltDataType.get(), aAltDataType));
+         "requestedType=%s]", this, availableAltData.get(), aAltDataType));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
+  // mAltDataOffset must be in sync with what is stored in metadata
+  MOZ_ASSERT(mAltDataOffset == offset);
+
   // Once we open input stream we no longer allow preloading of chunks without
   // input stream, i.e. we will no longer keep first few chunks preloaded when
   // the last input stream is closed.
   mPreloadWithoutInputStreams = false;
 
   CacheFileInputStream *input = new CacheFileInputStream(this, aEntryHandle, true);
 
   LOG(("CacheFile::OpenAlternativeInputStream() - Creating new input stream %p "
@@ -897,17 +920,16 @@ CacheFile::OpenOutputStream(CacheOutputC
     rv = Truncate(mAltDataOffset);
     if (NS_FAILED(rv)) {
       LOG(("CacheFile::OpenOutputStream() - Truncating alt-data failed "
            "[rv=0x%08" PRIx32 "]", static_cast<uint32_t>(rv)));
       return rv;
     }
     SetAltMetadata(nullptr);
     mAltDataOffset = -1;
-    mAltDataType.Truncate();
   }
 
   // Once we open output stream we no longer allow preloading of chunks without
   // input stream. There is no reason to believe that some input stream will be
   // opened soon. Otherwise we would cache unused chunks of all newly created
   // entries until the CacheFile is destroyed.
   mPreloadWithoutInputStreams = false;
 
@@ -992,17 +1014,16 @@ CacheFile::OpenAlternativeOutputStream(C
   mPreloadWithoutInputStreams = false;
 
   mOutput = new CacheFileOutputStream(this, aCloseListener, true);
 
   LOG(("CacheFile::OpenAlternativeOutputStream() - Creating new output stream "
        "%p [this=%p]", mOutput, this));
 
   mDataAccessed = true;
-  mAltDataType = aAltDataType;
   NS_ADDREF(*_retval = mOutput);
   return NS_OK;
 }
 
 nsresult
 CacheFile::SetMemoryOnly()
 {
   LOG(("CacheFile::SetMemoryOnly() mMemoryOnly=%d [this=%p]",
@@ -1302,17 +1323,16 @@ CacheFile::SetAltMetadata(const char* aA
   nsresult rv = mMetadata->SetElement(CacheFileUtils::kAltDataKey, aAltMetadata);
   bool hasAltData = aAltMetadata ? true : false;
 
   if (NS_FAILED(rv)) {
     // Removing element shouldn't fail because it doesn't allocate memory.
     mMetadata->SetElement(CacheFileUtils::kAltDataKey, nullptr);
 
     mAltDataOffset = -1;
-    mAltDataType.Truncate();
     hasAltData = false;
   }
 
   if (mHandle && !mHandle->IsDoomed()) {
     CacheFileIOManager::UpdateIndexEntry(mHandle, nullptr, nullptr, &hasAltData, nullptr, nullptr);
   }
   return rv;
 }
@@ -2171,17 +2191,16 @@ CacheFile::RemoveOutput(CacheFileOutputS
         rv = Truncate(mAltDataOffset);
         if (NS_FAILED(rv)) {
           LOG(("CacheFile::RemoveOutput() - Truncating alt-data failed "
                "[rv=0x%08" PRIx32 "]", static_cast<uint32_t>(rv)));
           SetError(aStatus);
         } else {
           SetAltMetadata(nullptr);
           mAltDataOffset = -1;
-          mAltDataType.Truncate();
         }
       }
     } else {
       SetError(aStatus);
     }
   }
 
   // Notify close listener as the last action
@@ -2357,29 +2376,16 @@ CacheFile::GetAltDataSize(int64_t *aSize
   if (mAltDataOffset == -1) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   *aSize = mDataSize - mAltDataOffset;
   return NS_OK;
 }
 
-nsresult
-CacheFile::GetAltDataType(nsACString& aType)
-{
-  CacheFileAutoLock lock(this);
-
-  if (mAltDataOffset == -1) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  aType = mAltDataType;
-  return NS_OK;
-}
-
 bool
 CacheFile::IsDoomed()
 {
   CacheFileAutoLock lock(this);
 
   if (!mHandle)
     return false;
 
--- a/netwerk/cache2/CacheFile.h
+++ b/netwerk/cache2/CacheFile.h
@@ -87,17 +87,16 @@ public:
                                          const char *aAltDataType, nsIOutputStream **_retval);
   NS_IMETHOD SetMemoryOnly();
   NS_IMETHOD Doom(CacheFileListener *aCallback);
 
   void Kill() { mKill = true; }
   nsresult   ThrowMemoryCachedData();
 
   nsresult GetAltDataSize(int64_t *aSize);
-  nsresult GetAltDataType(nsACString& aType);
 
   // metadata forwarders
   nsresult GetElement(const char *aKey, char **_retval);
   nsresult SetElement(const char *aKey, const char *aValue);
   nsresult VisitMetaData(nsICacheEntryMetaDataVisitor *aVisitor);
   nsresult ElementsSize(uint32_t *_retval);
   nsresult SetExpirationTime(uint32_t aExpirationTime);
   nsresult GetExpirationTime(uint32_t *_retval);
@@ -211,17 +210,16 @@ private:
   nsresult       mStatus;
   int64_t        mDataSize; // Size of the whole data including eventual
                             // alternative data represenation.
   int64_t        mAltDataOffset; // If there is alternative data present, it
                                  // contains size of the original data, i.e.
                                  // offset where alternative data starts.
                                  // Otherwise it is -1.
   nsCString      mKey;
-  nsCString      mAltDataType; // The type of the saved alt-data. May be empty.
 
   RefPtr<CacheFileHandle>      mHandle;
   RefPtr<CacheFileMetadata>    mMetadata;
   nsCOMPtr<CacheFileListener>  mListener;
   nsCOMPtr<CacheFileIOListener>   mDoomAfterOpenListener;
   Atomic<bool, Relaxed>        mKill;
 
   nsRefPtrHashtable<nsUint32HashKey, CacheFileChunk> mChunks;
--- a/netwerk/cache2/OldWrappers.cpp
+++ b/netwerk/cache2/OldWrappers.cpp
@@ -391,21 +391,16 @@ NS_IMETHODIMP _OldCacheEntryWrapper::Get
   return NS_OK;
 }
 
 NS_IMETHODIMP _OldCacheEntryWrapper::GetAltDataSize(int64_t *aSize)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP _OldCacheEntryWrapper::GetAltDataType(nsACString &aType)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
 NS_IMETHODIMP _OldCacheEntryWrapper::GetPersistent(bool *aPersistToDisk)
 {
   if (!mOldDesc) {
     return NS_ERROR_NULL_POINTER;
   }
 
   nsresult rv;
 
--- a/netwerk/cache2/OldWrappers.h
+++ b/netwerk/cache2/OldWrappers.h
@@ -155,17 +155,16 @@ public:
   NS_IMETHOD GetPersistent(bool *aPersistToDisk) override;
   NS_IMETHOD GetIsForcedValid(bool *aIsForcedValid) override;
   NS_IMETHOD ForceValidFor(uint32_t aSecondsToTheFuture) override;
   NS_IMETHOD SetValid() override { return NS_OK; }
   NS_IMETHOD MetaDataReady() override { return NS_OK; }
   NS_IMETHOD Recreate(bool, nsICacheEntry**) override;
   NS_IMETHOD GetDataSize(int64_t *size) override;
   NS_IMETHOD GetAltDataSize(int64_t *size) override;
-  NS_IMETHOD GetAltDataType(nsACString &aType) override;
   NS_IMETHOD OpenInputStream(int64_t offset, nsIInputStream * *_retval) override;
   NS_IMETHOD OpenOutputStream(int64_t offset, int64_t predictedSize, nsIOutputStream * *_retval) override;
   NS_IMETHOD MaybeMarkValid() override;
   NS_IMETHOD HasWriteAccess(bool aWriteOnly, bool *aWriteAccess) override;
   NS_IMETHOD VisitMetaData(nsICacheEntryMetaDataVisitor*) override;
 
   explicit _OldCacheEntryWrapper(nsICacheEntryDescriptor* desc);
   explicit _OldCacheEntryWrapper(nsICacheEntryInfo* info);
--- a/netwerk/cache2/nsICacheEntry.idl
+++ b/netwerk/cache2/nsICacheEntry.idl
@@ -235,23 +235,16 @@ interface nsICacheEntry : nsISupports
   * @throws
   *    - NS_ERROR_IN_PROGRESS when a write is still in progress (either real
                               content or alt data).
   *    - NS_ERROR_NOT_AVAILABLE if alt data does not exist.
   */
   readonly attribute long long altDataSize;
 
   /**
-  * Returns the type of the saved alt data.
-  * @throws
-  *    - NS_ERROR_NOT_AVAILABLE if alt data does not exist.
-  */
-  readonly attribute ACString altDataType;
-
-  /**
    * Opens and returns an output stream that a consumer may use to save an
    * alternate representation of the data.
    *
    * @param type
    *        type of the alternative data representation
    * @param predictedSize
    *        Predicted size of the data that will be written. It's used to decide
    *        whether the resulting entry would exceed size limit, in which case
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -13,17 +13,16 @@ include ClientIPCTypes;
 include URIParams;
 include IPCServiceWorkerDescriptor;
 include IPCStream;
 include PBackgroundSharedTypes;
 
 using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using RequestHeaderTuples from "mozilla/net/PHttpChannelParams.h";
-using ArrayOfStringPairs from "mozilla/net/PHttpChannelParams.h";
 using struct nsHttpAtom from "nsHttp.h";
 using class mozilla::net::nsHttpResponseHead from "nsHttpResponseHead.h";
 using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
 using Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED from "DocumentAnalyticsTrackerFastBlocked.h";
 
 namespace mozilla {
 namespace net {
 
@@ -241,17 +240,17 @@ struct HttpChannelOpenArgs
   bool                        suspendAfterSynthesizeResponse;
   bool                        allowStaleCacheContent;
   nsCString                   contentTypeHint;
   uint32_t                    corsMode;
   uint32_t                    redirectMode;
   uint64_t                    channelId;
   nsString                    integrityMetadata;
   uint64_t                    contentWindowId;
-  ArrayOfStringPairs          preferredAlternativeTypes;
+  nsCString                   preferredAlternativeType;
   uint64_t                    topLevelOuterContentWindowId;
   TimeStamp                   launchServiceWorkerStart;
   TimeStamp                   launchServiceWorkerEnd;
   TimeStamp                   dispatchFetchEventStart;
   TimeStamp                   dispatchFetchEventEnd;
   TimeStamp                   handleFetchEventStart;
   TimeStamp                   handleFetchEventEnd;
   bool                        forceMainDocumentChannel;
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -3904,19 +3904,17 @@ HttpBaseChannel::SetupReplacementChannel
     newTimedChannel->SetDispatchFetchEventEnd(mDispatchFetchEventEnd);
     newTimedChannel->SetHandleFetchEventStart(mHandleFetchEventStart);
     newTimedChannel->SetHandleFetchEventEnd(mHandleFetchEventEnd);
   }
 
   // Pass the preferred alt-data type on to the new channel.
   nsCOMPtr<nsICacheInfoChannel> cacheInfoChan(do_QueryInterface(newChannel));
   if (cacheInfoChan) {
-    for (auto& pair : mPreferredCachedAltDataTypes) {
-      cacheInfoChan->PreferAlternativeDataType(mozilla::Get<0>(pair), mozilla::Get<1>(pair));
-    }
+    cacheInfoChan->PreferAlternativeDataType(mPreferredCachedAltDataType);
   }
 
   if (redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
                        nsIChannelEventSink::REDIRECT_STS_UPGRADE)) {
     // Copy non-origin related headers to the new channel.
     nsCOMPtr<nsIHttpHeaderVisitor> visitor =
       new AddHeadersToChannelVisitor(httpChannel);
     rv = mRequestHead.VisitHeaders(visitor);
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -41,17 +41,16 @@
 #include "PrivateBrowsingChannel.h"
 #include "mozilla/net/DNS.h"
 #include "nsITimedChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsISecurityConsoleMessage.h"
 #include "nsCOMArray.h"
 #include "mozilla/net/ChannelEventQueue.h"
 #include "mozilla/Move.h"
-#include "mozilla/Tuple.h"
 #include "nsIThrottledInputChannel.h"
 #include "nsTArray.h"
 #include "nsCOMPtr.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "nsStringEnumerator.h"
 
 #define HTTP_BASE_CHANNEL_IID \
 { 0x9d5cde03, 0xe6e9, 0x4612, \
@@ -67,18 +66,16 @@ namespace dom {
 class PerformanceStorage;
 }
 
 class LogCollector;
 
 namespace net {
 extern mozilla::LazyLogModule gHttpLog;
 
-typedef nsTArray<Tuple<nsCString, nsCString>> ArrayOfStringPairs;
-
 /*
  * This class is a partial implementation of nsIHttpChannel.  It contains code
  * shared by nsHttpChannel and HttpChannelChild.
  * - Note that this class has nothing to do with nsBaseChannel, which is an
  *   earlier effort at a base class for channels that somehow never made it all
  *   the way to the HTTP channel.
  */
 class HttpBaseChannel : public nsHashPropertyBag
@@ -551,18 +548,18 @@ protected:
   nsCString mUserSetCookieHeader;
   // HTTP Upgrade Data
   nsCString mUpgradeProtocol;
   // Resumable channel specific data
   nsCString mEntityID;
   // The initiator type (for this resource) - how was the resource referenced in
   // the HTML file.
   nsString mInitiatorType;
-  // Holds the name of the preferred alt-data type for each contentType.
-  ArrayOfStringPairs mPreferredCachedAltDataTypes;
+  // Holds the name of the preferred alt-data type.
+  nsCString mPreferredCachedAltDataType;
   // Holds the name of the alternative data type the channel returned.
   nsCString mAvailableCachedAltDataType;
   nsString mIntegrityMetadata;
 
   // Classified channel's matched information
   nsCString mMatchedList;
   nsCString mMatchedProvider;
   nsCString mMatchedFullHash;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1262,17 +1262,17 @@ HttpChannelChild::OnStopRequest(const ns
 
   CleanupBackgroundChannel();
 
   // If there is a possibility we might want to write alt data to the cache
   // entry, we keep the channel alive. We still send the DocumentChannelCleanup
   // message but request the cache entry to be kept by the parent.
   // If the channel has failed, the cache entry is in a non-writtable state and
   // we want to release it to not block following consumers.
-  if (NS_SUCCEEDED(channelStatus) && !mPreferredCachedAltDataTypes.IsEmpty()) {
+  if (NS_SUCCEEDED(channelStatus) && !mPreferredCachedAltDataType.IsEmpty()) {
     mKeptAlive = true;
     SendDocumentChannelCleanup(false); // don't clear cache entry
     return;
   }
 
   if (mLoadFlags & LOAD_DOCUMENT_URI) {
     // Keep IPDL channel open, but only for updating security info.
     // If IPDL is already closed, then do nothing.
@@ -1369,17 +1369,17 @@ HttpChannelChild::DoOnStopRequest(nsIReq
   // notify "http-on-stop-connect" observers
   gHttpHandler->OnStopRequest(this);
 
   ReleaseListeners();
 
   // If a preferred alt-data type was set, the parent would hold a reference to
   // the cache entry in case the child calls openAlternativeOutputStream().
   // (see nsHttpChannel::OnStopRequest)
-  if (!mPreferredCachedAltDataTypes.IsEmpty()) {
+  if (!mPreferredCachedAltDataType.IsEmpty()) {
     mAltDataCacheEntryAvailable = mCacheEntryAvailable;
   }
   mCacheEntryAvailable = false;
 
   if (mLoadGroup)
     mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 }
 
@@ -2869,17 +2869,17 @@ HttpChannelChild::ContinueAsyncOpen()
   SerializeURI(mOriginalURI, openArgs.original());
   SerializeURI(mDocumentURI, openArgs.doc());
   SerializeURI(mReferrer, openArgs.referrer());
   openArgs.referrerPolicy() = mReferrerPolicy;
   SerializeURI(mAPIRedirectToURI, openArgs.apiRedirectTo());
   openArgs.loadFlags() = mLoadFlags;
   openArgs.requestHeaders() = mClientSetRequestHeaders;
   mRequestHead.Method(openArgs.requestMethod());
-  openArgs.preferredAlternativeTypes() = mPreferredCachedAltDataTypes;
+  openArgs.preferredAlternativeType() = mPreferredCachedAltDataType;
 
   AutoIPCStream autoStream(openArgs.uploadStream());
   if (mUploadStream) {
     autoStream.Serialize(mUploadStream, ContentChild::GetSingleton());
     autoStream.TakeOptionalValue();
   }
 
   if (mResponseHead) {
@@ -3266,33 +3266,33 @@ HttpChannelChild::GetAllowStaleCacheCont
   }
 
   NS_ENSURE_ARG(aAllowStaleCacheContent);
   *aAllowStaleCacheContent = mAllowStaleCacheContent;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HttpChannelChild::PreferAlternativeDataType(const nsACString& aType,
-                                            const nsACString& aContentType)
+HttpChannelChild::PreferAlternativeDataType(const nsACString & aType)
 {
   ENSURE_CALLED_BEFORE_ASYNC_OPEN();
 
   if (mSynthesizedCacheInfo) {
-    return mSynthesizedCacheInfo->PreferAlternativeDataType(aType, aContentType);
+    return mSynthesizedCacheInfo->PreferAlternativeDataType(aType);
   }
 
-  mPreferredCachedAltDataTypes.AppendElement(MakePair(nsCString(aType), nsCString(aContentType)));
+  mPreferredCachedAltDataType = aType;
   return NS_OK;
 }
 
-const nsTArray<mozilla::Tuple<nsCString, nsCString>>&
-HttpChannelChild::PreferredAlternativeDataTypes()
+NS_IMETHODIMP
+HttpChannelChild::GetPreferredAlternativeDataType(nsACString & aType)
 {
-  return mPreferredCachedAltDataTypes;
+  aType = mPreferredCachedAltDataType;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelChild::GetAlternativeDataType(nsACString & aType)
 {
   if (mSynthesizedCacheInfo) {
     return mSynthesizedCacheInfo->GetAlternativeDataType(aType);
   }
@@ -3336,46 +3336,16 @@ HttpChannelChild::OpenAlternativeOutputS
                                                         this)) {
     return NS_ERROR_FAILURE;
   }
 
   stream.forget(_retval);
   return NS_OK;
 }
 
-NS_IMETHODIMP
-HttpChannelChild::GetOriginalInputStream(nsIInputStreamReceiver *aReceiver)
-{
-  if (aReceiver == nullptr) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  if (!mIPCOpen) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  mInputStreamReceiver = aReceiver;
-  Unused << SendOpenOriginalCacheInputStream();
-
-  return NS_OK;
-}
-
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvOriginalCacheInputStreamAvailable(const OptionalIPCStream& aStream)
-{
-  nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(aStream);
-  nsCOMPtr<nsIInputStreamReceiver> receiver;
-  receiver.swap(mInputStreamReceiver);
-  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));
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -177,18 +177,16 @@ protected:
   mozilla::ipc::IPCResult RecvSetPriority(const int16_t& aPriority) override;
 
   mozilla::ipc::IPCResult RecvAttachStreamFilter(Endpoint<extensions::PStreamFilterParent>&& aEndpoint) override;
 
   mozilla::ipc::IPCResult RecvCancelDiversion() override;
 
   mozilla::ipc::IPCResult RecvCancelRedirected() override;
 
-  mozilla::ipc::IPCResult RecvOriginalCacheInputStreamAvailable(const OptionalIPCStream& aStream) override;
-
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual void DoNotifyListenerCleanup() override;
 
   virtual void DoAsyncAbort(nsresult aStatus) override;
 
   nsresult
   AsyncCall(void (HttpChannelChild::*funcPtr)(),
@@ -324,18 +322,16 @@ private:
 
   RequestHeaderTuples mClientSetRequestHeaders;
   RefPtr<nsInputStreamPump> mSynthesizedResponsePump;
   nsCOMPtr<nsIInputStream> mSynthesizedInput;
   nsCOMPtr<nsIInterceptedBodyCallback> mSynthesizedCallback;
   nsCOMPtr<nsICacheInfoChannel> mSynthesizedCacheInfo;
   RefPtr<ChannelEventQueue> mEventQ;
 
-  nsCOMPtr<nsIInputStreamReceiver> mInputStreamReceiver;
-
   // 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
   nsCOMPtr<nsIRunnable> mBgInitFailCallback;
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -148,17 +148,17 @@ HttpChannelParent::Init(const HttpChanne
                        a.tlsFlags(), a.loadInfo(), a.synthesizedResponseHead(),
                        a.synthesizedSecurityInfoSerialization(),
                        a.cacheKey(), a.requestContextID(), a.preflightArgs(),
                        a.initialRwin(), a.blockAuthPrompt(),
                        a.suspendAfterSynthesizeResponse(),
                        a.allowStaleCacheContent(), a.contentTypeHint(),
                        a.corsMode(), a.redirectMode(),
                        a.channelId(), a.integrityMetadata(),
-                       a.contentWindowId(), a.preferredAlternativeTypes(),
+                       a.contentWindowId(), a.preferredAlternativeType(),
                        a.topLevelOuterContentWindowId(),
                        a.launchServiceWorkerStart(),
                        a.launchServiceWorkerEnd(),
                        a.dispatchFetchEventStart(),
                        a.dispatchFetchEventEnd(),
                        a.handleFetchEventStart(),
                        a.handleFetchEventEnd(),
                        a.forceMainDocumentChannel(),
@@ -450,17 +450,17 @@ HttpChannelParent::DoAsyncOpen(  const U
                                  const bool&                aSuspendAfterSynthesizeResponse,
                                  const bool&                aAllowStaleCacheContent,
                                  const nsCString&           aContentTypeHint,
                                  const uint32_t&            aCorsMode,
                                  const uint32_t&            aRedirectMode,
                                  const uint64_t&            aChannelId,
                                  const nsString&            aIntegrityMetadata,
                                  const uint64_t&            aContentWindowId,
-                                 const ArrayOfStringPairs&  aPreferredAlternativeTypes,
+                                 const nsCString&           aPreferredAlternativeType,
                                  const uint64_t&            aTopLevelOuterContentWindowId,
                                  const TimeStamp&           aLaunchServiceWorkerStart,
                                  const TimeStamp&           aLaunchServiceWorkerEnd,
                                  const TimeStamp&           aDispatchFetchEventStart,
                                  const TimeStamp&           aDispatchFetchEventEnd,
                                  const TimeStamp&           aHandleFetchEventStart,
                                  const TimeStamp&           aHandleFetchEventEnd,
                                  const bool&                aForceMainDocumentChannel,
@@ -609,19 +609,17 @@ HttpChannelParent::DoAsyncOpen(  const U
       MOZ_ASSERT(NS_SUCCEEDED(rv));
     }
   }
 
   nsCOMPtr<nsICacheInfoChannel> cacheChannel =
     do_QueryInterface(static_cast<nsIChannel*>(httpChannel.get()));
   if (cacheChannel) {
     cacheChannel->SetCacheKey(aCacheKey);
-    for (auto& pair : aPreferredAlternativeTypes) {
-      cacheChannel->PreferAlternativeDataType(mozilla::Get<0>(pair), mozilla::Get<1>(pair));
-    }
+    cacheChannel->PreferAlternativeDataType(aPreferredAlternativeType);
 
     cacheChannel->SetAllowStaleCacheContent(aAllowStaleCacheContent);
 
     // This is to mark that the results are going to the content process.
     if (httpChannelImpl) {
       httpChannelImpl->SetAltDataForChild(true);
     }
   }
@@ -1768,36 +1766,16 @@ HttpChannelParent::RecvBytesRead(const i
     MOZ_ASSERT(mSuspendedForFlowControl);
     Unused << mChannel->Resume();
     mSuspendedForFlowControl = false;
   }
   mSendWindowSize += aCount;
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult
-HttpChannelParent::RecvOpenOriginalCacheInputStream()
-{
-  if (mIPCClosed) {
-    return IPC_OK();
-  }
-  AutoIPCStream autoStream;
-  if (mCacheEntry) {
-    nsCOMPtr<nsIInputStream> inputStream;
-    nsresult rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
-    if (NS_SUCCEEDED(rv)) {
-      PContentParent* pcp = Manager()->Manager();
-      Unused << autoStream.Serialize(inputStream, static_cast<ContentParent*>(pcp));
-    }
-  }
-
-  Unused << SendOriginalCacheInputStreamAvailable(autoStream.TakeOptionalValue());
-  return IPC_OK();
-}
-
 //-----------------------------------------------------------------------------
 // HttpChannelParent::nsIProgressEventSink
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpChannelParent::OnProgress(nsIRequest *aRequest,
                               nsISupports *aContext,
                               int64_t aProgress,
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -168,17 +168,17 @@ protected:
               const bool&                aSuspendAfterSynthesizeResponse,
               const bool&                aAllowStaleCacheContent,
               const nsCString&           aContentTypeHint,
               const uint32_t&            aCorsMode,
               const uint32_t&            aRedirectMode,
               const uint64_t&            aChannelId,
               const nsString&            aIntegrityMetadata,
               const uint64_t&            aContentWindowId,
-              const ArrayOfStringPairs&  aPreferredAlternativeTypes,
+              const nsCString&           aPreferredAlternativeType,
               const uint64_t&            aTopLevelOuterContentWindowId,
               const TimeStamp&           aLaunchServiceWorkerStart,
               const TimeStamp&           aLaunchServiceWorkerEnd,
               const TimeStamp&           aDispatchFetchEventStart,
               const TimeStamp&           aDispatchFetchEventEnd,
               const TimeStamp&           aHandleFetchEventStart,
               const TimeStamp&           aHandleFetchEventEnd,
               const bool&                aForceMainDocumentChannel,
@@ -205,17 +205,16 @@ protected:
                                          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 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 RecvOpenOriginalCacheInputStream() 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
@@ -1310,28 +1310,28 @@ InterceptedHttpChannel::GetAllowStaleCac
 {
   if (mSynthesizedCacheInfo) {
     return mSynthesizedCacheInfo->GetAllowStaleCacheContent(aAllowStaleCacheContent);
   }
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
-InterceptedHttpChannel::PreferAlternativeDataType(const nsACString & aType,
-                                                  const nsACString& aContentType)
+InterceptedHttpChannel::PreferAlternativeDataType(const nsACString & aType)
 {
   ENSURE_CALLED_BEFORE_ASYNC_OPEN();
-  mPreferredCachedAltDataTypes.AppendElement(MakePair(nsCString(aType), nsCString(aContentType)));
+  mPreferredCachedAltDataType = aType;
   return NS_OK;
 }
 
-const nsTArray<mozilla::Tuple<nsCString, nsCString>>&
-InterceptedHttpChannel::PreferredAlternativeDataTypes()
+NS_IMETHODIMP
+InterceptedHttpChannel::GetPreferredAlternativeDataType(nsACString & aType)
 {
-  return mPreferredCachedAltDataTypes;
+  aType = mPreferredCachedAltDataType;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 InterceptedHttpChannel::GetAlternativeDataType(nsACString & aType)
 {
   if (mSynthesizedCacheInfo) {
     return mSynthesizedCacheInfo->GetAlternativeDataType(aType);
   }
@@ -1343,25 +1343,16 @@ InterceptedHttpChannel::OpenAlternativeO
 {
   if (mSynthesizedCacheInfo) {
     return mSynthesizedCacheInfo->OpenAlternativeOutputStream(type, predictedSize, _retval);
   }
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
-InterceptedHttpChannel::GetOriginalInputStream(nsIInputStreamReceiver *aReceiver)
-{
-  if (mSynthesizedCacheInfo) {
-    return mSynthesizedCacheInfo->GetOriginalInputStream(aReceiver);
-  }
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-NS_IMETHODIMP
 InterceptedHttpChannel::GetCacheKey(uint32_t* key)
 {
   if (mSynthesizedCacheInfo) {
     return mSynthesizedCacheInfo->GetCacheKey(key);
   }
   return NS_ERROR_NOT_AVAILABLE;
 }
 
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -7,17 +7,16 @@
 
 include protocol PNecko;
 include protocol PStreamFilter;
 include InputStreamParams;
 include URIParams;
 include PBackgroundSharedTypes;
 include NeckoChannelParams;
 include IPCServiceWorkerDescriptor;
-include IPCStream;
 
 include "mozilla/net/NeckoMessageUtils.h";
 
 using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
 using mozilla::net::NetAddr from "mozilla/net/DNS.h";
 using struct mozilla::net::ResourceTimingStruct from "mozilla/net/TimingStruct.h";
 
 namespace mozilla {
@@ -89,19 +88,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 was delivered.
-  async OpenOriginalCacheInputStream();
-
   // 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,
@@ -169,17 +165,16 @@ child:
   // console.
   async LogBlockedCORSRequest(nsString message, nsCString category);
 
   async AttachStreamFilter(Endpoint<PStreamFilterParent> aEndpoint);
 
   // See ADivertableParentChannel::CancelDiversion
   async CancelDiversion();
 
-  async OriginalCacheInputStreamAvailable(OptionalIPCStream 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/PHttpChannelParams.h
+++ b/netwerk/protocol/http/PHttpChannelParams.h
@@ -9,17 +9,16 @@
 
 #define ALLOW_LATE_NSHTTP_H_INCLUDE 1
 #include "base/basictypes.h"
 
 #include "ipc/IPCMessageUtils.h"
 #include "nsHttp.h"
 #include "nsHttpHeaderArray.h"
 #include "nsHttpResponseHead.h"
-#include "mozilla/Tuple.h"
 
 #include "nsIClassInfo.h"
 
 namespace mozilla {
 namespace net {
 
 struct RequestHeaderTuple {
   nsCString mHeader;
@@ -32,48 +31,22 @@ struct RequestHeaderTuple {
            mValue.Equals(other.mValue) &&
            mMerge == other.mMerge &&
            mEmpty == other.mEmpty;
   }
 };
 
 typedef nsTArray<RequestHeaderTuple> RequestHeaderTuples;
 
-typedef nsTArray<Tuple<nsCString, nsCString>> ArrayOfStringPairs;
-
 } // namespace net
 } // namespace mozilla
 
 namespace IPC {
 
 template<>
-struct ParamTraits<mozilla::Tuple<nsCString, nsCString>>
-{
-  typedef mozilla::Tuple<nsCString, nsCString> paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    WriteParam(aMsg, mozilla::Get<0>(aParam));
-    WriteParam(aMsg, mozilla::Get<1>(aParam));
-  }
-
-  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
-  {
-    nsCString first;
-    nsCString second;
-    if (!ReadParam(aMsg, aIter, &first) ||
-        !ReadParam(aMsg, aIter, &second))
-      return false;
-
-    *aResult = mozilla::MakeTuple(first, second);
-    return true;
-  }
-};
-
-template<>
 struct ParamTraits<mozilla::net::RequestHeaderTuple>
 {
   typedef mozilla::net::RequestHeaderTuple paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mHeader);
     WriteParam(aMsg, aParam.mValue);
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -4998,50 +4998,30 @@ nsHttpChannel::OpenCacheInputStream(nsIC
     bool altDataFromChild = false;
     {
         nsCString value;
         rv = cacheEntry->GetMetaDataElement("alt-data-from-child",
                                             getter_Copies(value));
         altDataFromChild = !value.IsEmpty();
     }
 
-    nsAutoCString altDataType;
-    Unused << cacheEntry->GetAltDataType(altDataType);
-
-    nsAutoCString contentType;
-    mCachedResponseHead->ContentType(contentType);
-
-    bool foundAltData = false;
-    if (!altDataType.IsEmpty() &&
-        !mPreferredCachedAltDataTypes.IsEmpty() &&
-        altDataFromChild == mAltDataForChild) {
-        for (auto& pref : mPreferredCachedAltDataTypes) {
-            if (mozilla::Get<0>(pref) == altDataType &&
-                (mozilla::Get<1>(pref).IsEmpty() || mozilla::Get<1>(pref) == contentType)) {
-                foundAltData = true;
-                break;
-            }
-        }
-    }
-    if (foundAltData) {
-        rv = cacheEntry->OpenAlternativeInputStream(altDataType,
+    if (!mPreferredCachedAltDataType.IsEmpty() && (altDataFromChild == mAltDataForChild)) {
+        rv = cacheEntry->OpenAlternativeInputStream(mPreferredCachedAltDataType,
                                                     getter_AddRefs(stream));
         if (NS_SUCCEEDED(rv)) {
-            LOG(("Opened alt-data input stream type=%s", altDataType.get()));
             // We have succeeded.
-            mAvailableCachedAltDataType = altDataType;
+            mAvailableCachedAltDataType = mPreferredCachedAltDataType;
             // Set the correct data size on the channel.
             int64_t altDataSize;
             if (NS_SUCCEEDED(cacheEntry->GetAltDataSize(&altDataSize))) {
                 mAltDataLength = altDataSize;
             }
         }
     }
 
-
     if (!stream) {
         rv = cacheEntry->OpenInputStream(0, getter_AddRefs(stream));
     }
 
     if (NS_FAILED(rv)) {
         LOG(("Failed to open cache input stream [channel=%p, "
              "mCacheEntry=%p]", this, cacheEntry));
         return rv;
@@ -7879,17 +7859,17 @@ nsHttpChannel::OnStopRequest(nsIRequest 
     gHttpHandler->OnStopRequest(this);
 
     RemoveAsNonTailRequest();
 
     // If a preferred alt-data type was set, this signals the consumer is
     // interested in reading and/or writing the alt-data representation.
     // We need to hold a reference to the cache entry in case the listener calls
     // openAlternativeOutputStream() after CloseCacheEntry() clears mCacheEntry.
-    if (!mPreferredCachedAltDataTypes.IsEmpty()) {
+    if (!mPreferredCachedAltDataType.IsEmpty()) {
         mAltDataCacheEntry = mCacheEntry;
     }
 
     CloseCacheEntry(!contentComplete);
 
     if (mOfflineCacheEntry)
         CloseOfflineCacheEntry();
 
@@ -8301,28 +8281,28 @@ NS_IMETHODIMP
 nsHttpChannel::GetAllowStaleCacheContent(bool *aAllowStaleCacheContent)
 {
     NS_ENSURE_ARG(aAllowStaleCacheContent);
     *aAllowStaleCacheContent = mAllowStaleCacheContent;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHttpChannel::PreferAlternativeDataType(const nsACString& aType,
-                                         const nsACString& aContentType)
+nsHttpChannel::PreferAlternativeDataType(const nsACString & aType)
 {
     ENSURE_CALLED_BEFORE_ASYNC_OPEN();
-    mPreferredCachedAltDataTypes.AppendElement(MakePair(nsCString(aType), nsCString(aContentType)));
+    mPreferredCachedAltDataType = aType;
     return NS_OK;
 }
 
-const nsTArray<mozilla::Tuple<nsCString, nsCString>>&
-nsHttpChannel::PreferredAlternativeDataTypes()
-{
-    return mPreferredCachedAltDataTypes;
+NS_IMETHODIMP
+nsHttpChannel::GetPreferredAlternativeDataType(nsACString & aType)
+{
+  aType = mPreferredCachedAltDataType;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHttpChannel::GetAlternativeDataType(nsACString & aType)
 {
     // must be called during or after OnStartRequest
     if (!mAfterOnStartRequestBegun) {
         return NS_ERROR_NOT_AVAILABLE;
@@ -8344,33 +8324,16 @@ nsHttpChannel::OpenAlternativeOutputStre
     if (NS_SUCCEEDED(rv)) {
         // Clear this metadata flag in case it exists.
         // The caller of this method may set it again.
         cacheEntry->SetMetaDataElement("alt-data-from-child", nullptr);
     }
     return rv;
 }
 
-NS_IMETHODIMP
-nsHttpChannel::GetOriginalInputStream(nsIInputStreamReceiver *aReceiver)
-{
-    if (aReceiver == nullptr) {
-        return NS_ERROR_INVALID_ARG;
-    }
-    nsCOMPtr<nsIInputStream> inputStream;
-
-    nsCOMPtr<nsICacheEntry> cacheEntry = mCacheEntry ? mCacheEntry
-                                                     : mAltDataCacheEntry;
-    if (cacheEntry) {
-        cacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
-    }
-    aReceiver->OnInputStreamReady(inputStream);
-    return NS_OK;
-}
-
 //-----------------------------------------------------------------------------
 // nsHttpChannel::nsICachingChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpChannel::GetCacheToken(nsISupports **token)
 {
     NS_ENSURE_ARG_POINTER(token);
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -1141,17 +1141,8 @@ nsViewSourceChannel::LogBlockedCORSReque
                                            const nsACString& aCategory)
 {
   if (!mHttpChannel) {
     NS_WARNING("nsViewSourceChannel::LogBlockedCORSRequest mHttpChannel is null");
     return NS_ERROR_UNEXPECTED;
   }
   return mHttpChannel->LogBlockedCORSRequest(aMessage, aCategory);
 }
-
-const nsTArray<mozilla::Tuple<nsCString, nsCString>>&
-nsViewSourceChannel::PreferredAlternativeDataTypes()
-{
-    if (mCacheInfoChannel) {
-        return mCacheInfoChannel->PreferredAlternativeDataTypes();
-    }
-    return mEmptyArray;
-}
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.h
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.h
@@ -60,17 +60,16 @@ public:
     // loadinfo to be prefixed with the "view-source:" schema as:
     //
     // mChannel.loadInfo.resultPrincipalURI = "view-source:" +
     //    (mChannel.loadInfo.resultPrincipalURI | mChannel.orignalURI);
     nsresult UpdateLoadInfoResultPrincipalURI();
 
 protected:
     ~nsViewSourceChannel() = default;
-    nsTArray<mozilla::Tuple<nsCString, nsCString>> mEmptyArray;
 
     // Clones aURI and prefixes it with "view-source:" schema,
     nsresult BuildViewSourceURI(nsIURI* aURI, nsIURI** aResult);
 
     nsCOMPtr<nsIChannel>        mChannel;
     nsCOMPtr<nsIHttpChannel>    mHttpChannel;
     nsCOMPtr<nsIHttpChannelInternal>    mHttpChannelInternal;
     nsCOMPtr<nsICachingChannel> mCachingChannel;
--- a/netwerk/test/unit/test_alt-data_cross_process.js
+++ b/netwerk/test/unit/test_alt-data_cross_process.js
@@ -80,17 +80,17 @@ function run_test()
   asyncOpen();
 }
 
 function asyncOpen()
 {
   var chan = make_channel(URL);
 
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType(altContentType, "");
+  cc.preferAlternativeDataType(altContentType);
 
   chan.asyncOpen2(new ChannelListener(readServerContent, null));
 }
 
 function readServerContent(request, buffer)
 {
   var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
 
@@ -115,17 +115,17 @@ function flushAndOpenAltChannel()
   do_await_remote_message('flushed').then(() => {
     openAltChannel();
   });
 }
 
 function openAltChannel() {
   var chan = make_channel(URL);
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType(altContentType, "");
+  cc.preferAlternativeDataType(altContentType);
 
   chan.asyncOpen2(new ChannelListener(readAltContent, null));
 }
 
 function readAltContent(request, buffer)
 {
   var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
 
--- a/netwerk/test/unit/test_alt-data_overwrite.js
+++ b/netwerk/test/unit/test_alt-data_overwrite.js
@@ -21,17 +21,17 @@ XPCOMUtils.defineLazyGetter(this, "URL",
 });
 
 let httpServer = null;
 
 function make_and_open_channel(url, altContentType, callback) {
   let chan = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
   if (altContentType) {
     let cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-    cc.preferAlternativeDataType(altContentType, "");
+    cc.preferAlternativeDataType(altContentType);
   }
   chan.asyncOpen2(new ChannelListener(callback, null));
 }
 
 const responseContent = "response body";
 const altContent = "!@#$%^&*()";
 const altContentType = "text/binary";
 const altContent2 = "abc";
--- a/netwerk/test/unit/test_alt-data_simple.js
+++ b/netwerk/test/unit/test_alt-data_simple.js
@@ -86,17 +86,17 @@ function run_test()
   }
 }
 
 function asyncOpen()
 {
   var chan = make_channel(URL);
 
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType(altContentType, "");
+  cc.preferAlternativeDataType(altContentType);
 
   chan.asyncOpen2(new ChannelListener(readServerContent, null));
 }
 
 function readServerContent(request, buffer)
 {
   var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
 
@@ -131,49 +131,39 @@ function flushAndOpenAltChannel()
       openAltChannel();
     });
   }
 }
 
 function openAltChannel() {
   var chan = make_channel(URL);
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType("dummy1", "text/javascript");
-  cc.preferAlternativeDataType(altContentType, "text/plain");
-  cc.preferAlternativeDataType("dummy2", "");
+  cc.preferAlternativeDataType(altContentType);
 
   chan.asyncOpen2(new ChannelListener(readAltContent, null));
 }
 
 function readAltContent(request, buffer)
 {
   var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
 
   Assert.equal(servedNotModified, true);
   Assert.equal(cc.alternativeDataType, altContentType);
   Assert.equal(buffer, altContent);
   check_has_alt_data_in_index(true);
 
-  cc.getOriginalInputStream({
-    onInputStreamReady: function(aInputStream) {
-      executeSoon(function() {
-        let originalData = read_stream(aInputStream, aInputStream.available());
-        Assert.equal(originalData, responseContent);
-        requestAgain();
-      });
-    }
-  });
+  requestAgain();
 }
 
 function requestAgain()
 {
   shouldPassRevalidation = false;
   var chan = make_channel(URL);
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType(altContentType, "");
+  cc.preferAlternativeDataType(altContentType);
   chan.asyncOpen2(new ChannelListener(readEmptyAltContent, null));
 }
 
 function readEmptyAltContent(request, buffer)
 {
   var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
 
   // the cache is overwrite and the alt-data is reset
--- a/netwerk/test/unit/test_alt-data_stream.js
+++ b/netwerk/test/unit/test_alt-data_stream.js
@@ -55,17 +55,17 @@ function run_test()
   do_get_profile();
   httpServer = new HttpServer();
   httpServer.registerPathHandler("/content", contentHandler);
   httpServer.start(-1);
 
   var chan = make_channel(URL);
 
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType(altContentType, "");
+  cc.preferAlternativeDataType(altContentType);
 
   chan.asyncOpen2(new ChannelListener(readServerContent, null));
   do_test_pending();
 }
 
 // Output stream used to write alt-data to the cache entry.
 var os;
 
@@ -84,17 +84,17 @@ function readServerContent(request, buff
     executeSoon(openAltChannel);
   });
 }
 
 function openAltChannel()
 {
   var chan = make_channel(URL);
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType(altContentType, "");
+  cc.preferAlternativeDataType(altContentType);
 
   chan.asyncOpen2(listener);
 }
 
 var listener = {
   buffer: "",
   onStartRequest: function(request, context) { },
   onDataAvailable: function(request, context, stream, offset, count) {
--- a/netwerk/test/unit/test_cache-entry-id.js
+++ b/netwerk/test/unit/test_cache-entry-id.js
@@ -48,17 +48,17 @@ function contentHandler(metadata, respon
 
 function fetch(preferredDataType = null)
 {
   return new Promise(resolve => {
     var chan = NetUtil.newChannel({uri: URL, loadUsingSystemPrincipal: true});
 
     if (preferredDataType) {
       var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-      cc.preferAlternativeDataType(altContentType, "");
+      cc.preferAlternativeDataType(altContentType);
     }
 
     chan.asyncOpen2(new ChannelListener((request,
                                          buffer,
                                          ctx,
                                          isFromCache,
                                          cacheEntryId) => {
       resolve({request, buffer, isFromCache, cacheEntryId});
--- a/netwerk/test/unit_ipc/test_alt-data_cross_process_wrap.js
+++ b/netwerk/test/unit_ipc/test_alt-data_cross_process_wrap.js
@@ -27,17 +27,17 @@ function run_test() {
   run_test_in_child("../unit/test_alt-data_cross_process.js");
 }
 
 function load_channel(url) {
   ok(url);
   URL = url; // save this to open the alt data channel later
   var chan = make_channel(url);
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType("text/binary", "");
+  cc.preferAlternativeDataType("text/binary");
   chan.asyncOpen2(new ChannelListener(readTextData, null));
 }
 
 function make_channel(url, callback, ctx) {
   return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
 }
 
 function readTextData(request, buffer)
@@ -59,17 +59,17 @@ function readTextData(request, buffer)
       Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(cacheFlushObserver2);
     });
   });
 }
 
 function openAltChannel() {
   var chan = make_channel(URL);
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
-  cc.preferAlternativeDataType("text/parent-binary", "");
+  cc.preferAlternativeDataType("text/parent-binary");
   chan.asyncOpen2(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.