Bug 782649 - 'Remove old IPC::InputStream'. r=cjones+khuey.
authorBen Turner <bent.mozilla@gmail.com>
Wed, 22 Aug 2012 19:13:54 -0700
changeset 109134 759b5d914905b34cee5884d97a09c876eec44dda
parent 109114 bbf6a7e1598d66d88322515784c7f5a9084d4b9b
child 109135 455ed4a415aa930e7bd3916362a0dd6b2e32c8e0
push id214
push userakeybl@mozilla.com
push dateWed, 14 Nov 2012 20:38:59 +0000
treeherdermozilla-release@c8b08ec8e1aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs782649
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 782649 - 'Remove old IPC::InputStream'. r=cjones+khuey.
ipc/glue/IPCSerializableParams.ipdlh
ipc/glue/InputStreamUtils.cpp
ipc/glue/InputStreamUtils.h
ipc/ipdl/ipdl/lower.py
netwerk/base/src/Makefile.in
netwerk/base/src/nsBufferedStreams.cpp
netwerk/base/src/nsBufferedStreams.h
netwerk/base/src/nsMIMEInputStream.cpp
netwerk/ipc/NeckoMessageUtils.h
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelParent.cpp
netwerk/protocol/ftp/FTPChannelParent.h
netwerk/protocol/ftp/PFTPChannel.ipdl
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/websocket/PWebSocket.ipdl
netwerk/protocol/websocket/WebSocketChannelChild.cpp
netwerk/protocol/websocket/WebSocketChannelParent.cpp
netwerk/protocol/websocket/WebSocketChannelParent.h
xpcom/io/nsMultiplexInputStream.cpp
--- a/ipc/glue/IPCSerializableParams.ipdlh
+++ b/ipc/glue/IPCSerializableParams.ipdlh
@@ -1,12 +1,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 "IPC/IPCMessageUtils.h";
+
+using mozilla::void_t;
+
 namespace mozilla {
 namespace ipc {
 
 struct StringInputStreamParams
 {
   nsCString data;
 };
 
@@ -32,13 +36,37 @@ struct MultiplexInputStreamParams
   bool startedReadingCurrent;
 };
 
 union InputStreamParams
 {
   StringInputStreamParams;
   FileInputStreamParams;
   PartialFileInputStreamParams;
+  BufferedInputStreamParams;
+  MIMEInputStreamParams;
   MultiplexInputStreamParams;
 };
 
+union OptionalInputStreamParams
+{
+  void_t;
+  InputStreamParams;
+};
+
+struct BufferedInputStreamParams
+{
+  OptionalInputStreamParams optionalStream;
+  uint32_t bufferSize;
+};
+
+struct MIMEInputStreamParams
+{
+  OptionalInputStreamParams optionalStream;
+  nsCString headers;
+  nsCString contentLength;
+  bool startedReading;
+  bool addContentLength;
+};
+
+
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/InputStreamUtils.cpp
+++ b/ipc/glue/InputStreamUtils.cpp
@@ -5,75 +5,141 @@
 #include "InputStreamUtils.h"
 
 #include "nsIIPCSerializableInputStream.h"
 
 #include "mozilla/Assertions.h"
 #include "nsComponentManagerUtils.h"
 #include "nsDebug.h"
 #include "nsID.h"
+#include "nsMIMEInputStream.h"
 #include "nsMultiplexInputStream.h"
 #include "nsNetCID.h"
 #include "nsStringStream.h"
 #include "nsThreadUtils.h"
 
 using namespace mozilla::ipc;
 
 namespace {
 
 NS_DEFINE_CID(kStringInputStreamCID, NS_STRINGINPUTSTREAM_CID);
 NS_DEFINE_CID(kFileInputStreamCID, NS_LOCALFILEINPUTSTREAM_CID);
 NS_DEFINE_CID(kPartialFileInputStreamCID, NS_PARTIALLOCALFILEINPUTSTREAM_CID);
+NS_DEFINE_CID(kBufferedInputStreamCID, NS_BUFFEREDINPUTSTREAM_CID);
+NS_DEFINE_CID(kMIMEInputStreamCID, NS_MIMEINPUTSTREAM_CID);
 NS_DEFINE_CID(kMultiplexInputStreamCID, NS_MULTIPLEXINPUTSTREAM_CID);
 
 } // anonymous namespace
 
 namespace mozilla {
 namespace ipc {
 
+void
+SerializeInputStream(nsIInputStream* aInputStream,
+                     InputStreamParams& aParams)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aInputStream);
+
+  nsCOMPtr<nsIIPCSerializableInputStream> serializable =
+    do_QueryInterface(aInputStream);
+  if (!serializable) {
+    NS_WARNING("Input stream is not serializable!");
+    return;
+  }
+
+  serializable->Serialize(aParams);
+
+  NS_WARN_IF_FALSE(aParams.type() != InputStreamParams::T__None,
+                   "Serialize failed!");
+}
+
+void
+SerializeInputStream(nsIInputStream* aInputStream,
+                     OptionalInputStreamParams& aParams)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (aInputStream) {
+    InputStreamParams params;
+    SerializeInputStream(aInputStream, params);
+    aParams = params;
+  }
+  else {
+    aParams = mozilla::void_t();
+  }
+}
+
 already_AddRefed<nsIInputStream>
 DeserializeInputStream(const InputStreamParams& aParams)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIIPCSerializableInputStream> serializable;
 
   switch (aParams.type()) {
-    case InputStreamParams::T__None:
-      NS_WARNING("This union has no type!");
-      return nullptr;
-
     case InputStreamParams::TStringInputStreamParams:
       serializable = do_CreateInstance(kStringInputStreamCID);
       break;
 
     case InputStreamParams::TFileInputStreamParams:
       serializable = do_CreateInstance(kFileInputStreamCID);
       break;
 
     case InputStreamParams::TPartialFileInputStreamParams:
       serializable = do_CreateInstance(kPartialFileInputStreamCID);
       break;
 
+    case InputStreamParams::TBufferedInputStreamParams:
+      serializable = do_CreateInstance(kBufferedInputStreamCID);
+      break;
+
+    case InputStreamParams::TMIMEInputStreamParams:
+      serializable = do_CreateInstance(kMIMEInputStreamCID);
+      break;
+
     case InputStreamParams::TMultiplexInputStreamParams:
       serializable = do_CreateInstance(kMultiplexInputStreamCID);
       break;
 
     default:
-      NS_WARNING("Unknown params!");
+      MOZ_ASSERT(false, "Unknown params!");
       return nullptr;
   }
 
   MOZ_ASSERT(serializable);
 
   if (!serializable->Deserialize(aParams)) {
-    NS_WARNING("Deserialize failed!");
+    MOZ_ASSERT(false, "Deserialize failed!");
     return nullptr;
   }
 
   nsCOMPtr<nsIInputStream> stream = do_QueryInterface(serializable);
   MOZ_ASSERT(stream);
 
   return stream.forget();
 }
 
