Backed out changeset 7a78f199e1cd (bug 975338)
authorEd Morley <emorley@mozilla.com>
Mon, 10 Mar 2014 17:57:46 +0000
changeset 172810 6a4806fc2d43c5c290696ea3b2c74379289133d1
parent 172809 c2658ef0233635d9f376e02db6bfe2525b83dc86
child 172811 13121198606eefb0c4330f49c6d4143af088506a
push id40835
push useremorley@mozilla.com
push dateMon, 10 Mar 2014 17:59:43 +0000
treeherdermozilla-inbound@5a0bd36ed103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs975338
milestone30.0a1
backs out7a78f199e1cde327d24e522a602352459935481d
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 7a78f199e1cd (bug 975338)
netwerk/base/src/nsBaseChannel.cpp
netwerk/base/src/nsBaseChannel.h
netwerk/protocol/file/nsFileChannel.cpp
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelChild.h
netwerk/protocol/ftp/FTPChannelParent.cpp
netwerk/protocol/ftp/FTPChannelParent.h
netwerk/protocol/ftp/nsFTPChannel.cpp
netwerk/protocol/ftp/nsFTPChannel.h
--- a/netwerk/base/src/nsBaseChannel.cpp
+++ b/netwerk/base/src/nsBaseChannel.cpp
@@ -151,17 +151,17 @@ nsBaseChannel::ContinueRedirect()
   ChannelDone();
 
   return NS_OK;
 }
 
 bool
 nsBaseChannel::HasContentTypeHint() const
 {
-  NS_ASSERTION(!Pending(), "HasContentTypeHint called too late");
+  NS_ASSERTION(!IsPending(), "HasContentTypeHint called too late");
   return !mContentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE);
 }
 
 nsresult
 nsBaseChannel::PushStreamConverter(const char *fromType,
                                    const char *toType,
                                    bool invalidatesContentLength,
                                    nsIStreamListener **result)
@@ -203,17 +203,17 @@ nsBaseChannel::BeginPumpingData()
 
   if (channel) {
       rv = NS_DispatchToCurrentThread(new RedirectRunnable(this, channel));
       if (NS_SUCCEEDED(rv))
           mWaitingOnAsyncRedirect = true;
       return rv;
   }
 
-  // By assigning mPump, we flag this channel as pending (see Pending).  It's
+  // By assigning mPump, we flag this channel as pending (see IsPending).  It's
   // important that the pending flag is set when we call into the stream (the
   // call to AsyncRead results in the stream's AsyncWait method being called)
   // and especially when we call into the loadgroup.  Our caller takes care to
   // release mPump if we return an error.
  
   rv = nsInputStreamPump::Create(getter_AddRefs(mPump), stream, -1, -1, 0, 0,
                                  true);
   if (NS_SUCCEEDED(rv))
