Bug 782649 - 'Remove old IPC::InputStream'. r=cjones+khuey.
☠☠ backed out by 9209d9af04d4 ☠ ☠
authorBen Turner <bent.mozilla@gmail.com>
Wed, 22 Aug 2012 12:19:29 -0700
changeset 105088 41a3cdf9206337399613463f3f008b24d764d1a4
parent 105087 2f60f3a4bdd703c40ac2b49d9547707bcf9614c2
child 105089 67c5213dfe2b944d0c2d019f9a47cb7da74823a2
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewerscjones
bugs782649
milestone17.0a1
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/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
@@ -17,63 +17,123 @@
 
 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(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::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/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