+already_AddRefed<nsIInputStream>
+DeserializeInputStream(const OptionalInputStreamParams& aParams)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsCOMPtr<nsIInputStream> stream;
+
+  switch (aParams.type()) {
+    case OptionalInputStreamParams::Tvoid_t:
+      // Leave stream null.
+      break;
+
+    case OptionalInputStreamParams::TInputStreamParams:
+      stream = DeserializeInputStream(aParams.get_InputStreamParams());
+      break;
+
+    default:
+      MOZ_ASSERT(false, "Unknown params!");
+  }
+
+  return stream.forget();
+}
+
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/InputStreamUtils.h
+++ b/ipc/glue/InputStreamUtils.h
@@ -7,15 +7,26 @@
 
 #include "mozilla/ipc/IPCSerializableParams.h"
 #include "nsCOMPtr.h"
 #include "nsIInputStream.h"
 
 namespace mozilla {
 namespace ipc {
 
+void
+SerializeInputStream(nsIInputStream* aInputStream,
+                     InputStreamParams& aParams);
+
+void
+SerializeInputStream(nsIInputStream* aInputStream,
+                     OptionalInputStreamParams& aParams);
+
 already_AddRefed<nsIInputStream>
 DeserializeInputStream(const InputStreamParams& aParams);
 
+already_AddRefed<nsIInputStream>
+DeserializeInputStream(const OptionalInputStreamParams& aParams);
+
 } // namespace ipc
 } // namespace mozilla
 
 #endif // mozilla_ipc_InputStreamUtils_h
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1289,20 +1289,21 @@ with some new IPDL/C++ nodes that are tu
         # reference known C++ types by their "short name" rather than
         # fully-qualified name. e.g. |Foo| rather than |a::b::Foo|.
         self.typedefs = [ ]
         self.typedefSet = set([ Typedef(Type('mozilla::ipc::ActorHandle'),
                                         'ActorHandle') ])
         self.protocolName = None
 
     def visitTranslationUnit(self, tu):
-        if not isinstance(tu, TranslationUnit) and tu not in self.visitedTus:
+        if tu not in self.visitedTus:
             self.visitedTus.add(tu)
             ipdl.ast.Visitor.visitTranslationUnit(self, tu)
-            TranslationUnit.upgrade(tu)
+            if not isinstance(tu, TranslationUnit):
+                TranslationUnit.upgrade(tu)
             self.typedefs[:] = sorted(list(self.typedefSet))
 
     def visitInclude(self, inc):
         if inc.tu.filetype == 'header':
             inc.tu.accept(self)
 
     def visitProtocol(self, pro):
         self.protocolName = pro.name
@@ -1312,30 +1313,33 @@ with some new IPDL/C++ nodes that are tu
 
 
     def visitUsingStmt(self, using):
         if using.decl.fullname is not None:
             self.typedefSet.add(Typedef(Type(using.decl.fullname),
                                         using.decl.shortname))
 
     def visitStructDecl(self, sd):
-        sd.decl.special = 0
-        newfields = [ ]
-        for f in sd.fields:
-            ftype = f.decl.type
-            if _hasVisibleActor(ftype):
-                sd.decl.special = 1
-                # if ftype has a visible actor, we need both
-                # |ActorParent| and |ActorChild| fields
-                newfields.append(_StructField(ftype, f.name, sd, side='parent'))
-                newfields.append(_StructField(ftype, f.name, sd, side='child'))
-            else:
-                newfields.append(_StructField(ftype, f.name, sd))
-        sd.fields = newfields
-        StructDecl.upgrade(sd)
+        if not isinstance(sd, StructDecl):
+            sd.decl.special = 0
+            newfields = [ ]
+            for f in sd.fields:
+                ftype = f.decl.type
+                if _hasVisibleActor(ftype):
+                    sd.decl.special = 1
+                    # if ftype has a visible actor, we need both
+                    # |ActorParent| and |ActorChild| fields
+                    newfields.append(_StructField(ftype, f.name, sd,
+                                                  side='parent'))
+                    newfields.append(_StructField(ftype, f.name, sd,
+                                                  side='child'))
+                else:
+                    newfields.append(_StructField(ftype, f.name, sd))
+            sd.fields = newfields
+            StructDecl.upgrade(sd)
 
         if sd.decl.fullname is not None:
             self.typedefSet.add(Typedef(Type(sd.fqClassName()), sd.name))
 
 
     def visitUnionDecl(self, ud):
         ud.decl.special = 0
         newcomponents = [ ]
--- a/netwerk/base/src/Makefile.in
+++ b/netwerk/base/src/Makefile.in
@@ -10,17 +10,20 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= necko
 LIBRARY_NAME	= neckobase_s
 LIBXUL_LIBRARY  = 1
 
-EXPORTS = nsURLHelper.h
+EXPORTS = \
+		nsMIMEInputStream.h \
+		nsURLHelper.h \
+		$(NULL)
 
 CPPSRCS		= \
 		nsTransportUtils.cpp \
 		nsAsyncStreamCopier.cpp \
 		nsAsyncRedirectVerifyHelper.cpp \
 		nsAuthInformationHolder.cpp \
 		nsBaseChannel.cpp \
 		nsBaseContentStream.cpp \
--- a/netwerk/base/src/nsBufferedStreams.cpp
+++ b/netwerk/base/src/nsBufferedStreams.cpp
@@ -1,22 +1,23 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "IPC/IPCMessageUtils.h"
-#include "mozilla/net/NeckoMessageUtils.h"
 
 #include "nsAlgorithm.h"
 #include "nsBufferedStreams.h"
 #include "nsStreamUtils.h"
 #include "nsCRT.h"
 #include "nsNetCID.h"
 #include "nsIClassInfoImpl.h"
+#include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/IPCSerializableParams.h"
 
 #ifdef DEBUG_brendan
 # define METERING
 #endif
 
 #ifdef METERING
 # include <stdio.h>
 # define METER(x)       x
@@ -33,16 +34,18 @@ static struct {
         int64_t         mOldOffset;
         int64_t         mNewOffset;
     } mBigSeek[MAX_BIG_SEEKS];
 } bufstats;
 #else
 # define METER(x)       /* nothing */
 #endif
 
+using namespace mozilla::ipc;
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsBufferedStream
 
 nsBufferedStream::nsBufferedStream()
     : mBuffer(nullptr),
       mBufferStartOffset(0),
       mCursor(0), 
       mFillPoint(0),