@@ -307,17 +307,17 @@ nsBaseChannel::GetName(nsACString &resul
     return NS_OK;
   }
   return mURI->GetSpec(result);
 }
 
 NS_IMETHODIMP
 nsBaseChannel::IsPending(bool *result)
 {
-  *result = Pending();
+  *result = IsPending();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsBaseChannel::GetStatus(nsresult *status)
 {
   if (mPump && NS_SUCCEEDED(mStatus)) {
     mPump->GetStatus(status);
@@ -720,17 +720,17 @@ NS_IMETHODIMP
 nsBaseChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
                              nsresult status)
 {
   // If both mStatus and status are failure codes, we keep mStatus as-is since
   // that is consistent with our GetStatus and Cancel methods.
   if (NS_SUCCEEDED(mStatus))
     mStatus = status;
 
-  // Cause Pending to return false.
+  // Cause IsPending to return false.
   mPump = nullptr;
 
   if (mListener) // null in case of redirect
       mListener->OnStopRequest(this, mListenerContext, mStatus);
   ChannelDone();
 
   // No need to suspend pump in this scope since we will not be receiving
   // any more events from it.
--- a/netwerk/base/src/nsBaseChannel.h
+++ b/netwerk/base/src/nsBaseChannel.h
@@ -152,19 +152,19 @@ public:
   }
 
   // Test the load flags
   bool HasLoadFlag(uint32_t flag) {
     return (mLoadFlags & flag) != 0;
   }
 
   // This is a short-cut to calling nsIRequest::IsPending()
-  virtual bool Pending() const {
+  bool IsPending() const {
     return mPump || mWaitingOnAsyncRedirect;
- }
+  }
 
   // Helper function for querying the channel's notification callbacks.
   template <class T> void GetCallback(nsCOMPtr<T> &result) {
     GetInterface(NS_GET_TEMPLATE_IID(T), getter_AddRefs(result));
   }
 
   // Helper function for calling QueryInterface on this.
   nsQueryInterface do_QueryInterface() {
--- a/netwerk/protocol/file/nsFileChannel.cpp
+++ b/netwerk/protocol/file/nsFileChannel.cpp
@@ -426,17 +426,17 @@ nsFileChannel::GetFile(nsIFile **file)
 //-----------------------------------------------------------------------------
 // nsFileChannel::nsIUploadChannel
 
 NS_IMETHODIMP
 nsFileChannel::SetUploadStream(nsIInputStream *stream,
                                const nsACString &contentType,
                                int64_t contentLength)
 {
-  NS_ENSURE_TRUE(!Pending(), NS_ERROR_IN_PROGRESS);
+  NS_ENSURE_TRUE(!IsPending(), NS_ERROR_IN_PROGRESS);
 
   if ((mUploadStream = stream)) {
     mUploadLength = contentLength;
     if (mUploadLength < 0) {
       // Make sure we know how much data we are uploading.
       uint64_t avail;
       nsresult rv = mUploadStream->Available(&avail);
       if (NS_FAILED(rv))
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et tw=80 : */
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/net/NeckoChild.h"
-#include "mozilla/net/ChannelDiverterChild.h"
 #include "mozilla/net/FTPChannelChild.h"
 #include "mozilla/dom/TabChild.h"
 #include "nsFtpProtocolHandler.h"
 #include "nsITabChild.h"
 #include "nsStringStream.h"
 #include "nsNetUtil.h"
 #include "base/compiler_specific.h"
 #include "mozilla/ipc/InputStreamUtils.h"
@@ -29,19 +28,16 @@ namespace net {
 FTPChannelChild::FTPChannelChild(nsIURI* uri)
 : mIPCOpen(false)
 , mCanceled(false)
 , mSuspendCount(0)
 , mIsPending(false)
 , mWasOpened(false)
 , mLastModifiedTime(0)
 , mStartPos(0)
-, mDivertingToParent(false)
-, mFlushedForDiversion(false)
-, mSuspendSent(false)
 {
   LOG(("Creating FTPChannelChild @%x\n", this));
   // grab a reference to the handler to ensure that it doesn't go away.
   NS_ADDREF(gFtpHandler);
   SetURI(uri);
   mEventQ = new ChannelEventQueue(static_cast<nsIFTPChannel*>(this));
 }
 
@@ -66,24 +62,23 @@ FTPChannelChild::ReleaseIPDLReference()
   mIPCOpen = false;
   Release();
 }
 
 //-----------------------------------------------------------------------------
 // FTPChannelChild::nsISupports
 //-----------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS_INHERITED6(FTPChannelChild,
+NS_IMPL_ISUPPORTS_INHERITED5(FTPChannelChild,
                              nsBaseChannel,
                              nsIFTPChannel,
                              nsIUploadChannel,
                              nsIResumableChannel,
                              nsIProxiedChannel,
-                             nsIChildChannel,
-                             nsIDivertableChannel)
+                             nsIChildChannel)
 
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 FTPChannelChild::GetLastModifiedTime(PRTime* lastModifiedTime)
 {
   *lastModifiedTime = mLastModifiedTime;
   return NS_OK;
@@ -242,23 +237,16 @@ class FTPStartRequestEvent : public Chan
 
 bool
 FTPChannelChild::RecvOnStartRequest(const int64_t& aContentLength,
                                     const nsCString& aContentType,
                                     const PRTime& aLastModified,
                                     const nsCString& aEntityID,
                                     const URIParams& aURI)
 {
-  // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
-  // stage, as they are set in the listener's OnStartRequest.
-  MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
-    "mFlushedForDiversion should be unset before OnStartRequest!");
-  MOZ_RELEASE_ASSERT(!mDivertingToParent,
-    "mDivertingToParent should be unset before OnStartRequest!");
-
   if (mEventQ->ShouldEnqueue()) {
     mEventQ->Enqueue(new FTPStartRequestEvent(this, aContentLength, aContentType,
                                               aLastModified, aEntityID, aURI));
   } else {
     DoOnStartRequest(aContentLength, aContentType, aLastModified,
                      aEntityID, aURI);
   }
   return true;
@@ -268,45 +256,30 @@ void
 FTPChannelChild::DoOnStartRequest(const int64_t& aContentLength,
                                   const nsCString& aContentType,
                                   const PRTime& aLastModified,
                                   const nsCString& aEntityID,
                                   const URIParams& aURI)
 {
   LOG(("FTPChannelChild::RecvOnStartRequest [this=%p]\n", this));
 
-  // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
-  // stage, as they are set in the listener's OnStartRequest.
-  MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
-    "mFlushedForDiversion should be unset before OnStartRequest!");
-  MOZ_RELEASE_ASSERT(!mDivertingToParent,
-    "mDivertingToParent should be unset before OnStartRequest!");
-
   mContentLength = aContentLength;
   SetContentType(aContentType);
   mLastModifiedTime = aLastModified;
   mEntityID = aEntityID;
 
   nsCString spec;
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   uri->GetSpec(spec);
   nsBaseChannel::URI()->SetSpec(spec);
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
   nsresult rv = mListener->OnStartRequest(this, mListenerContext);
   if (NS_FAILED(rv))
     Cancel(rv);
-
-  if (mDivertingToParent) {
-    mListener = nullptr;
-    mListenerContext = nullptr;
-    if (mLoadGroup) {
-      mLoadGroup->RemoveRequest(this, nullptr, mStatus);
-    }
-  }
 }
 
 class FTPDataAvailableEvent : public ChannelEvent
 {
  public:
   FTPDataAvailableEvent(FTPChannelChild* aChild, const nsCString& aData,
                         const uint64_t& aOffset, const uint32_t& aCount)
   : mChild(aChild), mData(aData), mOffset(aOffset), mCount(aCount) {}
@@ -318,45 +291,31 @@ class FTPDataAvailableEvent : public Cha
   uint32_t mCount;
 };
 
 bool
 FTPChannelChild::RecvOnDataAvailable(const nsCString& data,
                                      const uint64_t& offset,
                                      const uint32_t& count)
 {
-  MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
-                     "Should not be receiving any more callbacks from parent!");
-
   if (mEventQ->ShouldEnqueue()) {
     mEventQ->Enqueue(new FTPDataAvailableEvent(this, data, offset, count));
   } else {
-    MOZ_RELEASE_ASSERT(!mDivertingToParent,
-                       "ShouldEnqueue when diverting to parent!");
-
     DoOnDataAvailable(data, offset, count);
   }
   return true;
 }
 
 void
 FTPChannelChild::DoOnDataAvailable(const nsCString& data,
                                    const uint64_t& offset,
                                    const uint32_t& count)
 {
   LOG(("FTPChannelChild::RecvOnDataAvailable [this=%p]\n", this));
 
-  if (mDivertingToParent) {
-    MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
-      "Should not be processing any more callbacks from parent!");
-
-    SendDivertOnDataAvailable(data, offset, count);
-    return;
-  }
-
   if (mCanceled)
     return;
 
   // NOTE: the OnDataAvailable contract requires the client to read all the data
   // in the inputstream.  This code relies on that ('data' will go away after
   // this function).  Apparently the previous, non-e10s behavior was to actually
   // support only reading part of the data, allowing later calls to read the
   // rest.
@@ -387,41 +346,30 @@ class FTPStopRequestEvent : public Chann
  private:
   FTPChannelChild* mChild;
   nsresult mStatusCode;
 };
 
 bool
 FTPChannelChild::RecvOnStopRequest(const nsresult& statusCode)
 {
-  MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
-    "Should not be receiving any more callbacks from parent!");
-
   if (mEventQ->ShouldEnqueue()) {
     mEventQ->Enqueue(new FTPStopRequestEvent(this, statusCode));
   } else {
     DoOnStopRequest(statusCode);
   }
   return true;
 }
 
 void
 FTPChannelChild::DoOnStopRequest(const nsresult& statusCode)
 {
   LOG(("FTPChannelChild::RecvOnStopRequest [this=%p status=%u]\n",
            this, statusCode));
 
-  if (mDivertingToParent) {
-    MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
-      "Should not be processing any more callbacks from parent!");
-
-    SendDivertOnStopRequest(statusCode);
-    return;
-  }
-
   if (!mCanceled)
     mStatus = statusCode;
 
   { // Ensure that all queued ipdl events are dispatched before
     // we initiate protocol deletion below.
     mIsPending = false;
     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
     (void)mListener->OnStopRequest(this, mListenerContext, statusCode);
@@ -477,71 +425,26 @@ FTPChannelChild::DoFailedAsyncOpen(const
 
   mListener = nullptr;
   mListenerContext = nullptr;
 
   if (mIPCOpen)
     Send__delete__(this);
 }
 
-class FTPFlushedForDiversionEvent : public ChannelEvent
-{
- public:
-  FTPFlushedForDiversionEvent(FTPChannelChild* aChild)
-  : mChild(aChild)
-  {
-    MOZ_RELEASE_ASSERT(aChild);
-  }
-
-  void Run()
-  {
-    mChild->FlushedForDiversion();
-  }
- private:
-  FTPChannelChild* mChild;
-};
-
 bool
 FTPChannelChild::RecvFlushedForDiversion()
 {
-  MOZ_ASSERT(mDivertingToParent);
-
-  if (mEventQ->ShouldEnqueue()) {
-    mEventQ->Enqueue(new FTPFlushedForDiversionEvent(this));
-  } else {
-    MOZ_CRASH();
-  }
-  return true;
-}
-
-void
-FTPChannelChild::FlushedForDiversion()
-{
-  MOZ_RELEASE_ASSERT(mDivertingToParent);
-
-  // Once this is set, it should not be unset before FTPChannelChild is taken
-  // down. After it is set, no OnStart/OnData/OnStop callbacks should be
-  // received from the parent channel, nor dequeued from the ChannelEventQueue.
-  mFlushedForDiversion = true;
-
-  SendDivertComplete();
+  return false;
 }
 
 bool
 FTPChannelChild::RecvDivertMessages()
 {
-  MOZ_RELEASE_ASSERT(mDivertingToParent);
-  MOZ_RELEASE_ASSERT(mSuspendCount > 0);
-
-  // DivertTo() has been called on parent, so we can now start sending queued
-  // IPDL messages back to parent listener.
-  if (NS_WARN_IF(NS_FAILED(Resume()))) {
-    return false;
-  }
-  return true;
+  return false;
 }
 
 class FTPDeleteSelfEvent : public ChannelEvent
 {
  public:
   FTPDeleteSelfEvent(FTPChannelChild* aChild)
   : mChild(aChild) {}
   void Run() { mChild->DoDeleteSelf(); }
@@ -579,39 +482,30 @@ FTPChannelChild::Cancel(nsresult status)
     SendCancel(status);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::Suspend()
 {
   NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
-
-  // SendSuspend only once, when suspend goes from 0 to 1.
-  // Don't SendSuspend at all if we're diverting callbacks to the parent;
-  // suspend will be called at the correct time in the parent itself.
-  if (!mSuspendCount++ && !mDivertingToParent) {
+  if (!mSuspendCount++) {
     SendSuspend();
-    mSuspendSent = true;
   }
   mEventQ->Suspend();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::Resume()
 {
   NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
 
-  // SendResume only once, when suspend count drops to 0.
-  // Don't SendResume at all if we're diverting callbacks to the parent (unless
-  // suspend was sent earlier); otherwise, resume will be called at the correct
-  // time in the parent itself.
-  if (!--mSuspendCount && (!mDivertingToParent || mSuspendSent)) {
+  if (!--mSuspendCount) {
     SendResume();
   }
   mEventQ->Resume();
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
@@ -665,44 +559,11 @@ FTPChannelChild::CompleteRedirectSetup(n
     mLoadGroup->AddRequest(this, nullptr);
 
   // We already have an open IPDL connection to the parent. If on-modify-request
   // listeners or load group observers canceled us, let the parent handle it
   // and send it back to us naturally.
   return NS_OK;
 }
 
-//-----------------------------------------------------------------------------
-// FTPChannelChild::nsIDivertableChannel
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-FTPChannelChild::DivertToParent(ChannelDiverterChild **aChild)
-{
-  MOZ_RELEASE_ASSERT(aChild);
-  MOZ_RELEASE_ASSERT(gNeckoChild);
-  MOZ_RELEASE_ASSERT(!mDivertingToParent);
-
-  // We must fail DivertToParent() if there's no parent end of the channel (and
-  // won't be!) due to early failure.
-  if (NS_FAILED(mStatus) && !mIPCOpen) {
-    return mStatus;
-  }
-
-  nsresult rv = Suspend();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // Once this is set, it should not be unset before the child is taken down.
-  mDivertingToParent = true;
-
-  PChannelDiverterChild* diverter =
-    gNeckoChild->SendPChannelDiverterConstructor(this);
-  MOZ_RELEASE_ASSERT(diverter);
-
-  *aChild = static_cast<ChannelDiverterChild*>(diverter);
-
-  return NS_OK;
-}
-
 } // namespace net
 } // namespace mozilla
 
--- a/netwerk/protocol/ftp/FTPChannelChild.h
+++ b/netwerk/protocol/ftp/FTPChannelChild.h
@@ -11,17 +11,16 @@
 #include "mozilla/net/PFTPChannelChild.h"
 #include "mozilla/net/ChannelEventQueue.h"
 #include "nsBaseChannel.h"
 #include "nsIFTPChannel.h"
 #include "nsIUploadChannel.h"
 #include "nsIProxiedChannel.h"
 #include "nsIResumableChannel.h"
 #include "nsIChildChannel.h"
-#include "nsIDivertableChannel.h"
 
 #include "nsIStreamListener.h"
 #include "PrivateBrowsingChannel.h"
 
 namespace mozilla {
 namespace net {
 
 // This class inherits logic from nsBaseChannel that is not needed for an
@@ -31,28 +30,26 @@ namespace net {
 
 class FTPChannelChild : public PFTPChannelChild
                       , public nsBaseChannel
                       , public nsIFTPChannel
                       , public nsIUploadChannel
                       , public nsIResumableChannel
                       , public nsIProxiedChannel
                       , public nsIChildChannel
-                      , public nsIDivertableChannel
 {
 public:
   typedef ::nsIStreamListener nsIStreamListener;
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIFTPCHANNEL
   NS_DECL_NSIUPLOADCHANNEL
   NS_DECL_NSIRESUMABLECHANNEL
   NS_DECL_NSIPROXIEDCHANNEL
   NS_DECL_NSICHILDCHANNEL
-  NS_DECL_NSIDIVERTABLECHANNEL
 
   NS_IMETHOD Cancel(nsresult status);
   NS_IMETHOD Suspend();
   NS_IMETHOD Resume();
 
   FTPChannelChild(nsIURI* uri);
   virtual ~FTPChannelChild();
 
@@ -66,18 +63,16 @@ public:
   NS_IMETHOD IsPending(bool* result);
 
   nsresult OpenContentStream(bool async,
                              nsIInputStream** stream,
                              nsIChannel** channel) MOZ_OVERRIDE;
 
   bool IsSuspended();
 
-  void FlushedForDiversion();
-
 protected:
   bool RecvOnStartRequest(const int64_t& aContentLength,
                           const nsCString& aContentType,
                           const PRTime& aLastModified,
                           const nsCString& aEntityID,
                           const URIParams& aURI) MOZ_OVERRIDE;
   bool RecvOnDataAvailable(const nsCString& data,
                            const uint64_t& offset,
@@ -114,25 +109,16 @@ private:
   bool mCanceled;
   uint32_t mSuspendCount;
   bool mIsPending;
   bool mWasOpened;
   
   PRTime mLastModifiedTime;
   uint64_t mStartPos;
   nsCString mEntityID;
-
-  // Once set, OnData and possibly OnStop will be diverted to the parent.
-  bool mDivertingToParent;
-  // Once set, no OnStart/OnData/OnStop callbacks should be received from the
-  // parent channel, nor dequeued from the ChannelEventQueue.
-  bool mFlushedForDiversion;
-  // Set if SendSuspend is called. Determines if SendResume is needed when
-  // diverting callbacks to parent.
-  bool mSuspendSent;
 };
 
 inline bool
 FTPChannelChild::IsSuspended()
 {
   return mSuspendCount != 0;
 }
 
--- a/netwerk/protocol/ftp/FTPChannelParent.cpp
+++ b/netwerk/protocol/ftp/FTPChannelParent.cpp
@@ -6,35 +6,30 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/net/FTPChannelParent.h"
 #include "nsFTPChannel.h"
 #include "nsNetUtil.h"
 #include "nsFtpProtocolHandler.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/URIUtils.h"
-#include "mozilla/unused.h"
 #include "SerializedLoadContext.h"
 
 using namespace mozilla::ipc;
 
 #undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace net {
 
 FTPChannelParent::FTPChannelParent(nsILoadContext* aLoadContext, PBOverrideStatus aOverrideStatus)
   : mIPCClosed(false)
   , mLoadContext(aLoadContext)
   , mPBOverride(aOverrideStatus)
-  , mStatus(NS_OK)
-  , mDivertingFromChild(false)
-  , mDivertedOnStartRequest(false)
-  , mSuspendedForDiversion(false)
 {
   nsIProtocolHandler* handler;
   CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &handler);
   NS_ASSERTION(handler, "no ftp handler");
 }
 
 FTPChannelParent::~FTPChannelParent()
 {
@@ -184,107 +179,40 @@ FTPChannelParent::RecvResume()
   return true;
 }
 
 bool
 FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
                                             const uint64_t& offset,
                                             const uint32_t& count)
 {
-  if (NS_WARN_IF(!mDivertingFromChild)) {
-    MOZ_ASSERT(mDivertingFromChild,
-               "Cannot RecvDivertOnDataAvailable if diverting is not set!");
-    FailDiversion(NS_ERROR_UNEXPECTED);
-    return false;
-  }
-
-  // Drop OnDataAvailables if the parent was canceled already.
-  if (NS_FAILED(mStatus)) {
-    return true;
-  }
-
-  nsCOMPtr<nsIInputStream> stringStream;
-  nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(),
-                                      count, NS_ASSIGNMENT_DEPEND);
-  if (NS_FAILED(rv)) {
-    if (mChannel) {
-      mChannel->Cancel(rv);
-    }
-    mStatus = rv;
-    return true;
-  }
-
-  rv = OnDataAvailable(mChannel, nullptr, stringStream, offset, count);
-
-  stringStream->Close();
-  if (NS_FAILED(rv)) {
-    if (mChannel) {
-      mChannel->Cancel(rv);
-    }
-    mStatus = rv;
-  }
-  return true;
+  return false;
 }
 
 bool
 FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
 {
-  if (NS_WARN_IF(!mDivertingFromChild)) {
-    MOZ_ASSERT(mDivertingFromChild,
-               "Cannot RecvDivertOnStopRequest if diverting is not set!");
-    FailDiversion(NS_ERROR_UNEXPECTED);
-    return false;
-  }
-
-  // Honor the channel's status even if the underlying transaction completed.
-  nsresult status = NS_FAILED(mStatus) ? mStatus : statusCode;
-
-  // Reset fake pending status in case OnStopRequest has already been called.
-  if (mChannel) {
-    mChannel->ForcePending(false);
-  }
-
-  OnStopRequest(mChannel, nullptr, status);
-  return true;
+  return false;
 }
 
 bool
 FTPChannelParent::RecvDivertComplete()
 {
-  if (NS_WARN_IF(!mDivertingFromChild)) {
-    MOZ_ASSERT(mDivertingFromChild,
-               "Cannot RecvDivertComplete if diverting is not set!");
-    FailDiversion(NS_ERROR_UNEXPECTED);
-    return false;
-  }
-
-  nsresult rv = ResumeForDiversion();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    FailDiversion(NS_ERROR_UNEXPECTED);
-    return false;
-  }
-
-  return true;
+  return false;
 }
 
 //-----------------------------------------------------------------------------
 // FTPChannelParent::nsIRequestObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 FTPChannelParent::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
 {
   LOG(("FTPChannelParent::OnStartRequest [this=%p]\n", this));
 
-  if (mDivertingFromChild) {
-    MOZ_RELEASE_ASSERT(mDivertToListener,
-                       "Cannot divert if listener is unset!");
-    return mDivertToListener->OnStartRequest(aRequest, aContext);
-  }
-
   nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest);
   MOZ_ASSERT(chan);
   NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
 
   int64_t contentLength;
   chan->GetContentLength(&contentLength);
   nsCString contentType;
   chan->GetContentType(contentType);
@@ -322,22 +250,16 @@ FTPChannelParent::OnStartRequest(nsIRequ
 NS_IMETHODIMP
 FTPChannelParent::OnStopRequest(nsIRequest* aRequest,
                                 nsISupports* aContext,
                                 nsresult aStatusCode)
 {
   LOG(("FTPChannelParent::OnStopRequest: [this=%p status=%ul]\n",
        this, aStatusCode));
 
-  if (mDivertingFromChild) {
-    MOZ_RELEASE_ASSERT(mDivertToListener,
-                       "Cannot divert if listener is unset!");
-    return mDivertToListener->OnStopRequest(aRequest, aContext, aStatusCode);
-  }
-
   if (mIPCClosed || !SendOnStopRequest(aStatusCode)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
@@ -347,24 +269,17 @@ FTPChannelParent::OnStopRequest(nsIReque
 NS_IMETHODIMP
 FTPChannelParent::OnDataAvailable(nsIRequest* aRequest,
                                   nsISupports* aContext,
                                   nsIInputStream* aInputStream,
                                   uint64_t aOffset,
                                   uint32_t aCount)
 {
   LOG(("FTPChannelParent::OnDataAvailable [this=%p]\n", this));
-
-  if (mDivertingFromChild) {
-    MOZ_RELEASE_ASSERT(mDivertToListener,
-                       "Cannot divert if listener is unset!");
-    return mDivertToListener->OnDataAvailable(aRequest, aContext, aInputStream,
-                                              aOffset, aCount);
-  }
-
+  
   nsCString data;
   nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
   if (NS_FAILED(rv))
     return rv;
 
   if (mIPCClosed || !SendOnDataAvailable(data, aOffset, aCount))
     return NS_ERROR_UNEXPECTED;
 
@@ -396,201 +311,12 @@ FTPChannelParent::GetInterface(const nsI
     NS_ADDREF(mLoadContext);
     *result = static_cast<nsILoadContext*>(mLoadContext);
     return NS_OK;
   }
 
   return QueryInterface(uuid, result);
 }
 
-//-----------------------------------------------------------------------------
-// FTPChannelParent::ADivertableParentChannel
-//-----------------------------------------------------------------------------
-nsresult
-FTPChannelParent::SuspendForDiversion()
-{
-  MOZ_ASSERT(mChannel);
-  if (NS_WARN_IF(mDivertingFromChild)) {
-    MOZ_ASSERT(!mDivertingFromChild, "Already suspended for diversion!");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  // Try suspending the channel. Allow it to fail, since OnStopRequest may have
-  // been called and thus the channel may not be pending.
-  DebugOnly<nsresult> rv = mChannel->Suspend();
-  MOZ_ASSERT(NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_AVAILABLE);
-  mSuspendedForDiversion = NS_SUCCEEDED(rv);
-
-  // Once this is set, no more OnStart/OnData/OnStop callbacks should be sent
-  // to the child.
-  mDivertingFromChild = true;
-
-  return NS_OK;
-}
-
-/* private, supporting function for ADivertableParentChannel */
-nsresult
-FTPChannelParent::ResumeForDiversion()
-{
-  MOZ_ASSERT(mChannel);
-  MOZ_ASSERT(mDivertToListener);
-  if (NS_WARN_IF(!mDivertingFromChild)) {
-    MOZ_ASSERT(mDivertingFromChild,
-               "Cannot ResumeForDiversion if not diverting!");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  if (mSuspendedForDiversion) {
-    nsresult rv = mChannel->Resume();
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      FailDiversion(NS_ERROR_UNEXPECTED, true);
-      return rv;
-    }
-    mSuspendedForDiversion = false;
-  }
-
-  // Delete() will tear down IPDL, but ref from underlying nsFTPChannel will
-  // keep us alive if there's more data to be delivered to listener.
-  if (NS_WARN_IF(NS_FAILED(Delete()))) {
-    FailDiversion(NS_ERROR_UNEXPECTED);
-    return NS_ERROR_UNEXPECTED;   
-  }
-  return NS_OK;
-}
-
-void
-FTPChannelParent::DivertTo(nsIStreamListener *aListener)
-{
-  MOZ_ASSERT(aListener);
-  if (NS_WARN_IF(!mDivertingFromChild)) {
-    MOZ_ASSERT(mDivertingFromChild,
-               "Cannot DivertTo new listener if diverting is not set!");
-    return;
-  }
-
-  if (NS_WARN_IF(mIPCClosed || !SendFlushedForDiversion())) {
-    FailDiversion(NS_ERROR_UNEXPECTED);
-    return;
-  }
-
-  mDivertToListener = aListener;
-
-  // Call OnStartRequest and SendDivertMessages asynchronously to avoid
-  // reentering client context.
-  NS_DispatchToCurrentThread(
-    NS_NewRunnableMethod(this, &FTPChannelParent::StartDiversion));
-  return;
-}
-
-void
-FTPChannelParent::StartDiversion()
-{
-  if (NS_WARN_IF(!mDivertingFromChild)) {
-    MOZ_ASSERT(mDivertingFromChild,
-               "Cannot StartDiversion if diverting is not set!");
-    return;
-  }
-
-  // Fake pending status in case OnStopRequest has already been called.
-  if (mChannel) {
-    mChannel->ForcePending(true);
-  }
-
-  // Call OnStartRequest for the "DivertTo" listener.
-  nsresult rv = OnStartRequest(mChannel, nullptr);
-  if (NS_FAILED(rv)) {
-    if (mChannel) {
-      mChannel->Cancel(rv);
-    }
-    mStatus = rv;
-    return;
-  }
-
-  // After OnStartRequest has been called, tell FTPChannelChild to divert the
-  // OnDataAvailables and OnStopRequest to this FTPChannelParent.
-  if (NS_WARN_IF(mIPCClosed || !SendDivertMessages())) {
-    FailDiversion(NS_ERROR_UNEXPECTED);
-    return;
-  }
-}
-
-class FTPFailDiversionEvent : public nsRunnable
-{
-public:
-  FTPFailDiversionEvent(FTPChannelParent *aChannelParent,
-                        nsresult aErrorCode,
-                        bool aSkipResume)
-    : mChannelParent(aChannelParent)
-    , mErrorCode(aErrorCode)
-    , mSkipResume(aSkipResume)
-  {
-    MOZ_RELEASE_ASSERT(aChannelParent);
-    MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
-  }
-  NS_IMETHOD Run()
-  {
-    mChannelParent->NotifyDiversionFailed(mErrorCode, mSkipResume);
-    return NS_OK;
-  }
-private:
-  nsRefPtr<FTPChannelParent> mChannelParent;
-  nsresult mErrorCode;
-  bool mSkipResume;
-};
-
-void
-FTPChannelParent::FailDiversion(nsresult aErrorCode,
-                                            bool aSkipResume)
-{
-  MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
-  MOZ_RELEASE_ASSERT(mDivertingFromChild);
-  MOZ_RELEASE_ASSERT(mDivertToListener);
-  MOZ_RELEASE_ASSERT(mChannel);
-
-  NS_DispatchToCurrentThread(
-    new FTPFailDiversionEvent(this, aErrorCode, aSkipResume));
-}
-
-void
-FTPChannelParent::NotifyDiversionFailed(nsresult aErrorCode,
-                                        bool aSkipResume)
-{
-  MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
-  MOZ_RELEASE_ASSERT(mDivertingFromChild);
-  MOZ_RELEASE_ASSERT(mDivertToListener);
-  MOZ_RELEASE_ASSERT(mChannel);
-
-  mChannel->Cancel(aErrorCode);
-
-  mChannel->ForcePending(false);
-
-  bool isPending = false;
-  nsresult rv = mChannel->IsPending(&isPending);
-  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-
-  // Resume only we suspended earlier.
-  if (mSuspendedForDiversion) {
-    mChannel->Resume();
-  }
-  // Channel has already sent OnStartRequest to the child, so ensure that we
-  // call it here if it hasn't already been called.
-  if (!mDivertedOnStartRequest) {
-    mChannel->ForcePending(true);
-    mDivertToListener->OnStartRequest(mChannel, nullptr);
-    mChannel->ForcePending(false);
-  }
-  // If the channel is pending, it will call OnStopRequest itself; otherwise, do
-  // it here.
-  if (!isPending) {
-    mDivertToListener->OnStopRequest(mChannel, nullptr, aErrorCode);
-  }
-  mDivertToListener = nullptr;
-  mChannel = nullptr;
-
-  if (!mIPCClosed) {
-    unused << SendDeleteSelf();
-  }
-}
-
 //---------------------
 } // namespace net
 } // namespace mozilla
 
--- a/netwerk/protocol/ftp/FTPChannelParent.h
+++ b/netwerk/protocol/ftp/FTPChannelParent.h
@@ -3,65 +3,44 @@
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_net_FTPChannelParent_h
 #define mozilla_net_FTPChannelParent_h
 
-#include "ADivertableParentChannel.h"
 #include "mozilla/net/PFTPChannelParent.h"
 #include "mozilla/net/NeckoParent.h"
 #include "nsIParentChannel.h"
 #include "nsIInterfaceRequestor.h"
 
 class nsFtpChannel;
 class nsILoadContext;
 
 namespace mozilla {
 namespace net {
 
 class FTPChannelParent : public PFTPChannelParent
                        , public nsIParentChannel
                        , public nsIInterfaceRequestor
-                       , public ADivertableParentChannel
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIPARENTCHANNEL
   NS_DECL_NSIINTERFACEREQUESTOR
 
   FTPChannelParent(nsILoadContext* aLoadContext, PBOverrideStatus aOverrideStatus);
   virtual ~FTPChannelParent();
 
   bool Init(const FTPChannelCreationArgs& aOpenArgs);
 
-  // ADivertableParentChannel functions.
-  void DivertTo(nsIStreamListener *aListener) MOZ_OVERRIDE;
-  nsresult SuspendForDiversion() MOZ_OVERRIDE;
-
-  // Calls OnStartRequest for "DivertTo" listener, then notifies child channel
-  // that it should divert OnDataAvailable and OnStopRequest calls to this
-  // parent channel.
-  void StartDiversion();
-
-  // Handles calling OnStart/Stop if there are errors during diversion.
-  // Called asynchronously from FailDiversion.
-  void NotifyDiversionFailed(nsresult aErrorCode, bool aSkipResume = true);
-
 protected:
-  // private, supporting function for ADivertableParentChannel.
-  nsresult ResumeForDiversion();
-
-  // Asynchronously calls NotifyDiversionFailed.
-  void FailDiversion(nsresult aErrorCode, bool aSkipResume = true);
-
   bool DoAsyncOpen(const URIParams& aURI, const uint64_t& aStartPos,
                    const nsCString& aEntityID,
                    const OptionalInputStreamParams& aUploadStream);
 
   // used to connect redirected-to channel in parent with just created
   // ChildChannel.  Used during HTTP->FTP redirects.
   bool ConnectChannel(const uint32_t& channelId);
 
@@ -78,30 +57,14 @@ protected:
 
   nsRefPtr<nsFtpChannel> mChannel;
 
   bool mIPCClosed;
 
   nsCOMPtr<nsILoadContext> mLoadContext;
 
   PBOverrideStatus mPBOverride;
-
-  // If OnStart/OnData/OnStop have been diverted from the child, forward them to
-  // this listener.
-  nsCOMPtr<nsIStreamListener> mDivertToListener;
-  // Set to the canceled status value if the main channel was canceled.
-  nsresult mStatus;
-  // Once set, no OnStart/OnData/OnStop calls should be accepted; conversely, it
-  // must be set when RecvDivertOnData/~DivertOnStop/~DivertComplete are
-  // received from the child channel.
-  bool mDivertingFromChild;
-  // Set if OnStart|StopRequest was called during a diversion from the child.
-  bool mDivertedOnStartRequest;
-
-  // Set if we successfully suspended the nsHttpChannel for diversion. Unset
-  // when we call ResumeForDiversion.
-  bool mSuspendedForDiversion;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_FTPChannelParent_h
--- a/netwerk/protocol/ftp/nsFTPChannel.cpp
+++ b/netwerk/protocol/ftp/nsFTPChannel.cpp
@@ -33,17 +33,17 @@ NS_IMPL_ISUPPORTS_INHERITED4(nsFtpChanne
 
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsFtpChannel::SetUploadStream(nsIInputStream *stream,
                               const nsACString &contentType,
                               int64_t contentLength)
 {
-    NS_ENSURE_TRUE(!Pending(), NS_ERROR_IN_PROGRESS);
+    NS_ENSURE_TRUE(!IsPending(), NS_ERROR_IN_PROGRESS);
 
     mUploadStream = stream;
 
     // NOTE: contentLength is intentionally ignored here.
  
     return NS_OK;
 }
 
@@ -56,17 +56,17 @@ nsFtpChannel::GetUploadStream(nsIInputSt
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsFtpChannel::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID)
 {
-    NS_ENSURE_TRUE(!Pending(), NS_ERROR_IN_PROGRESS);
+    NS_ENSURE_TRUE(!IsPending(), NS_ERROR_IN_PROGRESS);
     mEntityID = aEntityID;
     mStartPos = aStartPos;
     mResumeRequested = (mStartPos || !mEntityID.IsEmpty());
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFtpChannel::GetEntityID(nsACString& entityID)
@@ -191,31 +191,8 @@ nsFtpChannel::GetFTPEventSink(nsCOMPtr<n
         nsCOMPtr<nsIFTPEventSink> ftpSink;
         GetCallback(ftpSink);
         if (ftpSink) {
             mFTPEventSink = new FTPEventSinkProxy(ftpSink);
         }
     }
     aResult = mFTPEventSink;
 }
-
-void
-nsFtpChannel::ForcePending(bool aForcePending)
-{
-    // Set true here so IsPending will return true.
-    // Required for callback diversion from child back to parent. In such cases
-    // OnStopRequest can be called in the parent before callbacks are diverted
-    // back from the child to the listener in the parent.
-    mForcePending = aForcePending;
-}
-
-NS_IMETHODIMP
-nsFtpChannel::IsPending(bool *result)
-{
-  *result = Pending();
-  return NS_OK;
-}
-
-bool
-nsFtpChannel::Pending() const
-{
-  return nsBaseChannel::Pending() || mForcePending;
-}
--- a/netwerk/protocol/ftp/nsFTPChannel.h
+++ b/netwerk/protocol/ftp/nsFTPChannel.h
@@ -31,36 +31,29 @@ public:
     NS_DECL_NSIRESUMABLECHANNEL
     NS_DECL_NSIPROXIEDCHANNEL
 
     nsFtpChannel(nsIURI *uri, nsIProxyInfo *pi)
         : mProxyInfo(pi)
         , mStartPos(0)
         , mResumeRequested(false)
         , mLastModifiedTime(0)
-        , mForcePending(false)
     {
         SetURI(uri);
     }
 
     nsIProxyInfo *ProxyInfo() {
         return mProxyInfo;
     }
 
     void SetProxyInfo(nsIProxyInfo *pi)
     {
         mProxyInfo = pi;
     }
 
-    NS_IMETHOD IsPending(bool *result) MOZ_OVERRIDE;
-
-    // This is a short-cut to calling nsIRequest::IsPending().
-    // Overrides Pending in nsBaseChannel.
-    bool Pending() const MOZ_OVERRIDE;
-
     // Were we asked to resume a download?
     bool ResumeRequested() { return mResumeRequested; }
 
     // Download from this byte offset
     uint64_t StartPos() { return mStartPos; }
 
     // ID of the entity to resume downloading
     const nsCString &EntityID() {
@@ -83,30 +76,26 @@ public:
     // Data stream to upload
     nsIInputStream *UploadStream() {
         return mUploadStream;
     }
 
     // Helper function for getting the nsIFTPEventSink.
     void GetFTPEventSink(nsCOMPtr<nsIFTPEventSink> &aResult);
 
-public: /* Internal Necko use only. */
-    void ForcePending(bool aForcePending);
-
 protected:
     virtual ~nsFtpChannel() {}
     virtual nsresult OpenContentStream(bool async, nsIInputStream **result,
                                        nsIChannel** channel);
     virtual bool GetStatusArg(nsresult status, nsString &statusArg);
     virtual void OnCallbacksChanged();
 
 private:
     nsCOMPtr<nsIProxyInfo>    mProxyInfo; 
     nsCOMPtr<nsIFTPEventSink> mFTPEventSink;
     nsCOMPtr<nsIInputStream>  mUploadStream;
     uint64_t                  mStartPos;
     nsCString                 mEntityID;
     bool                      mResumeRequested;
     PRTime                    mLastModifiedTime;
-    bool                      mForcePending;
 };
 
 #endif /* nsFTPChannel_h___ */