Backed out 6 changesets (bug 1371699) for various failures including frequent img-blobURI-2.html failures and leaks a=backout
authorWes Kocher <wkocher@mozilla.com>
Tue, 13 Jun 2017 17:50:11 -0700
changeset 363868 3611ff7a79e6b616088bc4bf14e7ba8cdfe8bebf
parent 363867 d14e2e6cae0e185a8c04b7b906c8784c6916a614
child 363869 3e1f13b62ce5ba0c0f2a4a3b413715af7f762596
push id32027
push usercbook@mozilla.com
push dateWed, 14 Jun 2017 12:45:45 +0000
treeherdermozilla-central@45fde181a497 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1371699
milestone56.0a1
backs out67a27cf0ab80b8ffdf672235e1816e8d795d6840
7e494fa9008731d27e3edd6946b2a30dd0f36e91
30405ec37e1e2441ed1f7e91cfa114ff22868c26
2d67624a01dc4894d647ebae9aaac75097b3b353
503c9d22e6bbaa92f42940f878b797c765f54708
eedcb67a9fb6b04fb4f204948a2aafa50bbfcabd
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 6 changesets (bug 1371699) for various failures including frequent img-blobURI-2.html failures and leaks a=backout Backed out changeset 67a27cf0ab80 (bug 1371699) Backed out changeset 7e494fa90087 (bug 1371699) Backed out changeset 30405ec37e1e (bug 1371699) Backed out changeset 2d67624a01dc (bug 1371699) Backed out changeset 503c9d22e6bb (bug 1371699) Backed out changeset eedcb67a9fb6 (bug 1371699) MozReview-Commit-ID: 4HydLjK7Ond
browser/components/feeds/nsFeedSniffer.cpp
dom/file/MultipartBlobImpl.cpp
dom/html/HTMLFormSubmission.cpp
dom/html/HTMLFormSubmission.h
dom/network/TCPSocket.cpp
dom/network/UDPSocket.cpp
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/presentation/PresentationTCPSessionTransport.cpp
dom/security/nsCSPContext.cpp
dom/workers/FileReaderSync.cpp
image/decoders/icon/android/nsIconChannel.cpp
image/decoders/icon/gtk/nsIconChannel.cpp
image/decoders/icon/mac/nsIconChannelCocoa.mm
image/decoders/icon/win/nsIconChannel.cpp
intl/uconv/nsScriptableUConv.cpp
ipc/glue/IPCStreamSource.cpp
ipc/glue/IPCStreamSource.h
netwerk/base/nsNetUtil.cpp
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/streamconv/converters/nsHTTPCompressConv.cpp
netwerk/streamconv/converters/nsUnknownDecoder.cpp
startupcache/StartupCache.cpp
startupcache/StartupCacheUtils.cpp
toolkit/components/downloads/ApplicationReputation.cpp
toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
xpcom/io/SnappyUncompressInputStream.cpp
xpcom/io/SnappyUncompressInputStream.h
xpcom/io/nsIMultiplexInputStream.idl
xpcom/io/nsIStringStream.idl
xpcom/io/nsMultiplexInputStream.cpp
xpcom/io/nsStringStream.cpp
xpcom/io/nsStringStream.h
xpcom/tests/gtest/TestCloneInputStream.cpp
xpcom/tests/gtest/TestMultiplexInputStream.cpp
xpcom/tests/gtest/TestSlicedInputStream.cpp
--- a/browser/components/feeds/nsFeedSniffer.cpp
+++ b/browser/components/feeds/nsFeedSniffer.cpp
@@ -68,27 +68,28 @@ nsFeedSniffer::ConvertEncodedData(nsIReq
       nsCOMPtr<nsIStreamListener> converter;
       rv = converterService->AsyncConvertData(contentEncoding.get(), 
                                               "uncompressed", this, nullptr, 
                                               getter_AddRefs(converter));
       NS_ENSURE_SUCCESS(rv, rv);
 
       converter->OnStartRequest(request, nullptr);
 
-      if (data) {
-        nsCOMPtr<nsIInputStream> rawStream;
-        rv = NS_NewCStringInputStream(
-          getter_AddRefs(rawStream),
-          nsDependentCSubstring(reinterpret_cast<const char*>(data), length));
-        if (NS_SUCCEEDED(rv)) {
-          rv = converter->OnDataAvailable(request, nullptr, rawStream, 0, length);
-        }
-      }
+      nsCOMPtr<nsIStringInputStream> rawStream =
+        do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID);
+      if (!rawStream)
+        return NS_ERROR_FAILURE;
 
-      converter->OnStopRequest(request, nullptr, rv);
+      rv = rawStream->SetData((const char*)data, length);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = converter->OnDataAvailable(request, nullptr, rawStream, 0, length);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      converter->OnStopRequest(request, nullptr, NS_OK);
     }
   }
   return rv;
 }
 
 template<int N>
 static bool
 StringBeginsWithLowercaseLiteral(nsAString& aString,
--- a/dom/file/MultipartBlobImpl.cpp
+++ b/dom/file/MultipartBlobImpl.cpp
@@ -80,17 +80,17 @@ MultipartBlobImpl::GetInternalStream(nsI
     }
 
     aRv = stream->AppendStream(scratchStream);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
   }
 
-  CallQueryInterface(stream, aStream);
+  stream.forget(aStream);
 }
 
 already_AddRefed<BlobImpl>
 MultipartBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
                                const nsAString& aContentType,
                                ErrorResult& aRv)
 {
   // If we clamped to nothing we create an empty blob
--- a/dom/html/HTMLFormSubmission.cpp
+++ b/dom/html/HTMLFormSubmission.cpp
@@ -419,19 +419,18 @@ FSURLEncoded::URLEncode(const nsAString&
 } // anonymous namespace
 
 // --------------------------------------------------------------------------
 
 FSMultipartFormData::FSMultipartFormData(NotNull<const Encoding*> aEncoding,
                                          nsIContent* aOriginatingElement)
   : EncodingFormSubmission(aEncoding, aOriginatingElement)
 {
-  mPostData =
+  mPostDataStream =
     do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
-  mPostDataStream = do_QueryInterface(mPostData);
   mTotalLength = 0;
 
   mBoundary.AssignLiteral("---------------------------");
   mBoundary.AppendInt(rand());
   mBoundary.AppendInt(rand());
   mBoundary.AppendInt(rand());
 }
 
@@ -626,17 +625,17 @@ FSMultipartFormData::AddDataChunk(const 
 
   // We should not try to append an invalid stream. That will happen for example
   // if we try to update a file that actually do not exist.
   if (aInputStream) {
     // We need to dump the data up to this point into the POST data stream
     // here, since we're about to add the file input stream
     AddPostDataStream();
 
-    mPostData->AppendStream(aInputStream);
+    mPostDataStream->AppendStream(aInputStream);
     mTotalLength += aInputStreamSize;
   }
 
   // CRLF after file
   mPostDataChunk.AppendLiteral(CRLF);
 }
 
 nsresult
@@ -667,17 +666,17 @@ FSMultipartFormData::AddPostDataStream()
 {
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsIInputStream> postDataChunkStream;
   rv = NS_NewCStringInputStream(getter_AddRefs(postDataChunkStream),
                                 mPostDataChunk);
   NS_ASSERTION(postDataChunkStream, "Could not open a stream for POST!");
   if (postDataChunkStream) {
-    mPostData->AppendStream(postDataChunkStream);
+    mPostDataStream->AppendStream(postDataChunkStream);
     mTotalLength += mPostDataChunk.Length();
   }
 
   mPostDataChunk.Truncate();
 
   return rv;
 }
 
--- a/dom/html/HTMLFormSubmission.h
+++ b/dom/html/HTMLFormSubmission.h
@@ -209,22 +209,17 @@ private:
                     const nsACString& aContentType,
                     nsIInputStream* aInputStream,
                     uint64_t aInputStreamSize);
   /**
    * The post data stream as it is so far.  This is a collection of smaller
    * chunks--string streams and file streams interleaved to make one big POST
    * stream.
    */
-  nsCOMPtr<nsIMultiplexInputStream> mPostData;
-
-  /**
-   * The same stream, but as an nsIInputStream.
-   */
-  nsCOMPtr<nsIInputStream> mPostDataStream;
+  nsCOMPtr<nsIMultiplexInputStream> mPostDataStream;
 
   /**
    * The current string chunk.  When a file is hit, the string chunk gets
    * wrapped up into an input stream and put into mPostDataStream so that the
    * file input stream can then be appended and everything is in the right
    * order.  Then the string chunk gets appended to again as we process more
    * name/value pairs.
    */