@@ -247,26 +250,25 @@ NS_IMPL_RELEASE_INHERITED(nsBufferedInpu
 
 NS_IMPL_CLASSINFO(nsBufferedInputStream, NULL, nsIClassInfo::THREADSAFE,
                   NS_BUFFEREDINPUTSTREAM_CID)
 
 NS_INTERFACE_MAP_BEGIN(nsBufferedInputStream)
     NS_INTERFACE_MAP_ENTRY(nsIInputStream)
     NS_INTERFACE_MAP_ENTRY(nsIBufferedInputStream)
     NS_INTERFACE_MAP_ENTRY(nsIStreamBufferAccess)
-    NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableObsolete)
+    NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableInputStream)
     NS_IMPL_QUERY_CLASSINFO(nsBufferedInputStream)
 NS_INTERFACE_MAP_END_INHERITING(nsBufferedStream)
 
-NS_IMPL_CI_INTERFACE_GETTER5(nsBufferedInputStream,
+NS_IMPL_CI_INTERFACE_GETTER4(nsBufferedInputStream,
                              nsIInputStream,
                              nsIBufferedInputStream,
                              nsISeekableStream,
-                             nsIStreamBufferAccess,
-                             nsIIPCSerializableObsolete)
+                             nsIStreamBufferAccess)
 
 nsresult
 nsBufferedInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
 {
     NS_ENSURE_NO_AGGREGATION(aOuter);
 
     nsBufferedInputStream* stream = new nsBufferedInputStream();
     if (stream == nullptr)
@@ -479,46 +481,74 @@ nsBufferedInputStream::GetUnbufferedStre
     mBufferStartOffset += mCursor;
     mFillPoint = mCursor = 0;
 
     *aStream = mStream;
     NS_IF_ADDREF(*aStream);
     return NS_OK;
 }
 
-bool
-nsBufferedInputStream::Read(const IPC::Message *aMsg, void **aIter)
+void
+nsBufferedInputStream::Serialize(InputStreamParams& aParams)
 {
-    using IPC::ReadParam;
+    BufferedInputStreamParams params;
+
+    if (mStream) {
+        nsCOMPtr<nsIIPCSerializableInputStream> stream =
+            do_QueryInterface(mStream);
+        NS_ASSERTION(stream, "Wrapped stream is not serializable!");
+
+        InputStreamParams wrappedParams;
+        stream->Serialize(wrappedParams);
+
+        NS_ASSERTION(wrappedParams.type() != InputStreamParams::T__None,
+                     "Wrapped stream failed to serialize!");
+
+        params.optionalStream() = wrappedParams;
+    }
+    else {
+        params.optionalStream() = mozilla::void_t();
+    }
+
+    params.bufferSize() = mBufferSize;
+
+    aParams = params;
+}
 
-    uint32_t bufferSize;
-    IPC::InputStream inputStream;
-    if (!ReadParam(aMsg, aIter, &bufferSize) ||
-        !ReadParam(aMsg, aIter, &inputStream))
+bool
+nsBufferedInputStream::Deserialize(const InputStreamParams& aParams)
+{
+    if (aParams.type() != InputStreamParams::TBufferedInputStreamParams) {
+        NS_ERROR("Received unknown parameters from the other process!");
         return false;
+    }
 
-    nsCOMPtr<nsIInputStream> stream(inputStream);
-    nsresult rv = Init(stream, bufferSize);
-    if (NS_FAILED(rv))
-        return false;
+    const BufferedInputStreamParams& params =
+        aParams.get_BufferedInputStreamParams();
+    const OptionalInputStreamParams& wrappedParams = params.optionalStream();
+
+    nsCOMPtr<nsIInputStream> stream;
+    if (wrappedParams.type() == OptionalInputStreamParams::TInputStreamParams) {
+        stream = DeserializeInputStream(wrappedParams.get_InputStreamParams());
+        if (!stream) {
+            NS_WARNING("Failed to deserialize wrapped stream!");
+            return false;
+        }
+    }
+    else {
+        NS_ASSERTION(wrappedParams.type() == OptionalInputStreamParams::Tvoid_t,
+                     "Unknown type for OptionalInputStreamParams!");
+    }
+
+    nsresult rv = Init(stream, params.bufferSize());
+    NS_ENSURE_SUCCESS(rv, false);
 
     return true;
 }
 
-void
-nsBufferedInputStream::Write(IPC::Message *aMsg)
-{
-    using IPC::WriteParam;
-
-    WriteParam(aMsg, mBufferSize);
-
-    IPC::InputStream inputStream(Source());
-    WriteParam(aMsg, inputStream);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsBufferedOutputStream
 
 NS_IMPL_ADDREF_INHERITED(nsBufferedOutputStream, nsBufferedStream)
 NS_IMPL_RELEASE_INHERITED(nsBufferedOutputStream, nsBufferedStream)
 // This QI uses NS_INTERFACE_MAP_ENTRY_CONDITIONAL to check for
 // non-nullness of mSafeStream.
 NS_INTERFACE_MAP_BEGIN(nsBufferedOutputStream)
@@ -782,9 +812,9 @@ nsBufferedOutputStream::GetUnbufferedStr
             return rv;
     }
 
     *aStream = mStream;
     NS_IF_ADDREF(*aStream);
     return NS_OK;
 }
 
-////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
--- a/netwerk/base/src/nsBufferedStreams.h
+++ b/netwerk/base/src/nsBufferedStreams.h
@@ -8,17 +8,17 @@
 
 #include "nsIBufferedStreams.h"
 #include "nsIInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsISafeOutputStream.h"
 #include "nsISeekableStream.h"
 #include "nsIStreamBufferAccess.h"
 #include "nsCOMPtr.h"
-#include "nsIIPCSerializableObsolete.h"
+#include "nsIIPCSerializableInputStream.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 
 class nsBufferedStream : public nsISeekableStream
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSISEEKABLESTREAM
@@ -55,24 +55,24 @@ protected:
     uint8_t                     mGetBufferCount;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
 class nsBufferedInputStream : public nsBufferedStream,
                               public nsIBufferedInputStream,
                               public nsIStreamBufferAccess,
-                              public nsIIPCSerializableObsolete
+                              public nsIIPCSerializableInputStream
 {
 public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIINPUTSTREAM
     NS_DECL_NSIBUFFEREDINPUTSTREAM
     NS_DECL_NSISTREAMBUFFERACCESS
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
+    NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
 
     nsBufferedInputStream() : nsBufferedStream() {}
     virtual ~nsBufferedInputStream() {}
 
     static nsresult
     Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
 
     nsIInputStream* Source() { 
--- a/netwerk/base/src/nsMIMEInputStream.cpp
+++ b/netwerk/base/src/nsMIMEInputStream.cpp
@@ -4,43 +4,46 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * The MIME stream separates headers and a datastream. It also allows
  * automatic creation of the content-length header.
  */
 
 #include "IPC/IPCMessageUtils.h"
-#include "mozilla/net/NeckoMessageUtils.h"
 
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMultiplexInputStream.h"
 #include "nsIMIMEInputStream.h"
 #include "nsISeekableStream.h"
 #include "nsIStringStream.h"
 #include "nsString.h"
 #include "nsMIMEInputStream.h"
-#include "nsIIPCSerializableObsolete.h"
 #include "nsIClassInfoImpl.h"
+#include "nsIIPCSerializableInputStream.h"
+#include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/IPCSerializableParams.h"
+
+using namespace mozilla::ipc;
 
 class nsMIMEInputStream : public nsIMIMEInputStream,
                           public nsISeekableStream,
-                          public nsIIPCSerializableObsolete
+                          public nsIIPCSerializableInputStream
 {
 public:
     nsMIMEInputStream();
     virtual ~nsMIMEInputStream();
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIINPUTSTREAM
     NS_DECL_NSIMIMEINPUTSTREAM
     NS_DECL_NSISEEKABLESTREAM
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
-    
+    NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
+
     NS_METHOD Init();
 
 private:
 
     void InitStreams();
 
     struct ReadSegmentsState {
         nsIInputStream* mThisStream;
@@ -68,22 +71,21 @@ NS_IMPL_THREADSAFE_RELEASE(nsMIMEInputSt
 
 NS_IMPL_CLASSINFO(nsMIMEInputStream, NULL, nsIClassInfo::THREADSAFE,
                   NS_MIMEINPUTSTREAM_CID)
 
 NS_IMPL_QUERY_INTERFACE4_CI(nsMIMEInputStream,
                             nsIMIMEInputStream,
                             nsIInputStream,
                             nsISeekableStream,
-                            nsIIPCSerializableObsolete)
-NS_IMPL_CI_INTERFACE_GETTER4(nsMIMEInputStream,
+                            nsIIPCSerializableInputStream)
+NS_IMPL_CI_INTERFACE_GETTER3(nsMIMEInputStream,
                              nsIMIMEInputStream,
                              nsIInputStream,
-                             nsISeekableStream,
-                             nsIIPCSerializableObsolete)
+                             nsISeekableStream)
 
 nsMIMEInputStream::nsMIMEInputStream() : mAddContentLength(false),
                                          mStartedReading(false)
 {
 }
 
 nsMIMEInputStream::~nsMIMEInputStream()
 {
@@ -288,56 +290,84 @@ nsMIMEInputStreamConstructor(nsISupports
     }
 
     rv = inst->QueryInterface(iid, result);
     NS_RELEASE(inst);
 
     return rv;
 }
 
-bool
-nsMIMEInputStream::Read(const IPC::Message *aMsg, void **aIter)
+void
+nsMIMEInputStream::Serialize(InputStreamParams& aParams)
 {
-    using IPC::ReadParam;
+    MIMEInputStreamParams params;
+
+    if (mData) {
+        nsCOMPtr<nsIIPCSerializableInputStream> stream =
+            do_QueryInterface(mData);
+        NS_ASSERTION(stream, "Wrapped stream is not serializable!");
+
+        InputStreamParams wrappedParams;
+        stream->Serialize(wrappedParams);
+
+        NS_ASSERTION(wrappedParams.type() != InputStreamParams::T__None,
+                     "Wrapped stream failed to serialize!");
+
+        params.optionalStream() = wrappedParams;
+    }
+    else {
+        params.optionalStream() = mozilla::void_t();
+    }
 
-    if (!ReadParam(aMsg, aIter, &mHeaders) ||
-        !ReadParam(aMsg, aIter, &mContentLength) ||
-        !ReadParam(aMsg, aIter, &mStartedReading))
+    params.headers() = mHeaders;
+    params.contentLength() = mContentLength;
+    params.startedReading() = mStartedReading;
+    params.addContentLength() = mAddContentLength;
+
+    aParams = params;
+}
+
+bool
+nsMIMEInputStream::Deserialize(const InputStreamParams& aParams)
+{
+    if (aParams.type() != InputStreamParams::TMIMEInputStreamParams) {
+        NS_ERROR("Received unknown parameters from the other process!");
         return false;
+    }
+
+    const MIMEInputStreamParams& params =
+        aParams.get_MIMEInputStreamParams();
+    const OptionalInputStreamParams& wrappedParams = params.optionalStream();
+
+    mHeaders = params.headers();
+    mContentLength = params.contentLength();
+    mStartedReading = params.startedReading();
 
     // nsMIMEInputStream::Init() already appended mHeaderStream & mCLStream
     mHeaderStream->ShareData(mHeaders.get(),
-                             mStartedReading? mHeaders.Length() : 0);
+                             mStartedReading ? mHeaders.Length() : 0);
     mCLStream->ShareData(mContentLength.get(),
-                         mStartedReading? mContentLength.Length() : 0);
+                         mStartedReading ? mContentLength.Length() : 0);
 
-    IPC::InputStream inputStream;
-    if (!ReadParam(aMsg, aIter, &inputStream))
-        return false;
+    nsCOMPtr<nsIInputStream> stream;
+    if (wrappedParams.type() == OptionalInputStreamParams::TInputStreamParams) {
+        stream = DeserializeInputStream(wrappedParams.get_InputStreamParams());
+        if (!stream) {
+            NS_WARNING("Failed to deserialize wrapped stream!");
+            return false;
+        }
 
-    nsCOMPtr<nsIInputStream> stream(inputStream);
-    mData = stream;
-    if (stream) {
-        nsresult rv = mStream->AppendStream(mData);
-        if (NS_FAILED(rv))
+        mData = stream;
+
+        if (NS_FAILED(mStream->AppendStream(mData))) {
+            NS_WARNING("Failed to append stream!");
             return false;
+        }
+    }
+    else {
+        NS_ASSERTION(wrappedParams.type() == OptionalInputStreamParams::Tvoid_t,
+                     "Unknown type for OptionalInputStreamParams!");
     }
 
-    if (!ReadParam(aMsg, aIter, &mAddContentLength))
-        return false;
+    mAddContentLength = params.addContentLength();
 
     return true;
 }
-
-void
-nsMIMEInputStream::Write(IPC::Message *aMsg)
-{
-    using IPC::WriteParam;
-
-    WriteParam(aMsg, mHeaders);
-    WriteParam(aMsg, mContentLength);
-    WriteParam(aMsg, mStartedReading);
-
-    IPC::InputStream inputStream(mData);
-    WriteParam(aMsg, inputStream);
-
-    WriteParam(aMsg, mAddContentLength);
-}
--- a/netwerk/ipc/NeckoMessageUtils.h
+++ b/netwerk/ipc/NeckoMessageUtils.h
@@ -138,128 +138,16 @@ struct ParamTraits<URI>
       aLog->append(StringPrintf(L"[%s]", spec.get()));
     }
     else {
       aLog->append(L"[]");
     }
   }
 };
 