--- a/dom/network/TCPSocket.cpp
+++ b/dom/network/TCPSocket.cpp
@@ -213,26 +213,25 @@ TCPSocket::CreateStream()
     mInputStreamScriptable = do_CreateInstance("@mozilla.org/scriptableinputstream;1", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = mInputStreamScriptable->Init(mSocketInputStream);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   mMultiplexStream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIInputStream> stream = do_QueryInterface(mMultiplexStream);
 
   mMultiplexStreamCopier = do_CreateInstance("@mozilla.org/network/async-stream-copier;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISocketTransportService> sts =
       do_GetService("@mozilla.org/network/socket-transport-service;1");
 
   nsCOMPtr<nsIEventTarget> target = do_QueryInterface(sts);
-  rv = mMultiplexStreamCopier->Init(stream,
+  rv = mMultiplexStreamCopier->Init(mMultiplexStream,
                                     mSocketOutputStream,
                                     target,
                                     true, /* source buffered */
                                     false, /* sink buffered */
                                     BUFFER_SIZE,
                                     false, /* close source */
                                     false); /* close sink */
   NS_ENSURE_SUCCESS(rv, rv);
@@ -607,18 +606,17 @@ TCPSocket::Ssl()
 uint64_t
 TCPSocket::BufferedAmount()
 {
   if (mSocketBridgeChild) {
     return mBufferedAmount;
   }
   if (mMultiplexStream) {
     uint64_t available = 0;
-    nsCOMPtr<nsIInputStream> stream(do_QueryInterface(mMultiplexStream));
-    stream->Available(&available);
+    mMultiplexStream->Available(&available);
     return available;
   }
   return 0;
 }
 
 void
 TCPSocket::Suspend()
 {
--- a/dom/network/UDPSocket.cpp
+++ b/dom/network/UDPSocket.cpp
@@ -367,17 +367,17 @@ UDPSocket::Send(const StringOrBlobOrArra
       data.ComputeLengthAndData();
       aRv = strStream->SetData(reinterpret_cast<const char*>(data.Data()), data.Length());
     }
 
     if (NS_WARN_IF(aRv.Failed())) {
       return false;
     }
 
-    stream = do_QueryInterface(strStream);
+    stream = strStream;
   }
 
   if (mSocket) {
     aRv = mSocket->SendBinaryStream(remoteAddress, remotePort, stream);
   } else if (mSocketChild) {
     aRv = mSocketChild->SendBinaryStream(remoteAddress, remotePort, stream);
   }
 
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -575,17 +575,17 @@ nsresult nsPluginHost::PostURL(nsISuppor
     free(dataToPost);
     return rv;
   }
 
   // data allocated by ParsePostBufferToFixHeaders() is managed and
   // freed by the string stream.
   postDataLen = newDataToPostLen;
   sis->AdoptData(dataToPost, postDataLen);
-  postStream = do_QueryInterface(sis);
+  postStream = sis;
 
   if (target) {
     RefPtr<nsPluginInstanceOwner> owner = instance->GetOwner();
     if (owner) {
       rv = owner->GetURL(url, target, postStream,
                          (void*)postHeaders, postHeadersLength, true);
     }
   }
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -20,17 +20,17 @@ using mozilla::DefaultXDisplay;
 #include "nsContentUtils.h"
 #include "nsRect.h"
 #include "nsSize.h"
 #include "nsDisplayList.h"
 #include "ImageLayers.h"
 #include "GLImages.h"
 #include "nsPluginFrame.h"
 #include "nsIPluginDocument.h"
-#include "nsStringStream.h"
+#include "nsIStringStream.h"
 #include "nsNetUtil.h"
 #include "mozilla/Preferences.h"
 #include "nsILinkHandler.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsLayoutUtils.h"
 #include "nsIPluginWidget.h"
 #include "nsViewManager.h"
@@ -535,21 +535,23 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, baseURI);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIInputStream> headersDataStream;
   if (aPostStream && aHeadersData) {
     if (!aHeadersDataLen)
       return NS_ERROR_UNEXPECTED;
 
-    rv = NS_NewCStringInputStream(
-      getter_AddRefs(headersDataStream),
-      nsDependentCSubstring(reinterpret_cast<const char*>(aHeadersData),
-                            aHeadersDataLen));
+    nsCOMPtr<nsIStringInputStream> sis = do_CreateInstance("@mozilla.org/io/string-input-stream;1");
+    if (!sis)
+      return NS_ERROR_OUT_OF_MEMORY;
+
+    rv = sis->SetData((char *)aHeadersData, aHeadersDataLen);
     NS_ENSURE_SUCCESS(rv, rv);
+    headersDataStream = do_QueryInterface(sis);
   }
 
   int32_t blockPopups =
     Preferences::GetInt("privacy.popups.disable_from_plugins");
   nsAutoPopupStatePusher popupStatePusher((PopupControlState)blockPopups);
 
 
   // if security checks (in particular CheckLoadURIWithPrincipal) needs
--- a/dom/presentation/PresentationTCPSessionTransport.cpp
+++ b/dom/presentation/PresentationTCPSessionTransport.cpp
@@ -17,17 +17,16 @@
 #include "nsISupportsPrimitives.h"
 #include "nsNetUtil.h"
 #include "nsQueryObject.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 #include "PresentationLog.h"
 #include "PresentationTCPSessionTransport.h"
-#include "nsStringStream.h"
 
 #define BUFFER_SIZE 65536
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 class CopierCallbacks final : public nsIRequestObserver
 {
@@ -233,31 +232,30 @@ PresentationTCPSessionTransport::CreateS
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   mMultiplexStream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
-  nsCOMPtr<nsIInputStream> stream = do_QueryInterface(mMultiplexStream);
 
   mMultiplexStreamCopier = do_CreateInstance("@mozilla.org/network/async-stream-copier;1", &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsCOMPtr<nsISocketTransportService> sts =
     do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID);
   if (NS_WARN_IF(!sts)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsCOMPtr<nsIEventTarget> target = do_QueryInterface(sts);
-  rv = mMultiplexStreamCopier->Init(stream,
+  rv = mMultiplexStreamCopier->Init(mMultiplexStream,
                                     mSocketOutputStream,
                                     target,
                                     true, /* source buffered */
                                     false, /* sink buffered */
                                     BUFFER_SIZE,
                                     false, /* close source */
                                     false); /* close sink */
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -390,20 +388,26 @@ PresentationTCPSessionTransport::NotifyC
 
 NS_IMETHODIMP
 PresentationTCPSessionTransport::Send(const nsAString& aData)
 {
   if (NS_WARN_IF(mReadyState != ReadyState::OPEN)) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
-  nsCOMPtr<nsIInputStream> stream;
-  nsresult rv = NS_NewCStringInputStream(getter_AddRefs(stream),
-                                         NS_ConvertUTF16toUTF8(aData));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
+  nsresult rv;
+  nsCOMPtr<nsIStringInputStream> stream =
+    do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
+  if(NS_WARN_IF(NS_FAILED(rv))) {
+    return NS_ERROR_DOM_INVALID_STATE_ERR;
+  }
+
+  NS_ConvertUTF16toUTF8 msgString(aData);
+  rv = stream->SetData(msgString.BeginReading(), msgString.Length());
+  if(NS_WARN_IF(NS_FAILED(rv))) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   mMultiplexStream->AppendStream(stream);
 
   EnsureCopying();
 
   return NS_OK;
--- a/dom/security/nsCSPContext.cpp
+++ b/dom/security/nsCSPContext.cpp
@@ -1010,31 +1010,31 @@ nsCSPContext::SendReports(nsISupports* a
     reportChannel->SetNotificationCallbacks(reportSink);
 
     // apply the loadgroup from the channel taken by setRequestContext.  If
     // there's no loadgroup, AsyncOpen will fail on process-split necko (since
     // the channel cannot query the iTabChild).
     rv = reportChannel->SetLoadGroup(mCallingChannelLoadGroup);
     NS_ENSURE_SUCCESS(rv, rv);
 
+    // wire in the string input stream to send the report
+    nsCOMPtr<nsIStringInputStream> sis(do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID));
+    NS_ASSERTION(sis, "nsIStringInputStream is needed but not available to send CSP violation reports");
+    nsAutoCString utf8CSPReport = NS_ConvertUTF16toUTF8(csp_report);
+    rv = sis->SetData(utf8CSPReport.get(), utf8CSPReport.Length());
+    NS_ENSURE_SUCCESS(rv, rv);
+
     nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(reportChannel));
     if (!uploadChannel) {
       // It's possible the URI provided can't be uploaded to, in which case
       // we skip this one. We'll already have warned about a non-HTTP URI earlier.
       continue;
     }
 
-    // wire in the string input stream to send the report
-    nsCOMPtr<nsIInputStream> stream;
-    rv = NS_NewCStringInputStream(getter_AddRefs(stream),
-                                  NS_ConvertUTF16toUTF8(csp_report));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = uploadChannel->SetUploadStream(
-      stream, NS_LITERAL_CSTRING("application/csp-report"), -1);
+    rv = uploadChannel->SetUploadStream(sis, NS_LITERAL_CSTRING("application/csp-report"), -1);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // if this is an HTTP channel, set the request method to post
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(reportChannel));
     if (httpChannel) {
       rv = httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
       MOZ_ASSERT(NS_SUCCEEDED(rv));
     }
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -226,18 +226,17 @@ FileReaderSync::ReadAsText(Blob& aBlob,
   // already closed or there is nothing to read.
   if (syncStream) {
     aRv = multiplexStream->AppendStream(syncStream);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
   }
 
-  nsCOMPtr<nsIInputStream> multiplex(do_QueryInterface(multiplexStream));
-  aRv = ConvertStream(multiplex, encoding.get(), aResult);
+  aRv = ConvertStream(multiplexStream, encoding.get(), aResult);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 }
 
 void
 FileReaderSync::ReadAsDataURL(Blob& aBlob, nsAString& aResult,
                               ErrorResult& aRv)
--- a/image/decoders/icon/android/nsIconChannel.cpp
+++ b/image/decoders/icon/android/nsIconChannel.cpp
@@ -6,17 +6,16 @@
 #include <stdlib.h>
 #include "mozilla/dom/ContentChild.h"
 #include "nsMimeTypes.h"
 #include "nsIURL.h"
 #include "nsXULAppAPI.h"
 #include "AndroidBridge.h"
 #include "nsIconChannel.h"
 #include "nsIStringStream.h"
-#include "nsIInputStream.h"
 #include "nsNetUtil.h"
 #include "nsComponentManagerUtils.h"
 #include "NullPrincipal.h"
 
 NS_IMPL_ISUPPORTS(nsIconChannel,
                   nsIRequest,
                   nsIChannel)
 
@@ -101,25 +100,23 @@ moz_icon_to_channel(nsIURI* aURI, const 
       *(out++) = DO_PREMULTIPLY(b);
       *(out++) = DO_PREMULTIPLY(g);
       *(out++) = DO_PREMULTIPLY(r);
       *(out++) = a;
 #undef DO_PREMULTIPLY
     }
   }
 
-  nsCOMPtr<nsIStringInputStream> sis =
+  nsCOMPtr<nsIStringInputStream> stream =
     do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = sis->AdoptData((char*)buf, buf_size);
+  rv = stream->AdoptData((char*)buf, buf_size);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIInputStream> stream = do_QueryInterface(sis);
-
   // nsIconProtocolHandler::NewChannel2 will provide the correct loadInfo for
   // this iconChannel. Use the most restrictive security settings for the
   // temporary loadInfo to make sure the channel can not be openend.
   nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::Create();
   return NS_NewInputStreamChannel(aChannel,
                                   aURI,
                                   stream,
                                   nullPrincipal,
--- a/image/decoders/icon/gtk/nsIconChannel.cpp
+++ b/image/decoders/icon/gtk/nsIconChannel.cpp
@@ -19,17 +19,16 @@
 #include "nsMimeTypes.h"
 #include "nsIMIMEService.h"
 
 #include "nsServiceManagerUtils.h"
 
 #include "nsNetUtil.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIStringStream.h"
-#include "nsIInputStream.h"
 #include "nsServiceManagerUtils.h"
 #include "NullPrincipal.h"
 #include "nsIURL.h"
 #include "prlink.h"
 #include "gfxPlatform.h"
 
 NS_IMPL_ISUPPORTS(nsIconChannel,
                   nsIRequest,
@@ -82,35 +81,33 @@ moz_gdk_pixbuf_to_channel(GdkPixbuf* aPi
 #endif
 #undef DO_PREMULTIPLY
     }
   }
 
   NS_ASSERTION(out == buf + buf_size, "size miscalculation");
 
   nsresult rv;
-  nsCOMPtr<nsIStringInputStream> sis =
+  nsCOMPtr<nsIStringInputStream> stream =
     do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
 
   // Prevent the leaking of buf
   if (NS_WARN_IF(NS_FAILED(rv))) {
     free(buf);
     return rv;
   }
 
   // stream takes ownership of buf and will free it on destruction.
   // This function cannot fail.
-  rv = sis->AdoptData((char*)buf, buf_size);
+  rv = stream->AdoptData((char*)buf, buf_size);
 
   // If this no longer holds then re-examine buf's lifetime.
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIInputStream> stream(do_QueryInterface(sis));
-
   // nsIconProtocolHandler::NewChannel2 will provide the correct loadInfo for
   // this iconChannel. Use the most restrictive security settings for the
   // temporary loadInfo to make sure the channel can not be openend.
   nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::Create();
   return NS_NewInputStreamChannel(aChannel,
                                   aURI,
                                   stream,
                                   nullPrincipal,
--- a/image/decoders/icon/mac/nsIconChannelCocoa.mm
+++ b/image/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -9,17 +9,17 @@
 #include "mozilla/EndianUtils.h"
 #include "nsIIconURI.h"
 #include "nsIServiceManager.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsXPIDLString.h"
 #include "nsMimeTypes.h"
 #include "nsMemory.h"
-#include "nsIInputStream.h"
+#include "nsIStringStream.h"
 #include "nsIURL.h"
 #include "nsNetCID.h"
 #include "nsIPipe.h"
 #include "nsIOutputStream.h"
 #include "nsIMIMEService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsILocalFileMac.h"
 #include "nsIFileURL.h"
--- a/image/decoders/icon/win/nsIconChannel.cpp
+++ b/image/decoders/icon/win/nsIconChannel.cpp
@@ -10,17 +10,17 @@
 #include "nsIIconURI.h"
 #include "nsIServiceManager.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsMimeTypes.h"
 #include "nsMemory.h"
-#include "nsIInputStream.h"
+#include "nsIStringStream.h"
 #include "nsIURL.h"
 #include "nsIOutputStream.h"
 #include "nsIPipe.h"
 #include "nsNetCID.h"
 #include "nsIFile.h"
 #include "nsIFileURL.h"
 #include "nsIMIMEService.h"
 #include "nsCExternalHandlerService.h"
--- a/intl/uconv/nsScriptableUConv.cpp
+++ b/intl/uconv/nsScriptableUConv.cpp
@@ -3,17 +3,16 @@
 /* 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 "nsString.h"
 #include "nsIScriptableUConv.h"
 #include "nsScriptableUConv.h"
 #include "nsIStringStream.h"
-#include "nsIInputStream.h"
 #include "nsComponentManagerUtils.h"
 
 using namespace mozilla;
 
 /* Implementation file */
 NS_IMPL_ISUPPORTS(nsScriptableUnicodeConverter, nsIScriptableUnicodeConverter)
 
 nsScriptableUnicodeConverter::nsScriptableUnicodeConverter()
@@ -229,17 +228,18 @@ nsScriptableUnicodeConverter::ConvertToI
     return rv;
 
   rv = inputStream->AdoptData(reinterpret_cast<char*>(data), dataLen);
   if (NS_FAILED(rv)) {
     free(data);
     return rv;
   }
 
-  return CallQueryInterface(inputStream, _retval);
+  NS_ADDREF(*_retval = inputStream);
+  return rv;
 }
 
 NS_IMETHODIMP
 nsScriptableUnicodeConverter::GetCharset(nsACString& aCharset)
 {
   if (!mDecoder) {
     aCharset.Truncate();
   } else {
--- a/ipc/glue/IPCStreamSource.cpp
+++ b/ipc/glue/IPCStreamSource.cpp
@@ -185,50 +185,41 @@ IPCStreamSource::ActorDestroyed()
     mWorkerPrivate = nullptr;
   }
 }
 
 void
 IPCStreamSource::Start()
 {
   NS_ASSERT_OWNINGTHREAD(IPCStreamSource);
-  DoRead(ReadReason::Starting);
+  DoRead();
 }
 
 void
 IPCStreamSource::StartDestroy()
 {
   NS_ASSERT_OWNINGTHREAD(IPCStreamSource);
   OnEnd(NS_ERROR_ABORT);
 }
 
 void
-IPCStreamSource::DoRead(ReadReason aReadReason)
+IPCStreamSource::DoRead()
 {
   NS_ASSERT_OWNINGTHREAD(IPCStreamSource);
   MOZ_ASSERT(mState == eActorConstructed);
   MOZ_ASSERT(!mCallback);
 
   // The input stream (likely a pipe) probably uses a segment size of
   // 4kb.  If there is data already buffered it would be nice to aggregate
   // multiple segments into a single IPC call.  Conversely, don't send too
   // too large of a buffer in a single call to avoid spiking memory.
   static const uint64_t kMaxBytesPerMessage = 32 * 1024;
   static_assert(kMaxBytesPerMessage <= static_cast<uint64_t>(UINT32_MAX),
                 "kMaxBytesPerMessage must cleanly cast to uint32_t");
 
-  // Per the nsIInputStream API, having 0 bytes available in a stream is
-  // ambiguous.  It could mean "no data yet, but some coming later" or it could
-  // mean "EOF" (end of stream).
-  //
-  // If we're just starting up, we can't distinguish between those two options.
-  // But if we're being notified that an async stream is ready, then the
-  // first Available() call returning 0 should really mean end of stream.
-  // Subsequent Available() calls, after we read some data, could mean anything.
-  bool noDataMeansEOF = (aReadReason == ReadReason::Notified);
   while (true) {
     // It should not be possible to transition to closed state without
     // this loop terminating via a return.
     MOZ_ASSERT(mState == eActorConstructed);
 
     // Use non-auto here as we're unlikely to hit stack storage with the
     // sizes we are sending.  Also, it would be nice to avoid another copy
     // to the IPC layer which we avoid if we use COW strings.  Unfortunately
@@ -238,37 +229,30 @@ IPCStreamSource::DoRead(ReadReason aRead
     uint64_t available = 0;
     nsresult rv = mStream->Available(&available);
     if (NS_FAILED(rv)) {
       OnEnd(rv);
       return;
     }
 
     if (available == 0) {
-      if (noDataMeansEOF) {
-        OnEnd(rv);
-      } else {
-        Wait();
-      }
+      Wait();
       return;
     }
 
     uint32_t expectedBytes =
       static_cast<uint32_t>(std::min(available, kMaxBytesPerMessage));
 
     buffer.SetLength(expectedBytes);
 
     uint32_t bytesRead = 0;
     rv = mStream->Read(buffer.BeginWriting(), buffer.Length(), &bytesRead);
     MOZ_ASSERT_IF(NS_FAILED(rv), bytesRead == 0);
     buffer.SetLength(bytesRead);
 
-    // After this point, having no data tells us nothing about EOF.
-    noDataMeansEOF = false;
-
     // If we read any data from the stream, send it across.
     if (!buffer.IsEmpty()) {
       SendData(buffer);
     }
 
     if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
       Wait();
       return;
@@ -302,17 +286,17 @@ IPCStreamSource::Wait()
 void
 IPCStreamSource::OnStreamReady(Callback* aCallback)
 {
   NS_ASSERT_OWNINGTHREAD(IPCStreamSource);
   MOZ_ASSERT(mCallback);
   MOZ_ASSERT(aCallback == mCallback);
   mCallback->ClearSource();
   mCallback = nullptr;
-  DoRead(ReadReason::Notified);
+  DoRead();
 }
 
 void
 IPCStreamSource::OnEnd(nsresult aRv)
 {
   NS_ASSERT_OWNINGTHREAD(IPCStreamSource);
   MOZ_ASSERT(aRv != NS_BASE_STREAM_WOULD_BLOCK);
 
--- a/ipc/glue/IPCStreamSource.h
+++ b/ipc/glue/IPCStreamSource.h
@@ -116,21 +116,17 @@ protected:
 
 private:
   class Callback;
 
   // WorkerHolder methods
   virtual bool
   Notify(dom::workers::Status aStatus) override;
 
-  enum class ReadReason {
-    Starting, // We're trying to read because we just started off.
-    Notified  // We're trying to read because the streams said it's ready.
-  };
-  void DoRead(ReadReason aReadReason);
+  void DoRead();
 
   void Wait();
 
   void OnStreamReady(Callback* aCallback);
 
   nsCOMPtr<nsIAsyncInputStream> mStream;
   RefPtr<Callback> mCallback;
 
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -617,21 +617,25 @@ NS_NewInputStreamChannel(nsIChannel     
 nsresult
 NS_NewInputStreamChannelInternal(nsIChannel        **outChannel,
                                  nsIURI             *aUri,
                                  const nsAString    &aData,
                                  const nsACString   &aContentType,
                                  nsILoadInfo        *aLoadInfo,
                                  bool                aIsSrcdocChannel /* = false */)
 {
-  nsCOMPtr<nsIInputStream> stream;
-  nsresult rv = NS_NewCStringInputStream(getter_AddRefs(stream),
-                                         NS_ConvertUTF16toUTF8(aData));
+  nsresult rv;
+  nsCOMPtr<nsIStringInputStream> stream;
+  stream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
+    uint32_t len;
+    char* utf8Bytes = ToNewUTF8String(aData, &len);
+    rv = stream->AdoptData(utf8Bytes, len);
+
   nsCOMPtr<nsIChannel> channel;
   rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel),
                                         aUri,
                                         stream,
                                         aContentType,
                                         NS_LITERAL_CSTRING("UTF-8"),
                                         aLoadInfo);
 
@@ -1445,18 +1449,22 @@ NS_NewPostDataStream(nsIInputStream  **r
                 // wrap the file stream with a buffered input stream
                 rv = NS_NewBufferedInputStream(result, fileStream, 8192);
             }
         }
         return rv;
     }
 
     // otherwise, create a string stream for the data (copies)
-    nsCOMPtr<nsIInputStream> stream;
-    rv = NS_NewCStringInputStream(getter_AddRefs(stream), data);
+    nsCOMPtr<nsIStringInputStream> stream
+        (do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv));
+    if (NS_FAILED(rv))
+        return rv;
+
+    rv = stream->SetData(data.BeginReading(), data.Length());
     if (NS_FAILED(rv))
         return rv;
 
     stream.forget(result);
     return NS_OK;
 }
 
 nsresult
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -369,18 +369,17 @@ nsHttpTransaction::Init(uint32_t caps,
         if (NS_FAILED(rv)) return rv;
 
         rv = multi->AppendStream(requestBody);
         if (NS_FAILED(rv)) return rv;
 
         // wrap the multiplexed input stream with a buffered input stream, so
         // that we write data in the largest chunks possible.  this is actually
         // necessary to workaround some common server bugs (see bug 137155).
-        nsCOMPtr<nsIInputStream> stream(do_QueryInterface(multi));
-        rv = NS_NewBufferedInputStream(getter_AddRefs(mRequestStream), stream,
+        rv = NS_NewBufferedInputStream(getter_AddRefs(mRequestStream), multi,
                                        nsIOService::gDefaultSegmentSize);
         if (NS_FAILED(rv)) return rv;
     } else {
         mRequestStream = headers;
     }
 
     nsCOMPtr<nsIThrottledInputChannel> throttled = do_QueryInterface(mChannel);
     nsIInputChannelThrottleQueue* queue;
--- a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp
+++ b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp
@@ -512,18 +512,17 @@ nsHTTPCompressConv::do_OnDataAvailable(n
 
   mStream->ShareData(buffer, count);
 
   nsCOMPtr<nsIStreamListener> listener;
   {
     MutexAutoLock lock(mMutex);
     listener = mListener;
   }
-  nsCOMPtr<nsIInputStream> stream(do_QueryInterface(mStream));
-  nsresult rv = listener->OnDataAvailable(request, context, stream,
+  nsresult rv = listener->OnDataAvailable(request, context, mStream,
                                           offset, count);
 
   // Make sure the stream no longer references |buffer| in case our listener
   // is crazy enough to try to read from |mStream| after ODA.
   mStream->ShareData("", 0);
   mDecodedDataLength += count;
 
   return rv;
--- a/netwerk/streamconv/converters/nsUnknownDecoder.cpp
+++ b/netwerk/streamconv/converters/nsUnknownDecoder.cpp
@@ -760,25 +760,29 @@ nsUnknownDecoder::ConvertEncodedData(nsI
 
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     if (listener) {
       listener->OnStartRequest(request, nullptr);
 
-      nsCOMPtr<nsIInputStream> rawStream;
-      rv = NS_NewCStringInputStream(getter_AddRefs(rawStream),
-                                    nsDependentCSubstring(data, length));
-      if (NS_SUCCEEDED(rv)) {
-        rv = listener->OnDataAvailable(request, nullptr, rawStream, 0,
-                                       length);
-      }
+      nsCOMPtr<nsIStringInputStream> rawStream =
+        do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID);
+      if (!rawStream)
+        return NS_ERROR_FAILURE;
 
-      listener->OnStopRequest(request, nullptr, rv);
+      rv = rawStream->SetData((const char*)data, length);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = listener->OnDataAvailable(request, nullptr, rawStream, 0,
+                                     length);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      listener->OnStopRequest(request, nullptr, NS_OK);
     }
   }
   return rv;
 }
 
 void
 nsBinaryDetector::DetermineContentType(nsIRequest* aRequest)
 {
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -370,28 +370,27 @@ struct CacheWriteHolder
 
 static void
 CacheCloseHelper(const nsACString& key, const CacheEntry* data,
                  const CacheWriteHolder* holder)
 {
   MOZ_ASSERT(data); // assert key was found in mTable.
 
   nsresult rv;
-  nsIStringInputStream* sis = holder->stream;
+  nsIStringInputStream* stream = holder->stream;
   nsIZipWriter* writer = holder->writer;
 
-  sis->ShareData(data->data.get(), data->size);
+  stream->ShareData(data->data.get(), data->size);
 
 #ifdef DEBUG
   bool hasEntry;
   rv = writer->HasEntry(key, &hasEntry);
   NS_ASSERTION(NS_SUCCEEDED(rv) && hasEntry == false, 
                "Existing entry in disk StartupCache.");
 #endif
-  nsCOMPtr<nsIInputStream> stream(do_QueryInterface(sis));
   rv = writer->AddEntryStream(key, holder->time, true, stream, false);
 
   if (NS_FAILED(rv)) {
     NS_WARNING("cache entry deleted but not written to disk.");
   }
 }
 
 
--- a/startupcache/StartupCacheUtils.cpp
+++ b/startupcache/StartupCacheUtils.cpp
@@ -26,18 +26,17 @@ NewObjectInputStreamFromBuffer(UniquePtr
     do_CreateInstance("@mozilla.org/io/string-input-stream;1");
   NS_ENSURE_TRUE(stringStream, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIObjectInputStream> objectInput =
     do_CreateInstance("@mozilla.org/binaryinputstream;1");
   NS_ENSURE_TRUE(objectInput, NS_ERROR_FAILURE);
 
   stringStream->AdoptData(buffer.release(), len);
-  nsCOMPtr<nsIInputStream> baseStream(do_QueryInterface(stringStream));
-  objectInput->SetInputStream(baseStream);
+  objectInput->SetInputStream(stringStream);
 
   objectInput.forget(stream);
   return NS_OK;
 }
 
 nsresult
 NewObjectOutputWrappedStorageStream(nsIObjectOutputStream **wrapperStream,
                                     nsIStorageStream** stream,
--- a/toolkit/components/downloads/ApplicationReputation.cpp
+++ b/toolkit/components/downloads/ApplicationReputation.cpp
@@ -1358,19 +1358,16 @@ PendingLookup::SendRemoteQueryInternal()
   // Set the input stream to the serialized protocol buffer
   nsCOMPtr<nsIStringInputStream> sstream =
     do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = sstream->SetData(serialized.c_str(), serialized.length());
   NS_ENSURE_SUCCESS(rv, rv);
 
-
-  nsCOMPtr<nsIInputStream> stream(do_QueryInterface(sstream));
-
   // Set up the channel to transmit the request to the service.
   nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
   rv = ios->NewChannel2(serviceUrl,
                         nullptr,
                         nullptr,
                         nullptr, // aLoadingNode
                         nsContentUtils::GetSystemPrincipal(),
                         nullptr, // aTriggeringPrincipal
@@ -1389,17 +1386,17 @@ PendingLookup::SendRemoteQueryInternal()
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
   mozilla::Unused << httpChannel;
 
   // Upload the protobuf to the application reputation service.
   nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(mChannel, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = uploadChannel->ExplicitSetUploadStream(stream,
+  rv = uploadChannel->ExplicitSetUploadStream(sstream,
     NS_LITERAL_CSTRING("application/octet-stream"), serialized.size(),
     NS_LITERAL_CSTRING("POST"), false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t timeoutMs = Preferences::GetUint(PREF_SB_DOWNLOADS_REMOTE_TIMEOUT, 10000);
   mTimeoutTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
   mTimeoutTimer->InitWithCallback(this, timeoutMs, nsITimer::TYPE_ONE_SHOT);
 
--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
@@ -541,19 +541,23 @@ nsUrlClassifierStreamUpdater::UpdateErro
   }
 
   return NS_OK;
 }
 
 nsresult
 nsUrlClassifierStreamUpdater::AddRequestBody(const nsACString &aRequestBody)
 {
-  nsCOMPtr<nsIInputStream> strStream;
-  nsresult rv = NS_NewCStringInputStream(getter_AddRefs(strStream),
-                                         aRequestBody);
+  nsresult rv;
+  nsCOMPtr<nsIStringInputStream> strStream =
+    do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = strStream->SetData(aRequestBody.BeginReading(),
+                          aRequestBody.Length());
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(mChannel, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = uploadChannel->SetUploadStream(strStream,
                                       NS_LITERAL_CSTRING("text/plain"),
                                       -1);
--- a/xpcom/io/SnappyUncompressInputStream.cpp
+++ b/xpcom/io/SnappyUncompressInputStream.cpp
@@ -3,17 +3,16 @@
 /* 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 "mozilla/SnappyUncompressInputStream.h"
 
 #include <algorithm>
 #include "nsIAsyncInputStream.h"
-#include "nsIStringStream.h"
 #include "nsStreamUtils.h"
 #include "snappy/snappy.h"
 
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(SnappyUncompressInputStream,
                   nsIInputStream);
 
@@ -33,32 +32,27 @@ SnappyUncompressInputStream::SnappyUncom
   , mUncompressedBytes(0)
   , mNextByte(0)
   , mNextChunkType(Unknown)
   , mNextChunkDataLength(0)
   , mNeedFirstStreamIdentifier(true)
 {
   // This implementation only supports sync base streams.  Verify this in debug
   // builds.  Note, this is a bit complicated because the streams we support
-  // advertise different capabilities and we have no way to ask for the real
-  // thing we care about: "does this stream ever return
-  // NS_BASE_STREAM_WOULD_BLOCK when read?":
+  // advertise different capabilities:
   //  - nsFileInputStream - blocking and sync
-  //  - nsStringInputStream - non-blocking and provides async interface
+  //  - nsStringInputStream - non-blocking and sync
   //  - nsPipeInputStream - can be blocking, but provides async interface
 #ifdef DEBUG
   bool baseNonBlocking;
   nsresult rv = mBaseStream->IsNonBlocking(&baseNonBlocking);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   if (baseNonBlocking) {
-    nsCOMPtr<nsIStringInputStream> stringStream = do_QueryInterface(mBaseStream);
-    if (!stringStream) {
-      nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(mBaseStream);
-      MOZ_ASSERT(!async);
-    }
+    nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(mBaseStream);
+    MOZ_ASSERT(!async);
   }
 #endif
 }
 
 NS_IMETHODIMP
 SnappyUncompressInputStream::Close()
 {
   if (!mBaseStream) {
--- a/xpcom/io/SnappyUncompressInputStream.h
+++ b/xpcom/io/SnappyUncompressInputStream.h
@@ -16,21 +16,18 @@
 
 namespace mozilla {
 
 class SnappyUncompressInputStream final : public nsIInputStream
                                         , protected detail::SnappyFrameUtils
 {
 public:
   // Construct a new blocking stream to uncompress the given base stream.  The
-  // base stream must be readable in its entirety without having to wait for it
-  // to have more data (e.g. must be blocking, or must have all its data
-  // already).  Specifically, the base stream must never return
-  // NS_BASE_STREAM_WOULD_BLOCK when it's read.  The base stream does not have
-  // to be buffered.
+  // base stream must also be blocking.  The base stream does not have to be
+  // buffered.
   explicit SnappyUncompressInputStream(nsIInputStream* aBaseStream);
 
 private:
   virtual ~SnappyUncompressInputStream();
 
   // Parse the next chunk of data.  This may populate mBuffer and set
   // mBufferFillSize.  This should not be called when mBuffer already
   // contains data.
--- a/xpcom/io/nsIMultiplexInputStream.idl
+++ b/xpcom/io/nsIMultiplexInputStream.idl
@@ -6,17 +6,17 @@
 #include "nsIInputStream.idl"
 
 /**
  * The multiplex stream concatenates a list of input streams into a single
  * stream.
  */
 
 [scriptable, uuid(a076fd12-1dd1-11b2-b19a-d53b5dffaade)]
-interface nsIMultiplexInputStream : nsISupports
+interface nsIMultiplexInputStream : nsIInputStream
 {
     /**
      * Number of streams in this multiplex-stream
      */
     readonly attribute unsigned long count;
 
     /**
      * Appends a stream to the end of the streams. The cursor of the stream
--- a/xpcom/io/nsIStringStream.idl
+++ b/xpcom/io/nsIStringStream.idl
@@ -1,29 +1,29 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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"
+#include "nsIInputStream.idl"
 
 %{C++
 #include "mozilla/MemoryReporting.h"
 %}
 
 native MallocSizeOf(mozilla::MallocSizeOf);
 
 /**
  * nsIStringInputStream
  *
  * Provides scriptable and specialized C++-only methods for initializing a
  * nsIInputStream implementation with a simple character array.
  */
 [scriptable, builtinclass, uuid(450cd2d4-f0fd-424d-b365-b1251f80fd53)]
-interface nsIStringInputStream : nsISupports
+interface nsIStringInputStream : nsIInputStream
 {
     /**
      * SetData - assign data to the input stream (copied on assignment).
      *
      * @param data    - stream data
      * @param dataLen - stream data length (-1 if length should be computed)
      *
      * NOTE: C++ code should consider using AdoptData or ShareData to avoid
--- a/xpcom/io/nsMultiplexInputStream.cpp
+++ b/xpcom/io/nsMultiplexInputStream.cpp
@@ -49,17 +49,16 @@ public:
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIMULTIPLEXINPUTSTREAM
   NS_DECL_NSISEEKABLESTREAM
   NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
   NS_DECL_NSICLONEABLEINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
 
   void AsyncWaitCompleted();
-  void AsyncWaitCanceled();
 
 private:
   ~nsMultiplexInputStream()
   {
   }
 
   struct MOZ_STACK_CLASS ReadSegmentsState
   {
@@ -90,17 +89,17 @@ private:
 NS_IMPL_ADDREF(nsMultiplexInputStream)
 NS_IMPL_RELEASE(nsMultiplexInputStream)
 
 NS_IMPL_CLASSINFO(nsMultiplexInputStream, nullptr, nsIClassInfo::THREADSAFE,
                   NS_MULTIPLEXINPUTSTREAM_CID)
 
 NS_INTERFACE_MAP_BEGIN(nsMultiplexInputStream)
   NS_INTERFACE_MAP_ENTRY(nsIMultiplexInputStream)
-  NS_INTERFACE_MAP_ENTRY(nsIInputStream)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIInputStream, nsIMultiplexInputStream)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISeekableStream, IsSeekable())
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
                                      IsIPCSerializable())
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICloneableInputStream,
                                      IsCloneable())
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStream,
                                      IsAsyncInputStream())
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMultiplexInputStream)
@@ -317,17 +316,17 @@ nsMultiplexInputStream::ReadSegments(nsW
   if (NS_FAILED(mStatus)) {
     return mStatus;
   }
 
   NS_ASSERTION(aWriter, "missing aWriter");
 
   nsresult rv = NS_OK;
   ReadSegmentsState state;
-  state.mThisStream = this;
+  state.mThisStream = static_cast<nsIMultiplexInputStream*>(this);
   state.mOffset = 0;
   state.mWriter = aWriter;
   state.mClosure = aClosure;
   state.mDone = false;
 
   uint32_t len = mStreams.Length();
   while (mCurrentStream < len && aCount) {
     uint32_t read;
@@ -697,40 +696,34 @@ nsMultiplexInputStream::SetEOF()
 NS_IMETHODIMP
 nsMultiplexInputStream::CloseWithStatus(nsresult aStatus)
 {
   return Close();
 }
 
 // This class is used to inform nsMultiplexInputStream that it's time to execute
 // the asyncWait callback.
-class AsyncWaitRunnable final : public CancelableRunnable
+class AsyncWaitRunnable final : public Runnable
 {
   RefPtr<nsMultiplexInputStream> mStream;
 
 public:
   explicit AsyncWaitRunnable(nsMultiplexInputStream* aStream)
-    : CancelableRunnable("AsyncWaitRunnable")
+    : Runnable("AsyncWaitRunnable")
     , mStream(aStream)
   {
     MOZ_ASSERT(aStream);
   }
 
   NS_IMETHOD
   Run() override
   {
     mStream->AsyncWaitCompleted();
     return NS_OK;
   }
-
-  nsresult Cancel() override
-  {
-    mStream->AsyncWaitCanceled();
-    return NS_OK;
-  }
 };
 
 // This helper class processes an array of nsIAsyncInputStreams, calling
 // AsyncWait() for each one of them. When all of them have answered, this helper
 // dispatches a AsyncWaitRunnable object. If there is an error calling
 // AsyncWait(), AsyncWaitRunnable is not dispatched.
 class AsyncStreamHelper final : public nsIInputStreamCallback
 {
@@ -879,31 +872,16 @@ nsMultiplexInputStream::AsyncWaitComplet
     }
 
     mAsyncWaitCallback.swap(callback);
   }
 
   callback->OnInputStreamReady(this);
 }
 
-void
-nsMultiplexInputStream::AsyncWaitCanceled()
-{
-  // The event target for our asyncwait decided to not process our event.  Go
-  // ahead and just notify our consumer that they should stop waiting for us,
-  // but that they can't get any data.  Let's hope that our AsyncWaitRunnables
-  // are always canceled on the thread we expect them to run on!  I don't see a
-  // way of checking for that, unfortunately.
-  {
-    MutexAutoLock lock(mLock);
-    mStatus = NS_BINDING_ABORTED;
-  }
-  AsyncWaitCompleted();
-}
-
 nsresult
 nsMultiplexInputStreamConstructor(nsISupports* aOuter,
                                   REFNSIID aIID,
                                   void** aResult)
 {
   *aResult = nullptr;
 
   if (aOuter) {
@@ -1037,17 +1015,17 @@ nsMultiplexInputStream::Clone(nsIInputSt
   MutexAutoLock lock(mLock);
 
   //XXXnsm Cloning a multiplex stream which has started reading is not permitted
   //right now.
   if (mCurrentStream > 0 || mStartedReadingCurrent) {
     return NS_ERROR_FAILURE;
   }
 
-  RefPtr<nsMultiplexInputStream> clone = new nsMultiplexInputStream();
+  nsCOMPtr<nsIMultiplexInputStream> clone = new nsMultiplexInputStream();
 
   nsresult rv;
   uint32_t len = mStreams.Length();
   for (uint32_t i = 0; i < len; ++i) {
     nsCOMPtr<nsICloneableInputStream> substream = do_QueryInterface(mStreams[i]);
     if (NS_WARN_IF(!substream)) {
       return NS_ERROR_FAILURE;
     }
--- a/xpcom/io/nsStringStream.cpp
+++ b/xpcom/io/nsStringStream.cpp
@@ -8,19 +8,17 @@
  * Based on original code from nsIStringStream.cpp
  */
 
 #include "ipc/IPCMessageUtils.h"
 
 #include "nsStringStream.h"
 #include "nsStreamUtils.h"
 #include "nsReadableUtils.h"
-#include "nsIAsyncInputStream.h"
 #include "nsICloneableInputStream.h"
-#include "nsIEventTarget.h"
 #include "nsISeekableStream.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCRT.h"
 #include "prerror.h"
 #include "plstr.h"
 #include "nsIClassInfoImpl.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ipc/InputStreamUtils.h"
@@ -30,49 +28,42 @@ using namespace mozilla::ipc;
 using mozilla::Maybe;
 using mozilla::Some;
 
 //-----------------------------------------------------------------------------
 // nsIStringInputStream implementation
 //-----------------------------------------------------------------------------
 
 class nsStringInputStream final
-  : public nsIAsyncInputStream
-  , public nsIStringInputStream
+  : public nsIStringInputStream
   , public nsISeekableStream
   , public nsISupportsCString
   , public nsIIPCSerializableInputStream
   , public nsICloneableInputStream
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSISTRINGINPUTSTREAM
   NS_DECL_NSISEEKABLESTREAM
   NS_DECL_NSISUPPORTSPRIMITIVE
   NS_DECL_NSISUPPORTSCSTRING
   NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
   NS_DECL_NSICLONEABLEINPUTSTREAM
-  NS_DECL_NSIASYNCINPUTSTREAM
 
   nsStringInputStream()
-    : mOffset(0)
   {
-    Clear(); // Sets mStatus too.
+    Clear();
   }
 
   explicit nsStringInputStream(const nsStringInputStream& aOther)
     : mOffset(aOther.mOffset)
-    // We don't copy the async callback state
-    , mStatus(aOther.mStatus)
   {
     // Use Assign() here because we don't want the life of the clone to be
-    // dependent on the life of the original stream.  This will ensure that we
-    // copy the other stream's string data.  Note that this also copies the "is
-    // void" flag, so copying the other stream's mStatus makes sense.
+    // dependent on the life of the original stream.
     mData.Assign(aOther.mData);
   }
 
 private:
   ~nsStringInputStream()
   {
   }
 
@@ -81,62 +72,45 @@ private:
     return mData.Length();
   }
 
   uint32_t LengthRemaining() const
   {
     return Length() - mOffset;
   }
 
-  void Clear(nsresult aStatus = NS_BASE_STREAM_CLOSED)
+  void Clear()
   {
     mData.SetIsVoid(true);
-    mStatus = NS_FAILED(aStatus) ? aStatus : NS_BASE_STREAM_CLOSED;
-    MaybeNotifyAsyncCallback();
   }
 
-  bool Closed() const
+  bool Closed()
   {
-    MOZ_ASSERT(mData.IsVoid() == NS_FAILED(mStatus),
-               "Status should match data state");
     return mData.IsVoid();
   }
 
-  void UpdateStatus()
-  {
-    // Can't use Closed() here, because that checks our status.
-    mStatus = mData.IsVoid() ? NS_BASE_STREAM_CLOSED : NS_OK;
-  }
-
-  void MaybeNotifyAsyncCallback();
-
-  nsCOMPtr<nsIInputStreamCallback> mAsyncWaitCallback;
   nsDependentCSubstring mData;
   uint32_t mOffset;
-  nsresult mStatus;
 };
 
 // This class needs to support threadsafe refcounting since people often
 // allocate a string stream, and then read it from a background thread.
 NS_IMPL_ADDREF(nsStringInputStream)
 NS_IMPL_RELEASE(nsStringInputStream)
 
 NS_IMPL_CLASSINFO(nsStringInputStream, nullptr, nsIClassInfo::THREADSAFE,
                   NS_STRINGINPUTSTREAM_CID)
 NS_IMPL_QUERY_INTERFACE_CI(nsStringInputStream,
-                           nsIAsyncInputStream,
                            nsIStringInputStream,
                            nsIInputStream,
                            nsISupportsCString,
                            nsISeekableStream,
                            nsIIPCSerializableInputStream,
                            nsICloneableInputStream)
-
 NS_IMPL_CI_INTERFACE_GETTER(nsStringInputStream,
-                            nsIAsyncInputStream,
                             nsIStringInputStream,
                             nsIInputStream,
                             nsISupportsCString,
                             nsISeekableStream,
                             nsICloneableInputStream)
 
 /////////
 // nsISupportsCString implementation
@@ -151,28 +125,27 @@ nsStringInputStream::GetType(uint16_t* a
 
 NS_IMETHODIMP
 nsStringInputStream::GetData(nsACString& data)
 {
   // The stream doesn't have any data when it is closed.  We could fake it
   // and return an empty string here, but it seems better to keep this return
   // value consistent with the behavior of the other 'getter' methods.
   if (NS_WARN_IF(Closed())) {
-    return mStatus;
+    return NS_BASE_STREAM_CLOSED;
   }
 
   data.Assign(mData);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStringInputStream::SetData(const nsACString& aData)
 {
   mData.Assign(aData);
-  UpdateStatus();
   mOffset = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStringInputStream::ToString(char** aResult)
 {
   // NOTE: This method may result in data loss, so we do not implement it.
@@ -185,46 +158,43 @@ nsStringInputStream::ToString(char** aRe
 
 NS_IMETHODIMP
 nsStringInputStream::SetData(const char* aData, int32_t aDataLen)
 {
   if (NS_WARN_IF(!aData)) {
     return NS_ERROR_INVALID_ARG;
   }
   mData.Assign(aData, aDataLen);
-  UpdateStatus();
   mOffset = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStringInputStream::AdoptData(char* aData, int32_t aDataLen)
 {
   if (NS_WARN_IF(!aData)) {
     return NS_ERROR_INVALID_ARG;
   }
   mData.Adopt(aData, aDataLen);
-  UpdateStatus();
   mOffset = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStringInputStream::ShareData(const char* aData, int32_t aDataLen)
 {
   if (NS_WARN_IF(!aData)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   if (aDataLen < 0) {
     aDataLen = strlen(aData);
   }
 
   mData.Rebind(aData, aDataLen);
-  UpdateStatus();
   mOffset = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP_(size_t)
 nsStringInputStream::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
 {
   size_t n = aMallocSizeOf(this);
@@ -244,17 +214,17 @@ nsStringInputStream::Close()
 }
 
 NS_IMETHODIMP
 nsStringInputStream::Available(uint64_t* aLength)
 {
   NS_ASSERTION(aLength, "null ptr");
 
   if (Closed()) {
-    return mStatus;
+    return NS_BASE_STREAM_CLOSED;
   }
 
   *aLength = LengthRemaining();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStringInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aReadCount)
@@ -266,17 +236,17 @@ nsStringInputStream::Read(char* aBuf, ui
 NS_IMETHODIMP
 nsStringInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
                                   uint32_t aCount, uint32_t* aResult)
 {
   NS_ASSERTION(aResult, "null ptr");
   NS_ASSERTION(Length() >= mOffset, "bad stream state");
 
   if (Closed()) {
-    return mStatus;
+    return NS_BASE_STREAM_CLOSED;
   }
 
   // We may be at end-of-file
   uint32_t maxCount = LengthRemaining();
   if (maxCount == 0) {
     *aResult = 0;
     return NS_OK;
   }
@@ -306,17 +276,17 @@ nsStringInputStream::IsNonBlocking(bool*
 /////////
 // nsISeekableStream implementation
 /////////
 
 NS_IMETHODIMP
 nsStringInputStream::Seek(int32_t aWhence, int64_t aOffset)
 {
   if (Closed()) {
-    return mStatus;
+    return NS_BASE_STREAM_CLOSED;
   }
 
   // Compute new stream position.  The given offset may be a negative value.
 
   int64_t newPos = aOffset;
   switch (aWhence) {
     case NS_SEEK_SET:
       break;
@@ -338,28 +308,28 @@ nsStringInputStream::Seek(int32_t aWhenc
   mOffset = (uint32_t)newPos;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStringInputStream::Tell(int64_t* aOutWhere)
 {
   if (Closed()) {
-    return mStatus;
+    return NS_BASE_STREAM_CLOSED;
   }
 
   *aOutWhere = mOffset;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStringInputStream::SetEOF()
 {
   if (Closed()) {
-    return mStatus;
+    return NS_BASE_STREAM_CLOSED;
   }
 
   mOffset = Length();
   return NS_OK;
 }
 
 /////////
 // nsIIPCSerializableInputStream implementation
@@ -414,74 +384,16 @@ nsStringInputStream::GetCloneable(bool* 
 NS_IMETHODIMP
 nsStringInputStream::Clone(nsIInputStream** aCloneOut)
 {
   RefPtr<nsIInputStream> ref = new nsStringInputStream(*this);
   ref.forget(aCloneOut);
   return NS_OK;
 }
 
-/////////
-// nsIAsyncInputStream implementation
-/////////
-
-NS_IMETHODIMP
-nsStringInputStream::CloseWithStatus(nsresult aStatus)
-{
-  Clear(aStatus);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsStringInputStream::AsyncWait(nsIInputStreamCallback* aCallback,
-                               uint32_t aFlags,
-                               uint32_t aRequestedCount,
-                               nsIEventTarget* aEventTarget)
-{
-  // We're going to ignore aRequestedCount, because we're really not expecting
-  // to get more bytes or anything.  And the interface says it's just a hint
-  // anyway.
-  if (mAsyncWaitCallback && aCallback) {
-    return NS_ERROR_FAILURE;
-  }
-
-  if (!aCallback) {
-    // They're just clearing a callback; nothing else to do.
-    mAsyncWaitCallback = nullptr;
-    return NS_OK;
-  }
-
-  if (aEventTarget) {
-    mAsyncWaitCallback = NS_NewInputStreamReadyEvent(aCallback, aEventTarget);
-  } else {
-    mAsyncWaitCallback = aCallback;
-  }
-
-  if (Closed() ||
-      !(aFlags & WAIT_CLOSURE_ONLY)) {
-    // If the caller just wants to know when we have data... well, we have it.
-    MaybeNotifyAsyncCallback();
-  }
-  return NS_OK;
-}
-
-void
-nsStringInputStream::MaybeNotifyAsyncCallback()
-{
-  if (!mAsyncWaitCallback) {
-    return;
-  }
-
-  // Callee can call AsyncWait from the notification, so make sure we clear
-  // mAsyncWaitCallback before we do the call.
-  nsCOMPtr<nsIInputStreamCallback> callback;
-  callback.swap(mAsyncWaitCallback);
-  callback->OnInputStreamReady(this);
-}
-
 nsresult
 NS_NewByteInputStream(nsIInputStream** aStreamResult,
                       const char* aStringToRead, int32_t aLength,
                       nsAssignmentType aAssignment)
 {
   NS_PRECONDITION(aStreamResult, "null out ptr");
 
   RefPtr<nsStringInputStream> stream = new nsStringInputStream();
--- a/xpcom/io/nsStringStream.h
+++ b/xpcom/io/nsStringStream.h
@@ -3,17 +3,16 @@
 /* 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/. */
 
 #ifndef nsStringStream_h__
 #define nsStringStream_h__
 
 #include "nsIStringStream.h"
-#include "nsIInputStream.h"
 #include "nsStringGlue.h"
 #include "nsMemory.h"
 
 /**
  * Implements:
  *   nsIStringInputStream
  *   nsIInputStream
  *   nsISeekableStream
--- a/xpcom/tests/gtest/TestCloneInputStream.cpp
+++ b/xpcom/tests/gtest/TestCloneInputStream.cpp
@@ -111,32 +111,30 @@ TEST(CloneInputStream, NonCloneableInput
   } while(available < inputString.Length());
 
   testing::ConsumeAndValidateStream(stream, inputString);
   testing::ConsumeAndValidateStream(clone, inputString);
 }
 
 TEST(CloneInputStream, CloneMultiplexStream)
 {
-  nsCOMPtr<nsIMultiplexInputStream> multiplexStream =
+  nsCOMPtr<nsIMultiplexInputStream> stream =
     do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
-  ASSERT_TRUE(multiplexStream);
-  nsCOMPtr<nsIInputStream> stream(do_QueryInterface(multiplexStream));
   ASSERT_TRUE(stream);
 
   nsTArray<char> inputData;
   testing::CreateData(1024, inputData);
   for (uint32_t i = 0; i < 2; ++i) {
     nsCString inputString(inputData.Elements(), inputData.Length());
 
     nsCOMPtr<nsIInputStream> base;
     nsresult rv = NS_NewCStringInputStream(getter_AddRefs(base), inputString);
     ASSERT_TRUE(NS_SUCCEEDED(rv));
 
-    rv = multiplexStream->AppendStream(base);
+    rv = stream->AppendStream(base);
     ASSERT_TRUE(NS_SUCCEEDED(rv));
   }
 
   // Unread stream should clone successfully.
   nsTArray<char> doubled;
   doubled.AppendElements(inputData);
   doubled.AppendElements(inputData);
 
@@ -153,32 +151,30 @@ TEST(CloneInputStream, CloneMultiplexStr
 
   nsCOMPtr<nsIInputStream> clone2;
   rv = NS_CloneInputStream(stream, getter_AddRefs(clone2));
   ASSERT_TRUE(NS_FAILED(rv));
 }
 
 TEST(CloneInputStream, CloneMultiplexStreamPartial)
 {
-  nsCOMPtr<nsIMultiplexInputStream> multiplexStream =
+  nsCOMPtr<nsIMultiplexInputStream> stream =
     do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
-  ASSERT_TRUE(multiplexStream);
-  nsCOMPtr<nsIInputStream> stream(do_QueryInterface(multiplexStream));
   ASSERT_TRUE(stream);
 
   nsTArray<char> inputData;
   testing::CreateData(1024, inputData);
   for (uint32_t i = 0; i < 2; ++i) {
     nsCString inputString(inputData.Elements(), inputData.Length());
 
     nsCOMPtr<nsIInputStream> base;
     nsresult rv = NS_NewCStringInputStream(getter_AddRefs(base), inputString);
     ASSERT_TRUE(NS_SUCCEEDED(rv));
 
-    rv = multiplexStream->AppendStream(base);
+    rv = stream->AppendStream(base);
     ASSERT_TRUE(NS_SUCCEEDED(rv));
   }
 
   // Fail when first stream read, but second hasn't been started.
   char buffer[1024];
   uint32_t read;
   nsresult rv = stream->Read(buffer, 1024, &read);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
--- a/xpcom/tests/gtest/TestMultiplexInputStream.cpp
+++ b/xpcom/tests/gtest/TestMultiplexInputStream.cpp
@@ -29,18 +29,16 @@ TEST(MultiplexInputStream, Seek_SET)
   rv = NS_NewCStringInputStream(getter_AddRefs(inputStream2), buf2);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   rv = NS_NewCStringInputStream(getter_AddRefs(inputStream3), buf3);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
   nsCOMPtr<nsIMultiplexInputStream> multiplexStream =
     do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
   ASSERT_TRUE(multiplexStream);
-  nsCOMPtr<nsIInputStream> stream(do_QueryInterface(multiplexStream));
-  ASSERT_TRUE(stream);
 
   rv = multiplexStream->AppendStream(inputStream1);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   rv = multiplexStream->AppendStream(inputStream2);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   rv = multiplexStream->AppendStream(inputStream3);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
@@ -48,56 +46,56 @@ TEST(MultiplexInputStream, Seek_SET)
   uint32_t count;
   char readBuf[4096];
   nsCOMPtr<nsISeekableStream> seekStream = do_QueryInterface(multiplexStream);
   ASSERT_TRUE(seekStream);
 
   // Seek forward in first input stream
   rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, 1);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
-  rv = stream->Available(&length);
+  rv = multiplexStream->Available(&length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)buf1.Length() + buf2.Length() + buf3.Length() - 1,
             length);
 
   // Check read is correct
-  rv = stream->Read(readBuf, 3, &count);
+  rv = multiplexStream->Read(readBuf, 3, &count);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)3, count);
-  rv = stream->Available(&length);
+  rv = multiplexStream->Available(&length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)buf1.Length() + buf2.Length() + buf3.Length() - 4,
             length);
   ASSERT_EQ(0, strncmp(readBuf, "ell", count));
 
   // Seek to start of third input stream
   rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET,
                         buf1.Length() + buf2.Length());
   ASSERT_TRUE(NS_SUCCEEDED(rv));
-  rv = stream->Available(&length);
+  rv = multiplexStream->Available(&length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)buf3.Length(), length);
 
   // Check read is correct
-  rv = stream->Read(readBuf, 5, &count);
+  rv = multiplexStream->Read(readBuf, 5, &count);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)5, count);
-  rv = stream->Available(&length);
+  rv = multiplexStream->Available(&length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)buf3.Length() - 5, length);
   ASSERT_EQ(0, strncmp(readBuf, "Foo b", count));
 
   // Seek back to start of second stream (covers bug 1272371)
   rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, buf1.Length());
   ASSERT_TRUE(NS_SUCCEEDED(rv));
-  rv = stream->Available(&length);
+  rv = multiplexStream->Available(&length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)buf2.Length() + buf3.Length(), length);
 
   // Check read is correct
-  rv = stream->Read(readBuf, 6, &count);
+  rv = multiplexStream->Read(readBuf, 6, &count);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)6, count);
-  rv = stream->Available(&length);
+  rv = multiplexStream->Available(&length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_EQ((uint64_t)buf2.Length() - 6 + buf3.Length(), length);
   ASSERT_EQ(0, strncmp(readBuf, "The qu", count));
-}
+}
\ No newline at end of file
--- a/xpcom/tests/gtest/TestSlicedInputStream.cpp
+++ b/xpcom/tests/gtest/TestSlicedInputStream.cpp
@@ -119,39 +119,16 @@ public:
   }
 
 private:
   ~NonSeekableStringStream() {}
 };
 
 NS_IMPL_ISUPPORTS(NonSeekableStringStream, nsIInputStream, nsIAsyncInputStream)
 
-/* A simple stream class that wraps another stream and does NOT implement
- * nsIAsyncInputStream.
- */
-class NonAsyncStream final : public nsIInputStream
-{
-  nsCOMPtr<nsIInputStream> mStream;
-
-public:
-  explicit NonAsyncStream(const nsACString& aBuffer)
-  {
-    NS_NewCStringInputStream(getter_AddRefs(mStream), aBuffer);
-  }
-
-  NS_DECL_THREADSAFE_ISUPPORTS
-
-  NS_FORWARD_NSIINPUTSTREAM(mStream->)
-
-private:
-  ~NonAsyncStream() {}
-};
-
-NS_IMPL_ISUPPORTS(NonAsyncStream, nsIInputStream);
-
 // Helper function for creating a seekable nsIInputStream + a SlicedInputStream.
 SlicedInputStream*
 CreateSeekableStreams(uint32_t aSize, uint64_t aStart, uint64_t aLength,
                       nsCString& aBuffer)
 {
   aBuffer.SetLength(aSize);
   for (uint32_t i = 0; i < aSize; ++i) {
     aBuffer.BeginWriting()[i] = i % 10;
@@ -172,31 +149,16 @@ CreateNonSeekableStreams(uint32_t aSize,
   for (uint32_t i = 0; i < aSize; ++i) {
     aBuffer.BeginWriting()[i] = i % 10;
   }
 
   RefPtr<NonSeekableStringStream> stream = new NonSeekableStringStream(aBuffer);
   return new SlicedInputStream(stream, aStart, aLength);
 }
 
-// Helper function for creating a non-nsIAsyncInputStream nsIInputStream + a
-// SlicedInputStream
-SlicedInputStream*
-CreateNonAsyncStreams(uint32_t aSize, uint64_t aStart, uint64_t aLength,
-		      nsCString& aBuffer)
-{
-  aBuffer.SetLength(aSize);
-  for (uint32_t i = 0; i < aSize; ++i) {
-    aBuffer.BeginWriting()[i] = i % 10;
-  }
-
-  nsCOMPtr<nsIInputStream> stream = new NonAsyncStream(aBuffer);
-  return new SlicedInputStream(stream, aStart, aLength);
-}
-
 // Same start, same length.
 TEST(TestSlicedInputStream, Simple) {
   const size_t kBufSize = 4096;
 
   nsCString buf;
   RefPtr<SlicedInputStream> sis =
     CreateSeekableStreams(kBufSize, 0, kBufSize, buf);
 
@@ -476,17 +438,17 @@ TEST(TestSlicedInputStream, Seek_END_Low
 }
 
 // Check the nsIAsyncInputStream interface
 TEST(TestSlicedInputStream, NoAsyncInputStream) {
   const size_t kBufSize = 4096;
 
   nsCString buf;
   nsCOMPtr<nsIInputStream> sis =
-    CreateNonAsyncStreams(kBufSize, 0, kBufSize, buf);
+    CreateSeekableStreams(kBufSize, 0, kBufSize, buf);
 
   // If the stream is not asyncInputStream, also SIS is not.
   nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(sis);
   ASSERT_TRUE(!async);
 }
 
 TEST(TestSlicedInputStream, AsyncInputStream) {
   nsCOMPtr<nsIAsyncInputStream> reader;