-class InputStream {
- public:
-  InputStream() : mStream(nullptr) {}
-  InputStream(nsIInputStream* aStream) : mStream(aStream) {}
-  operator nsIInputStream*() const { return mStream.get(); }
-
-  friend struct ParamTraits<InputStream>;
-
- private:
-  // Unimplemented
-  InputStream& operator=(InputStream&);
-
-  nsCOMPtr<nsIInputStream> mStream;
-};
-
-template<>
-struct ParamTraits<InputStream>
-{
-  typedef InputStream paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    bool isNull = !aParam.mStream;
-    aMsg->WriteBool(isNull);
-
-    if (isNull)
-      return;
-
-    nsCOMPtr<nsIIPCSerializableObsolete> serializable =
-      do_QueryInterface(aParam.mStream);
-    bool isSerializable = !!serializable;
-    WriteParam(aMsg, isSerializable);
-
-    if (!serializable) {
-      NS_WARNING("nsIInputStream implementation doesn't support "
-                 "nsIIPCSerializableObsolete; falling back to copying data");
-
-      nsCString streamString;
-      uint64_t bytes;
-
-      nsresult rv = aParam.mStream->Available(&bytes);
-      if (NS_SUCCEEDED(rv) && bytes > 0) {
-        // Also, on 64-bit system, for an interoperability for 32-bit process
-        // and 64-bit process, we shouldn't handle over 4GB message.
-        NS_ABORT_IF_FALSE(bytes < PR_UINT32_MAX, "nsIInputStream has over 4GB data");
-        mozilla::DebugOnly<nsresult> rv =
-          NS_ReadInputStreamToString(aParam.mStream, streamString, (uint32_t)bytes);
-        NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "Can't read input stream into a string!");
-      }
-
-      WriteParam(aMsg, streamString);
-      return;
-    }
-
-    nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(aParam.mStream);
-    NS_ASSERTION(classInfo, "Must QI to nsIClassInfo for this to work!");
-
-    char cidStr[NSID_LENGTH];
-    nsCID cid;
-    mozilla::DebugOnly<nsresult> rv = classInfo->GetClassIDNoAlloc(&cid);
-    NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "All IPDL streams must report a valid class ID");
-
-    cid.ToProvidedString(cidStr);
-    WriteParam(aMsg, nsCAutoString(cidStr));
-    serializable->Write(aMsg);
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
-  {
-    bool isNull;
-    if (!ReadParam(aMsg, aIter, &isNull))
-      return false;
-
-    if (isNull) {
-      aResult->mStream = nullptr;
-      return true;
-    }
-
-    bool isSerializable;
-    if (!ReadParam(aMsg, aIter, &isSerializable))
-      return false;
-
-    nsCOMPtr<nsIInputStream> stream;
-    if (!isSerializable) {
-      nsCString streamString;
-      if (!ReadParam(aMsg, aIter, &streamString))
-        return false;
-
-      nsresult rv = NS_NewCStringInputStream(getter_AddRefs(stream), streamString);
-      if (NS_FAILED(rv))
-        return false;
-    } else {
-      nsCAutoString cidStr;
-      nsCID cid;
-      if (!ReadParam(aMsg, aIter, &cidStr) ||
-          !cid.Parse(cidStr.get()))
-        return false;
-
-      stream = do_CreateInstance(cid);
-      if (!stream)
-        return false;
-      nsCOMPtr<nsIIPCSerializableObsolete> serializable =
-        do_QueryInterface(stream);
-      if (!serializable || !serializable->Read(aMsg, aIter))
-        return false;
-    }
-
-    stream.swap(aResult->mStream);
-    return true;
-  }
-};
-
 // nsIPermissionManager utilities
 
 struct Permission
 {
   nsCString host, type;
   uint32_t capability, expireType;
   int64_t expireTime;
 
@@ -360,9 +248,9 @@ struct ParamTraits<PRNetAddr>
 
     /* We've been tricked by some socket family we don't know about! */
     return false;
   }
 };
 
 }
 
-#endif // mozilla_net_NeckoMessageUtils_h
+#endif // mozilla_net_NeckoMessageUtils_h
\ No newline at end of file
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -11,16 +11,19 @@
 
 #include "nsStringStream.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsIURIFixup.h"
 #include "nsILoadContext.h"
 #include "nsCDefaultURIFixup.h"
 #include "base/compiler_specific.h"
+#include "mozilla/ipc/InputStreamUtils.h"
+
+using namespace mozilla::ipc;
 
 #undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace net {
 
 FTPChannelChild::FTPChannelChild(nsIURI* uri)
@@ -155,18 +158,21 @@ FTPChannelChild::AsyncOpen(::nsIStreamLi
   gNeckoChild->SendPFTPChannelConstructor(this);
   mListener = listener;
   mListenerContext = aContext;
 
   // add ourselves to the load group. 
   if (mLoadGroup)
     mLoadGroup->AddRequest(this, nullptr);
 
-  SendAsyncOpen(nsBaseChannel::URI(), mStartPos, mEntityID,
-                IPC::InputStream(mUploadStream), IPC::SerializedLoadContext(this));
+  OptionalInputStreamParams uploadStream;
+  SerializeInputStream(mUploadStream, uploadStream);
+
+  SendAsyncOpen(nsBaseChannel::URI(), mStartPos, mEntityID, uploadStream,
+                IPC::SerializedLoadContext(this));
 
   // The socket transport layer in the chrome process now has a logical ref to
   // us until OnStopRequest is called.
   AddIPDLReference();
 
   mIsPending = true;
   mWasOpened = true;
 
--- a/netwerk/protocol/ftp/FTPChannelParent.cpp
+++ b/netwerk/protocol/ftp/FTPChannelParent.cpp
@@ -7,16 +7,19 @@
 
 #include "mozilla/net/FTPChannelParent.h"
 #include "nsFTPChannel.h"
 #include "nsNetUtil.h"
 #include "nsISupportsPriority.h"
 #include "nsIRedirectChannelRegistrar.h"
 #include "nsFtpProtocolHandler.h"
 #include "mozilla/LoadContext.h"
+#include "mozilla/ipc/InputStreamUtils.h"
+
+using namespace mozilla::ipc;
 
 #undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace net {
 
 FTPChannelParent::FTPChannelParent()
@@ -53,17 +56,17 @@ NS_IMPL_ISUPPORTS4(FTPChannelParent,
 //-----------------------------------------------------------------------------
 // FTPChannelParent::PFTPChannelParent
 //-----------------------------------------------------------------------------
 
 bool
 FTPChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
                                 const uint64_t& aStartPos,
                                 const nsCString& aEntityID,
-                                const IPC::InputStream& aUploadStream,
+                                const OptionalInputStreamParams& aUploadStream,
                                 const IPC::SerializedLoadContext& loadContext)
 {
   nsCOMPtr<nsIURI> uri(aURI);
 
 #ifdef DEBUG
   nsCString uriSpec;
   uri->GetSpec(uriSpec);
   LOG(("FTPChannelParent RecvAsyncOpen [this=%x uri=%s]\n",
@@ -77,17 +80,17 @@ FTPChannelParent::RecvAsyncOpen(const IP
 
   nsCOMPtr<nsIChannel> chan;
   rv = NS_NewChannel(getter_AddRefs(chan), uri, ios);
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
 
   mChannel = static_cast<nsFtpChannel*>(chan.get());
   
-  nsCOMPtr<nsIInputStream> upload(aUploadStream);
+  nsCOMPtr<nsIInputStream> upload = DeserializeInputStream(aUploadStream);
   if (upload) {
     // contentType and contentLength are ignored
     rv = mChannel->SetUploadStream(upload, EmptyCString(), 0);
     if (NS_FAILED(rv))
       return SendFailedAsyncOpen(rv);
   }
 
   rv = mChannel->ResumeAt(aStartPos, aEntityID);
--- a/netwerk/protocol/ftp/FTPChannelParent.h
+++ b/netwerk/protocol/ftp/FTPChannelParent.h
@@ -32,17 +32,17 @@ public:
 
   FTPChannelParent();
   virtual ~FTPChannelParent();
 
 protected:
   virtual bool RecvAsyncOpen(const IPC::URI& uri,
                              const uint64_t& startPos,
                              const nsCString& entityID,
-                             const IPC::InputStream& uploadStream,
+                             const OptionalInputStreamParams& uploadStream,
                              const IPC::SerializedLoadContext& loadContext) MOZ_OVERRIDE;
   virtual bool RecvConnectChannel(const uint32_t& channelId) MOZ_OVERRIDE;
   virtual bool RecvCancel(const nsresult& status) MOZ_OVERRIDE;
   virtual bool RecvSuspend() MOZ_OVERRIDE;
   virtual bool RecvResume() MOZ_OVERRIDE;
 
   virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
--- a/netwerk/protocol/ftp/PFTPChannel.ipdl
+++ b/netwerk/protocol/ftp/PFTPChannel.ipdl
@@ -3,36 +3,36 @@
 
 /* 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 protocol PNecko;
 
 include "mozilla/net/NeckoMessageUtils.h";
+include IPCSerializableParams;
 
 using IPC::URI;
-using IPC::InputStream;
 using IPC::SerializedLoadContext;
 using PRTime;
 
 namespace mozilla {
 namespace net {
 
 async protocol PFTPChannel
 {
   manager PNecko;
 
 parent:
   __delete__();
 
   AsyncOpen(URI uri,
             uint64_t startPos,
             nsCString entityID,
-            InputStream uploadStream,
+            OptionalInputStreamParams uploadStream,
             SerializedLoadContext loadContext);
 
   ConnectChannel(uint32_t channelId);
   Cancel(nsresult status);
   Suspend();
   Resume();
 
 child:
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -11,16 +11,19 @@
 #include "mozilla/net/HttpChannelChild.h"
 
 #include "nsStringStream.h"
 #include "nsHttpHandler.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsSerializationHelper.h"
 #include "base/compiler_specific.h"
+#include "mozilla/ipc/InputStreamUtils.h"
+
+using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 //-----------------------------------------------------------------------------
 // HttpChannelChild
 //-----------------------------------------------------------------------------
 
@@ -1029,22 +1032,24 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
   }
 
   // The socket transport in the chrome process now holds a logical ref to us
   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
   AddIPDLReference();
 
   gNeckoChild->SendPHttpChannelConstructor(this, tabChild);
 
+  OptionalInputStreamParams uploadStream;
+  SerializeInputStream(mUploadStream, uploadStream);
+
   SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI),
                 IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags,
-                mClientSetRequestHeaders, mRequestHead.Method(),
-                IPC::InputStream(mUploadStream), mUploadStreamHasHeaders,
-                mPriority, mRedirectionLimit, mAllowPipelining,
-                mForceAllowThirdPartyCookie, mSendResumeAt,
+                mClientSetRequestHeaders, mRequestHead.Method(), uploadStream,
+                mUploadStreamHasHeaders, mPriority, mRedirectionLimit,
+                mAllowPipelining, mForceAllowThirdPartyCookie, mSendResumeAt,
                 mStartPos, mEntityID, mChooseApplicationCache,
                 appCacheClientId, mAllowSpdy, IPC::SerializedLoadContext(this));
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelChild::nsIHttpChannel
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -19,16 +19,19 @@
 #include "nsSerializationHelper.h"
 #include "nsISerializable.h"
 #include "nsIAssociatedContentSecurity.h"
 #include "nsIApplicationCacheService.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsIRedirectChannelRegistrar.h"
 #include "mozilla/LoadContext.h"
 #include "prinit.h"
+#include "mozilla/ipc/InputStreamUtils.h"
+
+using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 HttpChannelParent::HttpChannelParent(PBrowserParent* iframeEmbedding)
   : mIPCClosed(false)
   , mStoredStatus(NS_OK)
   , mStoredProgress(0)
@@ -103,17 +106,17 @@ HttpChannelParent::GetInterface(const ns
 bool 
 HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
                                  const IPC::URI&            aOriginalURI,
                                  const IPC::URI&            aDocURI,
                                  const IPC::URI&            aReferrerURI,
                                  const uint32_t&            loadFlags,
                                  const RequestHeaderTuples& requestHeaders,
                                  const nsHttpAtom&          requestMethod,
-                                 const IPC::InputStream&    uploadStream,
+                                 const OptionalInputStreamParams& uploadStream,
                                  const bool&              uploadStreamHasHeaders,
                                  const uint16_t&            priority,
                                  const uint8_t&             redirectionLimit,
                                  const bool&              allowPipelining,
                                  const bool&              forceAllowThirdPartyCookie,
                                  const bool&                doResumeAt,
                                  const uint64_t&            startPos,
                                  const nsCString&           entityID,
@@ -167,17 +170,17 @@ HttpChannelParent::RecvAsyncOpen(const I
 
   nsRefPtr<HttpChannelParentListener> channelListener =
       new HttpChannelParentListener(this);
 
   httpChan->SetNotificationCallbacks(channelListener);
 
   httpChan->SetRequestMethod(nsDependentCString(requestMethod.get()));
 
-  nsCOMPtr<nsIInputStream> stream(uploadStream);
+  nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(uploadStream);
   if (stream) {
     httpChan->InternalSetUploadStream(stream);
     httpChan->SetUploadStreamHasHeaders(uploadStreamHasHeaders);
   }
 
   if (priority != nsISupportsPriority::PRIORITY_NORMAL)
     httpChan->SetPriority(priority);
   httpChan->SetRedirectionLimit(redirectionLimit);
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -47,17 +47,17 @@ public:
 protected:
   virtual bool RecvAsyncOpen(const IPC::URI&            uri,
                              const IPC::URI&            originalUri,
                              const IPC::URI&            docUri,
                              const IPC::URI&            referrerUri,
                              const uint32_t&            loadFlags,
                              const RequestHeaderTuples& requestHeaders,
                              const nsHttpAtom&          requestMethod,
-                             const IPC::InputStream&    uploadStream,
+                             const OptionalInputStreamParams& uploadStream,
                              const bool&              uploadStreamHasHeaders,
                              const uint16_t&            priority,
                              const uint8_t&             redirectionLimit,
                              const bool&              allowPipelining,
                              const bool&              forceAllowThirdPartyCookie,
                              const bool&                doResumeAt,
                              const uint64_t&            startPos,
                              const nsCString&           entityID,
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -6,22 +6,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PNecko;
 
 include "mozilla/net/PHttpChannelParams.h";
 include "mozilla/net/NeckoMessageUtils.h";
 include "prio.h";
 
+include IPCSerializableParams;
+
 using RequestHeaderTuples;
 using nsHttpHeaderArray;
 using nsHttpResponseHead;
 using nsHttpAtom;
 using IPC::URI;
-using IPC::InputStream;
 using IPC::SerializedLoadContext;
 using PRNetAddr;
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 protocol PHttpChannel
@@ -34,17 +35,17 @@ parent:
             // set originalURI != uri (about:credits?); also not clear if
             // chrome channel would ever need to know.  Get rid of next arg?
             URI                 original,
             URI                 doc,
             URI                 referrer,
             uint32_t            loadFlags,
             RequestHeaderTuples requestHeaders,
             nsHttpAtom          requestMethod,
-            InputStream         uploadStream,
+            OptionalInputStreamParams uploadStream,
             bool                uploadStreamHasHeaders,
             uint16_t            priority,
             uint8_t             redirectionLimit,
             bool                allowPipelining,
             bool                forceAllowThirdPartyCookie,
             bool                resumeAt,
             uint64_t            startPos,
             nsCString           entityID,
--- a/netwerk/protocol/websocket/PWebSocket.ipdl
+++ b/netwerk/protocol/websocket/PWebSocket.ipdl
@@ -4,19 +4,19 @@
 /* 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 protocol PNecko;
 include protocol PBrowser;
 
 include "mozilla/net/NeckoMessageUtils.h";
+include IPCSerializableParams;
 
 using IPC::URI;
-using IPC::InputStream;
 using IPC::SerializedLoadContext;
 
 namespace mozilla {
 namespace net {
 
 async protocol PWebSocket
 {
   manager PNecko;
@@ -26,17 +26,17 @@ parent:
   AsyncOpen(URI aURI,
             nsCString aOrigin,
             nsCString aProtocol,
             bool aSecure,
             SerializedLoadContext loadContext);
   Close(uint16_t code, nsCString reason);
   SendMsg(nsCString aMsg);
   SendBinaryMsg(nsCString aMsg);
-  SendBinaryStream(InputStream aStream, uint32_t aLength);
+  SendBinaryStream(InputStreamParams aStream, uint32_t aLength);
 
   DeleteSelf();
 
 child:
   // Forwarded notifications corresponding to the nsIWebSocketListener interface
   OnStart(nsCString aProtocol, nsCString aExtensions);
   OnStop(nsresult aStatusCode);
   OnMessageAvailable(nsCString aMsg);
--- a/netwerk/protocol/websocket/WebSocketChannelChild.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelChild.cpp
@@ -6,16 +6,19 @@
 
 #include "WebSocketLog.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "WebSocketChannelChild.h"
 #include "nsITabChild.h"
 #include "nsILoadContext.h"
 #include "nsNetUtil.h"
+#include "mozilla/ipc/InputStreamUtils.h"
+
+using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ADDREF(WebSocketChannelChild)
 
 NS_IMETHODIMP_(nsrefcnt) WebSocketChannelChild::Release()
 {
@@ -376,17 +379,20 @@ WebSocketChannelChild::SendBinaryMsg(con
 }
 
 NS_IMETHODIMP
 WebSocketChannelChild::SendBinaryStream(nsIInputStream *aStream,
                                         uint32_t aLength)
 {
   LOG(("WebSocketChannelChild::SendBinaryStream() %p\n", this));
 
-  if (!mIPCOpen || !SendSendBinaryStream(IPC::InputStream(aStream), aLength))
+  OptionalInputStreamParams stream;
+  SerializeInputStream(aStream, stream);
+
+  if (!mIPCOpen || !SendSendBinaryStream(stream, aLength))
     return NS_ERROR_UNEXPECTED;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebSocketChannelChild::GetSecurityInfo(nsISupports **aSecurityInfo)
 {
   LOG(("WebSocketChannelChild::GetSecurityInfo() %p\n", this));
--- a/netwerk/protocol/websocket/WebSocketChannelParent.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.cpp
@@ -3,16 +3,19 @@
 /* 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 "WebSocketLog.h"
 #include "WebSocketChannelParent.h"
 #include "nsIAuthPromptProvider.h"
 #include "mozilla/LoadContext.h"
+#include "mozilla/ipc/InputStreamUtils.h"
+
+using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_THREADSAFE_ISUPPORTS2(WebSocketChannelParent,
                               nsIWebSocketListener,
                               nsIInterfaceRequestor)
 
@@ -109,22 +112,26 @@ WebSocketChannelParent::RecvSendBinaryMs
   if (mChannel) {
     nsresult rv = mChannel->SendBinaryMsg(aMsg);
     NS_ENSURE_SUCCESS(rv, true);
   }
   return true;
 }
 
 bool
-WebSocketChannelParent::RecvSendBinaryStream(const InputStream& aStream,
+WebSocketChannelParent::RecvSendBinaryStream(const InputStreamParams& aStream,
                                              const uint32_t& aLength)
 {
   LOG(("WebSocketChannelParent::RecvSendBinaryStream() %p\n", this));
   if (mChannel) {
-    nsresult rv = mChannel->SendBinaryStream(aStream, aLength);
+    nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aStream);
+    if (!stream) {
+      return false;
+    }
+    nsresult rv = mChannel->SendBinaryStream(stream, aLength);
     NS_ENSURE_SUCCESS(rv, true);
   }
   return true;
 }
 
 //-----------------------------------------------------------------------------
 // WebSocketChannelParent::nsIRequestObserver
 //-----------------------------------------------------------------------------
--- a/netwerk/protocol/websocket/WebSocketChannelParent.h
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.h
@@ -34,17 +34,17 @@ class WebSocketChannelParent : public PW
   bool RecvAsyncOpen(const IPC::URI& aURI,
                      const nsCString& aOrigin,
                      const nsCString& aProtocol,
                      const bool& aSecure,
                      const IPC::SerializedLoadContext& loadContext);
   bool RecvClose(const uint16_t & code, const nsCString & reason);
   bool RecvSendMsg(const nsCString& aMsg);
   bool RecvSendBinaryMsg(const nsCString& aMsg);
-  bool RecvSendBinaryStream(const InputStream& aStream,
+  bool RecvSendBinaryStream(const InputStreamParams& aStream,
                             const uint32_t& aLength);
   bool RecvDeleteSelf();
 
   void ActorDestroy(ActorDestroyReason why);
 
   nsCOMPtr<nsIAuthPromptProvider> mAuthProvider;
   nsCOMPtr<nsIWebSocketChannel> mChannel;
   nsCOMPtr<nsILoadContext> mLoadContext;
--- a/xpcom/io/nsMultiplexInputStream.cpp
+++ b/xpcom/io/nsMultiplexInputStream.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * The multiplex stream concatenates a list of input streams into a single
  * stream.
  */
 
 #include "IPC/IPCMessageUtils.h"
-#include "mozilla/net/NeckoMessageUtils.h"
 #include "mozilla/Attributes.h"
 
 #include "nsMultiplexInputStream.h"
 #include "nsIMultiplexInputStream.h"
 #include "nsISeekableStream.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsIIPCSerializableObsolete.h"
@@ -22,27 +21,25 @@
 #include "nsIIPCSerializableInputStream.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/IPCSerializableParams.h"
 
 using namespace mozilla::ipc;
 
 class nsMultiplexInputStream MOZ_FINAL : public nsIMultiplexInputStream,
                                          public nsISeekableStream,
-                                         public nsIIPCSerializableObsolete,
                                          public nsIIPCSerializableInputStream
 {
 public:
     nsMultiplexInputStream();
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIINPUTSTREAM
     NS_DECL_NSIMULTIPLEXINPUTSTREAM
     NS_DECL_NSISEEKABLESTREAM
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
     NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
 
 private:
     ~nsMultiplexInputStream() {}
 
     struct ReadSegmentsState {
         nsIInputStream* mThisStream;
         uint32_t mOffset;
@@ -62,21 +59,20 @@ private:
 };
 
 NS_IMPL_THREADSAFE_ADDREF(nsMultiplexInputStream)
 NS_IMPL_THREADSAFE_RELEASE(nsMultiplexInputStream)
 
 NS_IMPL_CLASSINFO(nsMultiplexInputStream, NULL, nsIClassInfo::THREADSAFE,
                   NS_MULTIPLEXINPUTSTREAM_CID)
 
-NS_IMPL_QUERY_INTERFACE5_CI(nsMultiplexInputStream,
+NS_IMPL_QUERY_INTERFACE4_CI(nsMultiplexInputStream,
                             nsIMultiplexInputStream,
                             nsIInputStream,
                             nsISeekableStream,
-                            nsIIPCSerializableObsolete,
                             nsIIPCSerializableInputStream)
 NS_IMPL_CI_INTERFACE_GETTER3(nsMultiplexInputStream,
                              nsIMultiplexInputStream,
                              nsIInputStream,
                              nsISeekableStream)
 
 nsMultiplexInputStream::nsMultiplexInputStream()
     : mCurrentStream(0),
@@ -591,62 +587,16 @@ nsMultiplexInputStreamConstructor(nsISup
 
     NS_ADDREF(inst);
     nsresult rv = inst->QueryInterface(iid, result);
     NS_RELEASE(inst);
 
     return rv;
 }
 
-bool
-nsMultiplexInputStream::Read(const IPC::Message *aMsg, void **aIter)
-{
-    using IPC::ReadParam;
-
-    uint32_t count;
-    if (!ReadParam(aMsg, aIter, &count))
-        return false;
-
-    for (uint32_t i = 0; i < count; i++) {
-        IPC::InputStream inputStream;
-        if (!ReadParam(aMsg, aIter, &inputStream))
-            return false;
-
-        nsCOMPtr<nsIInputStream> stream(inputStream);
-        nsresult rv = AppendStream(stream);
-        if (NS_FAILED(rv))
-            return false;
-    }
-
-    if (!ReadParam(aMsg, aIter, &mCurrentStream) ||
-        !ReadParam(aMsg, aIter, &mStartedReadingCurrent) ||
-        !ReadParam(aMsg, aIter, &mStatus))
-        return false;
-
-    return true;
-}
-
-void
-nsMultiplexInputStream::Write(IPC::Message *aMsg)
-{
-    using IPC::WriteParam;
-
-    uint32_t count = mStreams.Length();
-    WriteParam(aMsg, count);
-
-    for (uint32_t i = 0; i < count; i++) {
-        IPC::InputStream inputStream(mStreams[i]);
-        WriteParam(aMsg, inputStream);
-    }
-
-    WriteParam(aMsg, mCurrentStream);
-    WriteParam(aMsg, mStartedReadingCurrent);
-    WriteParam(aMsg, mStatus);
-}
-
 void
 nsMultiplexInputStream::Serialize(InputStreamParams& aParams)
 {
     MultiplexInputStreamParams params;
 
     uint32_t streamCount = mStreams.Length();
 
     if (streamCount) {
@@ -707,9 +657,9 @@ nsMultiplexInputStream::Deserialize(cons
         }
     }
 
     mCurrentStream = params.currentStream();
     mStatus = params.status();
     mStartedReadingCurrent = params.startedReadingCurrent();
 
     return true;
-}
+}
\ No newline at end of file