Bug 1510715 - Backed out changeset d15f0ac561d9 (bug 1260527) a=backout
authorValentin Gosu <valentin.gosu@gmail.com>
Wed, 28 Nov 2018 21:40:35 +0100
changeset 448626 9468e111ca989158c3d48e447756da6a57e184a4
parent 448625 9e3b1b073d5e859a010b07119c80adde8a13c41e
child 448627 97a4811843233628012bd1188b7b66843303eaee
push id35120
push userccoroiu@mozilla.com
push dateThu, 29 Nov 2018 04:28:09 +0000
treeherdermozilla-central@5972866ac7da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1510715, 1260527
milestone65.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 1510715 - Backed out changeset d15f0ac561d9 (bug 1260527) a=backout
netwerk/ipc/NeckoChild.cpp
netwerk/ipc/NeckoChild.h
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/PHttpChannel.ipdl
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -69,17 +69,19 @@ void NeckoChild::InitNeckoChild()
       return;
     }
     gNeckoChild = cpc->SendPNeckoConstructor();
     NS_ASSERTION(gNeckoChild, "PNecko Protocol init failed!");
   }
 }
 
 PHttpChannelChild*
-NeckoChild::AllocPHttpChannelChild()
+NeckoChild::AllocPHttpChannelChild(const PBrowserOrId& browser,
+                                   const SerializedLoadContext& loadContext,
+                                   const HttpChannelCreationArgs& aOpenArgs)
 {
   // We don't allocate here: instead we always use IPDL constructor that takes
   // an existing HttpChildChannel
   MOZ_ASSERT_UNREACHABLE("AllocPHttpChannelChild should not be called on "
                          "child");
   return nullptr;
 }
 
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -20,17 +20,19 @@ class NeckoChild :
 {
 public:
   NeckoChild() = default;
   virtual ~NeckoChild();
 
   static void InitNeckoChild();
 
 protected:
-  virtual PHttpChannelChild* AllocPHttpChannelChild() override;
+  virtual PHttpChannelChild*
+    AllocPHttpChannelChild(const PBrowserOrId&, const SerializedLoadContext&,
+                           const HttpChannelCreationArgs& aOpenArgs) override;
   virtual bool DeallocPHttpChannelChild(PHttpChannelChild*) override;
 
   virtual PStunAddrsRequestChild* AllocPStunAddrsRequestChild() override;
   virtual bool
     DeallocPStunAddrsRequestChild(PStunAddrsRequestChild* aActor) override;
 
   virtual PWebrtcProxyChannelChild* AllocPWebrtcProxyChannelChild(
     const PBrowserOrId& browser) override;
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -87,31 +87,29 @@ NeckoParent::NeckoParent()
   static bool registeredBool = false;
   if (!registeredBool) {
     Preferences::AddBoolVarCache(&NeckoCommonInternal::gSecurityDisabled,
                                  "network.disable.ipc.security");
     registeredBool = true;
   }
 }
 
-/* static */ PBOverrideStatus
-NeckoParent::PBOverrideStatusFromLoadContext(
-  const SerializedLoadContext& aSerialized)
+static PBOverrideStatus
+PBOverrideStatusFromLoadContext(const SerializedLoadContext& aSerialized)
 {
   if (!aSerialized.IsNotNull() && aSerialized.IsPrivateBitValid()) {
     return (aSerialized.mOriginAttributes.mPrivateBrowsingId > 0) ?
       kPBOverride_Private :
       kPBOverride_NotPrivate;
   }
   return kPBOverride_Unset;
 }
 
-/* static */ already_AddRefed<nsIPrincipal>
-NeckoParent::GetRequestingPrincipal(
-  const OptionalLoadInfoArgs& aOptionalLoadInfoArgs)
+static already_AddRefed<nsIPrincipal>
+GetRequestingPrincipal(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs)
 {
   if (aOptionalLoadInfoArgs.type() != OptionalLoadInfoArgs::TLoadInfoArgs) {
     return nullptr;
   }
 
   const LoadInfoArgs& loadInfoArgs = aOptionalLoadInfoArgs.get_LoadInfoArgs();
   const OptionalPrincipalInfo& optionalPrincipalInfo =
     loadInfoArgs.requestingPrincipalInfo();
@@ -121,29 +119,29 @@ NeckoParent::GetRequestingPrincipal(
   }
 
   const PrincipalInfo& principalInfo =
     optionalPrincipalInfo.get_PrincipalInfo();
 
   return PrincipalInfoToPrincipal(principalInfo);
 }
 
-/* static */ already_AddRefed<nsIPrincipal>
-NeckoParent::GetRequestingPrincipal(const HttpChannelCreationArgs& aArgs)
+static already_AddRefed<nsIPrincipal>
+GetRequestingPrincipal(const HttpChannelCreationArgs& aArgs)
 {
   if (aArgs.type() != HttpChannelCreationArgs::THttpChannelOpenArgs) {
     return nullptr;
   }
 
   const HttpChannelOpenArgs& args = aArgs.get_HttpChannelOpenArgs();
   return GetRequestingPrincipal(args.loadInfo());
 }
 
-/* static */ already_AddRefed<nsIPrincipal>
-NeckoParent::GetRequestingPrincipal(const FTPChannelCreationArgs& aArgs)
+static already_AddRefed<nsIPrincipal>
+GetRequestingPrincipal(const FTPChannelCreationArgs& aArgs)
 {
   if (aArgs.type() != FTPChannelCreationArgs::TFTPChannelOpenArgs) {
     return nullptr;
   }
 
   const FTPChannelOpenArgs& args = aArgs.get_FTPChannelOpenArgs();
   return GetRequestingPrincipal(args.loadInfo());
 }
@@ -154,17 +152,17 @@ NeckoParent::GetRequestingPrincipal(cons
 static MOZ_COLD
 void CrashWithReason(const char * reason)
 {
 #ifndef RELEASE_OR_BETA
   MOZ_CRASH_UNSAFE_OOL(reason);
 #endif
 }
 
-/* static */ const char*
+const char*
 NeckoParent::GetValidatedOriginAttributes(const SerializedLoadContext& aSerialized,
                                           PContentParent* aContent,
                                           nsIPrincipal* aRequestingPrincipal,
                                           OriginAttributes& aAttrs)
 {
   if (!UsingNeckoIPCSecurity()) {
     if (!aSerialized.IsNotNull()) {
       // If serialized is null, we cannot validate anything. We have to assume
@@ -230,17 +228,17 @@ NeckoParent::GetValidatedOriginAttribute
   // Leak the buffer on the heap to make sure that it lives long enough, as
   // MOZ_CRASH_ANNOTATE expects the pointer passed to it to live to the end of
   // the program.
   char * error = strdup(errorString.BeginReading());
   CrashWithReason(error);
   return "App does not have permission";
 }
 
-/* static */ const char *
+const char *
 NeckoParent::CreateChannelLoadContext(const PBrowserOrId& aBrowser,
                                       PContentParent* aContent,
                                       const SerializedLoadContext& aSerialized,
                                       nsIPrincipal* aRequestingPrincipal,
                                       nsCOMPtr<nsILoadContext> &aResult)
 {
   OriginAttributes attrs;
   const char* error = GetValidatedOriginAttributes(aSerialized, aContent,
@@ -281,31 +279,61 @@ NeckoParent::CreateChannelLoadContext(co
 void
 NeckoParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   // Nothing needed here. Called right before destructor since this is a
   // non-refcounted class.
 }
 
 PHttpChannelParent*
-NeckoParent::AllocPHttpChannelParent()
+NeckoParent::AllocPHttpChannelParent(const PBrowserOrId& aBrowser,
+                                     const SerializedLoadContext& aSerialized,
+                                     const HttpChannelCreationArgs& aOpenArgs)
 {
-  HttpChannelParent* p = new HttpChannelParent();
+  nsCOMPtr<nsIPrincipal> requestingPrincipal =
+    GetRequestingPrincipal(aOpenArgs);
+
+  nsCOMPtr<nsILoadContext> loadContext;
+  const char *error = CreateChannelLoadContext(aBrowser, Manager(),
+                                               aSerialized, requestingPrincipal,
+                                               loadContext);
+  if (error) {
+    printf_stderr("NeckoParent::AllocPHttpChannelParent: "
+                  "FATAL error: %s: KILLING CHILD PROCESS\n",
+                  error);
+    return nullptr;
+  }
+  PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(aSerialized);
+  HttpChannelParent *p = new HttpChannelParent(aBrowser, loadContext, overrideStatus);
   p->AddRef();
   return p;
 }
 
 bool
 NeckoParent::DeallocPHttpChannelParent(PHttpChannelParent* channel)
 {
   HttpChannelParent *p = static_cast<HttpChannelParent *>(channel);
   p->Release();
   return true;
 }
 
+mozilla::ipc::IPCResult
+NeckoParent::RecvPHttpChannelConstructor(
+                      PHttpChannelParent* aActor,
+                      const PBrowserOrId& aBrowser,
+                      const SerializedLoadContext& aSerialized,
+                      const HttpChannelCreationArgs& aOpenArgs)
+{
+  HttpChannelParent* p = static_cast<HttpChannelParent*>(aActor);
+  if (!p->Init(aOpenArgs)) {
+    return IPC_FAIL_NO_REASON(this);
+  }
+  return IPC_OK();
+}
+
 PStunAddrsRequestParent*
 NeckoParent::AllocPStunAddrsRequestParent()
 {
 #ifdef MOZ_WEBRTC
   StunAddrsRequestParent* p = new StunAddrsRequestParent();
   p->AddRef();
   return p;
 #else
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -28,25 +28,16 @@ enum PBOverrideStatus {
 // Header file contents
 class NeckoParent
   : public PNeckoParent
 {
 public:
   NeckoParent();
   virtual ~NeckoParent() = default;
 
-  static PBOverrideStatus PBOverrideStatusFromLoadContext(
-    const SerializedLoadContext& aSerialized);
-  static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
-    const OptionalLoadInfoArgs& aOptionalLoadInfoArgs);
-  static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
-    const FTPChannelCreationArgs& aArgs);
-  static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
-    const HttpChannelCreationArgs& aArgs);
-
   MOZ_MUST_USE
   static const char *
   GetValidatedOriginAttributes(const SerializedLoadContext& aSerialized,
                                PContentParent* aBrowser,
                                nsIPrincipal* aRequestingPrincipal,
                                mozilla::OriginAttributes& aAttrs);
 
   /*
@@ -97,17 +88,25 @@ public:
                                nsIAuthInformation* aInfo, nsICancelable**) override;
 
   protected:
     PNeckoParent* mNeckoParent;
     TabId mNestedFrameId;
   };
 
 protected:
-  virtual PHttpChannelParent* AllocPHttpChannelParent() override;
+  virtual PHttpChannelParent*
+    AllocPHttpChannelParent(const PBrowserOrId&, const SerializedLoadContext&,
+                            const HttpChannelCreationArgs& aOpenArgs) override;
+  virtual mozilla::ipc::IPCResult
+    RecvPHttpChannelConstructor(
+      PHttpChannelParent* aActor,
+      const PBrowserOrId& aBrowser,
+      const SerializedLoadContext& aSerialized,
+      const HttpChannelCreationArgs& aOpenArgs) override;
   virtual bool DeallocPHttpChannelParent(PHttpChannelParent*) override;
 
   virtual PStunAddrsRequestParent* AllocPStunAddrsRequestParent() override;
   virtual bool
     DeallocPStunAddrsRequestParent(PStunAddrsRequestParent* aActor) override;
 
   virtual PWebrtcProxyChannelParent* AllocPWebrtcProxyChannelParent(
     const PBrowserOrId& aBrowser) override;
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -67,17 +67,19 @@ nested(upto inside_cpow) sync protocol P
   manages PStunAddrsRequest;
   manages PTrackingDummyChannel;
   manages PWebrtcProxyChannel;
 
 parent:
   async __delete__();
 
   nested(inside_cpow) async PCookieService();
-  async PHttpChannel();
+  async PHttpChannel(PBrowserOrId browser,
+                     SerializedLoadContext loadContext,
+                     HttpChannelCreationArgs args);
   async PWyciwygChannel();
   async PFTPChannel(PBrowserOrId browser, SerializedLoadContext loadContext,
                     FTPChannelCreationArgs args);
 
   async PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext,
                    uint32_t aSerialID);
   async PTCPServerSocket(uint16_t localPort, uint16_t backlog, bool useArrayBuffers);
   async PUDPSocket(Principal principal, nsCString filter);
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -188,17 +188,16 @@ HttpChannelChild::HttpChannelChild()
   , mShouldInterceptSubsequentRedirect(false)
   , mRedirectingForSubsequentSynthesizedResponse(false)
   , mPostRedirectChannelShouldIntercept(false)
   , mPostRedirectChannelShouldUpgrade(false)
   , mShouldParentIntercept(false)
   , mSuspendParentAfterSynthesizeResponse(false)
   , mCacheNeedToReportBytesReadInitialized(false)
   , mNeedToReportBytesRead(true)
-  , mSentAsyncOpen(false)
 {
   LOG(("Creating HttpChannelChild @%p\n", this));
 
   mChannelCreationTime = PR_Now();
   mChannelCreationTimestamp = TimeStamp::Now();
   mLastStatusReported = mChannelCreationTimestamp; // in case we enable the profiler after Init()
   mAsyncOpenTime = TimeStamp::Now();
   mEventQ = new ChannelEventQueue(static_cast<nsIHttpChannel*>(this));
@@ -262,17 +261,17 @@ NS_IMETHODIMP_(MozExternalRefCountType) 
   nsrefcnt count = --mRefCnt;
   MOZ_ASSERT(int32_t(count) >= 0, "dup release");
   NS_LOG_RELEASE(this, count, "HttpChannelChild");
 
   // Normally we Send_delete in OnStopRequest, but when we need to retain the
   // remote channel for security info IPDL itself holds 1 reference, so we
   // Send_delete when refCnt==1.  But if !mIPCOpen, then there's nobody to send
   // to, so we fall through.
-  if ((mKeptAlive || !mSentAsyncOpen) && count == 1 && mIPCOpen) {
+  if (mKeptAlive && count == 1 && mIPCOpen) {
     mKeptAlive = false;
     // We send a message to the parent, which calls SendDelete, and then the
     // child calling Send__delete__() to finally drop the refcount to 0.
     TrySendDeletingChannel();
     return 1;
   }
 
   if (count == 0) {
@@ -1647,18 +1646,17 @@ HttpChannelChild::RecvFinishInterceptedR
 void
 HttpChannelChild::DeleteSelf()
 {
   Send__delete__(this);
 }
 
 void HttpChannelChild::FinishInterceptedRedirect()
 {
-  nsresult rv = InitIPCChannel(); // reinitializes IPC channel
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
+  nsresult rv;
   if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
     MOZ_ASSERT(!mInterceptedRedirectContext, "the context should be null!");
     rv = AsyncOpen2(mInterceptedRedirectListener);
   } else {
     rv = AsyncOpen(mInterceptedRedirectListener, mInterceptedRedirectContext);
   }
   mInterceptedRedirectListener = nullptr;
   mInterceptedRedirectContext = nullptr;
@@ -2205,23 +2203,34 @@ HttpChannelChild::ConnectParent(uint32_t
 
   ContentChild* cc = static_cast<ContentChild*>(gNeckoChild->Manager());
   if (cc->IsShuttingDown()) {
     return NS_ERROR_FAILURE;
   }
 
   HttpBaseChannel::SetDocshellUserAgentOverride();
 
+  // 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();
+
+  // This must happen before the constructor message is sent. Otherwise messages
+  // from the parent could arrive quickly and be delivered to the wrong event
+  // target.
+  SetEventTarget();
+
   HttpChannelConnectArgs connectArgs(registrarId, mShouldParentIntercept);
   PBrowserOrId browser = static_cast<ContentChild*>(gNeckoChild->Manager())
                          ->GetBrowserOrId(tabChild);
-  if (!SendAsyncOpen(browser, IPC::SerializedLoadContext(this), connectArgs)) {
+  if (!gNeckoChild->
+        SendPHttpChannelConstructor(this, browser,
+                                    IPC::SerializedLoadContext(this),
+                                    connectArgs)) {
     return NS_ERROR_FAILURE;
   }
-  mSentAsyncOpen = true;
 
   {
     MutexAutoLock lock(mBgChildMutex);
 
     MOZ_ASSERT(!mBgChild);
     MOZ_ASSERT(!mBgInitFailCallback);
 
     mBgInitFailCallback = NewRunnableMethod<nsresult>(
@@ -2718,52 +2727,16 @@ HttpChannelChild::AsyncOpen2(nsIStreamLi
   nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     ReleaseListeners();
     return rv;
   }
   return AsyncOpen(listener, nullptr);
 }
 
-NS_IMETHODIMP
-HttpChannelChild::SetLoadInfo(nsILoadInfo* aLoadInfo)
-{
-  LOG(("HttpChannelChild::SetLoadInfo [this=%p, aLoadInfo=%p]",
-       this, aLoadInfo));
-  MOZ_ALWAYS_SUCCEEDS(HttpBaseChannel::SetLoadInfo(aLoadInfo));
-
-  // IPC channel already open
-  if (NS_WARN_IF(mIPCOpen)) {
-    return NS_OK;
-  }
-
-  return InitIPCChannel();
-}
-
-nsresult
-HttpChannelChild::InitIPCChannel()
-{
-  MOZ_ASSERT(!mIPCOpen);
-
-  // This must happen before the constructor message is sent. Otherwise messages
-  // from the parent could arrive quickly and be delivered to the wrong event
-  // target.
-  SetEventTarget();
-
-  LOG(("  Calling SendPHttpChannelConstructor"));
-  if (!gNeckoChild->SendPHttpChannelConstructor(this)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // 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();
-  return NS_OK;
-}
-
 // Assigns an nsIEventTarget to our IPDL actor so that IPC messages are sent to
 // the correct DocGroup/TabGroup.
 void
 HttpChannelChild::SetEventTarget()
 {
   nsCOMPtr<nsILoadInfo> loadInfo;
   GetLoadInfo(getter_AddRefs(loadInfo));
 
@@ -2967,22 +2940,31 @@ HttpChannelChild::ContinueAsyncOpen()
   openArgs.dispatchFetchEventEnd()    = mDispatchFetchEventEnd;
   openArgs.handleFetchEventStart()    = mHandleFetchEventStart;
   openArgs.handleFetchEventEnd()      = mHandleFetchEventEnd;
 
   openArgs.forceMainDocumentChannel() = mForceMainDocumentChannel;
 
   openArgs.navigationStartTimeStamp() = navigationStartTimeStamp;
 
-  LOG(("HttpChannelChild::ContinueAsyncOpen - SendAsyncOpen [this=%p]", this));
+  // This must happen before the constructor message is sent. Otherwise messages
+  // from the parent could arrive quickly and be delivered to the wrong event
+  // target.
+  SetEventTarget();
+
+  // 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();
+
   PBrowserOrId browser = cc->GetBrowserOrId(tabChild);
-  if (!SendAsyncOpen(browser, IPC::SerializedLoadContext(this), openArgs)) {
+  if (!gNeckoChild->SendPHttpChannelConstructor(this, browser,
+                                                IPC::SerializedLoadContext(this),
+                                                openArgs)) {
     return NS_ERROR_FAILURE;
   }
-  mSentAsyncOpen = true;
 
   {
     MutexAutoLock lock(mBgChildMutex);
 
     MOZ_RELEASE_ASSERT(gSocketTransportService);
 
     // Service worker might use the same HttpChannelChild to do async open
     // twice. Need to disconnect with previous background channel before
@@ -3749,24 +3731,16 @@ HttpChannelChild::ResetInterception()
     mLoadFlags |= LOAD_BYPASS_SERVICE_WORKER;
   }
 
   // If the channel has already been aborted or canceled, just stop.
   if (NS_FAILED(mStatus)) {
     return;
   }
 
-  if (!mIPCOpen) {
-    // The IPC channel was closed. See RecvFinishInterceptedRedirect.
-    // We now want to reuse it, so we call InitIPCChannel again.
-    DebugOnly<nsresult> rv = InitIPCChannel();
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
-  }
-  MOZ_ASSERT(mLoadInfo && mIPCOpen);
-
   // Continue with the original cross-process request
   nsresult rv = ContinueAsyncOpen();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     Unused << Cancel(rv);
   }
 }
 
 void
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -86,17 +86,16 @@ public:
   // nsIRequest
   NS_IMETHOD Cancel(nsresult status) override;
   NS_IMETHOD Suspend() override;
   NS_IMETHOD Resume() override;
   // nsIChannel
   NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo) override;
   NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext) override;
   NS_IMETHOD AsyncOpen2(nsIStreamListener *aListener) override;
-  NS_IMETHOD SetLoadInfo(nsILoadInfo* aLoadInfo) override;
 
   // HttpBaseChannel::nsIHttpChannel
   NS_IMETHOD SetReferrerWithPolicy(nsIURI *referrer, uint32_t referrerPolicy) override;
   NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
                               const nsACString& aValue,
                               bool aMerge) override;
   NS_IMETHOD SetEmptyRequestHeader(const nsACString& aHeader) override;
   NS_IMETHOD RedirectTo(nsIURI *newURI) override;
@@ -202,17 +201,16 @@ protected:
   };
 
   // Get event target for processing network events.
   already_AddRefed<nsIEventTarget> GetNeckoTarget() override;
 
   virtual mozilla::ipc::IPCResult RecvLogBlockedCORSRequest(const nsString& aMessage, const nsCString& aCategory) override;
   NS_IMETHOD LogBlockedCORSRequest(const nsAString & aMessage, const nsACString& aCategory) override;
 
-  nsresult InitIPCChannel();
 private:
   nsresult
   AsyncCallImpl(void (HttpChannelChild::*funcPtr)(),
                 nsRunnableMethod<HttpChannelChild> **retval);
 
   class OverrideRunnable : public Runnable {
   public:
     OverrideRunnable(HttpChannelChild* aChannel,
@@ -429,32 +427,21 @@ private:
   uint8_t mSuspendParentAfterSynthesizeResponse : 1;
 
   // Set if we get the result and cache |mNeedToReportBytesRead|
   uint8_t mCacheNeedToReportBytesReadInitialized : 1;
 
   // True if we need to tell the parent the size of unreported received data
   uint8_t mNeedToReportBytesRead : 1;
 
-  // True after SendAsyncOpen is called.
-  uint8_t mSentAsyncOpen : 1;
-
   void FinishInterceptedRedirect();
   void CleanupRedirectingChannel(nsresult rv);
 
   // true after successful AsyncOpen until OnStopRequest completes.
-  // XXX valentin: technically the channel exists after SetLoadInfo, but it
-  // used to be created at AsyncOpen, and before that the parent actually
-  // doesn't have all the info for it to be safe to call any method.
-  // We should rename it in the future and allow some methods to be called
-  // before asyncOpen.
-  bool RemoteChannelExists()
-  {
-    return mIPCOpen && !mKeptAlive && mSentAsyncOpen;
-  }
+  bool RemoteChannelExists() { return mIPCOpen && !mKeptAlive; }
 
   void AssociateApplicationCache(const nsCString &groupID,
                                  const nsCString &clientID);
   void OnStartRequest(const nsresult& channelStatus,
                       const nsHttpResponseHead& responseHead,
                       const bool& useResponseHead,
                       const nsHttpHeaderArray& requestHeaders,
                       const ParentLoadInfoForwarderArgs& loadInfoForwarder,
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -57,21 +57,23 @@
 
 using mozilla::BasePrincipal;
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
-HttpChannelParent::HttpChannelParent()
-  : mLoadContext(nullptr)
+HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding,
+                                     nsILoadContext* aLoadContext,
+                                     PBOverrideStatus aOverrideStatus)
+  : mLoadContext(aLoadContext)
   , mNestedFrameId(0)
   , mIPCClosed(false)
-  , mPBOverride(kPBOverride_Unset)
+  , mPBOverride(aOverrideStatus)
   , mStatus(NS_OK)
   , mIgnoreProgress(false)
   , mSentRedirect1BeginFailed(false)
   , mReceivedRedirect2Verify(false)
   , mHasSuspendedByBackPressure(false)
   , mPendingDiversion(false)
   , mDivertingFromChild(false)
   , mDivertedOnStartRequest(false)
@@ -87,16 +89,24 @@ HttpChannelParent::HttpChannelParent()
 
   // Ensure gHttpHandler is initialized: we need the atom table up and running.
   nsCOMPtr<nsIHttpProtocolHandler> dummyInitializer =
     do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http");
 
   MOZ_ASSERT(gHttpHandler);
   mHttpHandler = gHttpHandler;
 
+  if (iframeEmbedding.type() == PBrowserOrId::TPBrowserParent) {
+    mTabParent = static_cast<dom::TabParent*>(iframeEmbedding.get_PBrowserParent());
+  } else {
+    mNestedFrameId = iframeEmbedding.get_TabId();
+  }
+
+  mSendWindowSize = gHttpHandler->SendWindowSize();
+
   mEventQ = new ChannelEventQueue(static_cast<nsIParentRedirectingChannel*>(this));
 }
 
 HttpChannelParent::~HttpChannelParent()
 {
   LOG(("Destroying HttpChannelParent [this=%p]\n", this));
   CleanupBackgroundChannel();
 }
@@ -160,53 +170,16 @@ HttpChannelParent::Init(const HttpChanne
     return ConnectChannel(cArgs.registrarId(), cArgs.shouldIntercept());
   }
   default:
     MOZ_ASSERT_UNREACHABLE("unknown open type");
     return false;
   }
 }
 
-mozilla::ipc::IPCResult
-HttpChannelParent::RecvAsyncOpen(const PBrowserOrId& aBrowser,
-                                 const SerializedLoadContext& aSerialized,
-                                 const HttpChannelCreationArgs& aOpenArgs)
-{
-  LOG(("HttpChannelParent::RecvAsyncOpen [this=%p]\n", this));
-
-  nsCOMPtr<nsIPrincipal> requestingPrincipal =
-    NeckoParent::GetRequestingPrincipal(aOpenArgs);
-
-  nsCOMPtr<nsILoadContext> loadContext;
-  const char* error =
-    NeckoParent::CreateChannelLoadContext(aBrowser,
-                                          Manager()->Manager(),
-                                          aSerialized,
-                                          requestingPrincipal,
-                                          loadContext);
-  if (error) {
-    return IPC_FAIL(this, "Error in NeckoParent::CreateChannelLoadContext");
-  }
-  mPBOverride = NeckoParent::PBOverrideStatusFromLoadContext(aSerialized);
-  mLoadContext = loadContext;
-
-  if (aBrowser.type() == PBrowserOrId::TPBrowserParent) {
-    mTabParent = static_cast<dom::TabParent*>(aBrowser.get_PBrowserParent());
-  } else {
-    mNestedFrameId = aBrowser.get_TabId();
-  }
-
-  mSendWindowSize = gHttpHandler->SendWindowSize();
-
-  if (!Init(aOpenArgs)) {
-    return IPC_FAIL(this, "Error in HttpChannelParent::Init");
-  }
-  return IPC_OK();
-}
-
 void
 HttpChannelParent::TryInvokeAsyncOpen(nsresult aRv)
 {
   LOG(("HttpChannelParent::TryInvokeAsyncOpen [this=%p barrier=%u rv=%" PRIx32
        "]\n", this, mAsyncOpenBarrier, static_cast<uint32_t>(aRv)));
   MOZ_ASSERT(NS_IsMainThread());
 
   // TryInvokeAsyncOpen is called more than we expected.
@@ -500,22 +473,18 @@ HttpChannelParent::DoAsyncOpen(  const U
     return false;
   }
   nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI);
   nsCOMPtr<nsIURI> docUri = DeserializeURI(aDocURI);
   nsCOMPtr<nsIURI> referrerUri = DeserializeURI(aReferrerURI);
   nsCOMPtr<nsIURI> apiRedirectToUri = DeserializeURI(aAPIRedirectToURI);
   nsCOMPtr<nsIURI> topWindowUri = DeserializeURI(aTopWindowURI);
 
-  LOG(("HttpChannelParent DoAsyncOpen [this=%p uri=%s, gid=%" PRIu64
-       " topwinid=%" PRIx64 "]\n",
-       this,
-       uri->GetSpecOrDefault().get(),
-       aChannelId,
-       aTopLevelOuterContentWindowId));
+  LOG(("HttpChannelParent RecvAsyncOpen [this=%p uri=%s, gid=%" PRIu64 " topwinid=%" PRIx64 "]\n",
+       this, uri->GetSpecOrDefault().get(), aChannelId, aTopLevelOuterContentWindowId));
 
   nsresult rv;
 
   nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
 
   nsCOMPtr<nsILoadInfo> loadInfo;
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -66,17 +66,19 @@ public:
   NS_DECL_NSIPROGRESSEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSIAUTHPROMPTPROVIDER
   NS_DECL_NSIDEPRECATIONWARNER
   NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK
 
   NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_PARENT_IID)
 
-  HttpChannelParent();
+  HttpChannelParent(const dom::PBrowserOrId& iframeEmbedding,
+                    nsILoadContext* aLoadContext,
+                    PBOverrideStatus aStatus);
 
   MOZ_MUST_USE bool Init(const HttpChannelCreationArgs& aOpenArgs);
 
   // ADivertableParentChannel functions.
   void DivertTo(nsIStreamListener *aListener) override;
   MOZ_MUST_USE nsresult SuspendForDiversion() override;
   MOZ_MUST_USE nsresult SuspendMessageDiversion() override;
   MOZ_MUST_USE nsresult ResumeMessageDiversion() override;
@@ -226,20 +228,16 @@ protected:
   nsresult LogBlockedCORSRequest(const nsAString& aMessage, const nsACString& aCategory) override;
 
   // Calls SendDeleteSelf and sets mIPCClosed to true because we should not
   // send any more messages after that. Bug 1274886
   MOZ_MUST_USE bool DoSendDeleteSelf();
   // Called to notify the parent channel to not send any more IPC messages.
   virtual mozilla::ipc::IPCResult RecvDeletingChannel() override;
   virtual mozilla::ipc::IPCResult RecvFinishInterceptedRedirect() override;
-  virtual mozilla::ipc::IPCResult RecvAsyncOpen(
-    const PBrowserOrId& aBrowser,
-    const SerializedLoadContext& aSerialized,
-    const HttpChannelCreationArgs& aOpenArgs) override;
 
 private:
   void UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurityInfoOut);
 
   void DivertOnDataAvailable(const nsCString& data,
                              const uint64_t& offset,
                              const uint32_t& count);
   void DivertOnStopRequest(const nsresult& statusCode);
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -8,37 +8,34 @@
 include protocol PNecko;
 include protocol PStreamFilter;
 include InputStreamParams;
 include URIParams;
 include PBackgroundSharedTypes;
 include NeckoChannelParams;
 include IPCServiceWorkerDescriptor;
 include IPCStream;
-include PBrowserOrId;
 
 include "mozilla/net/NeckoMessageUtils.h";
 
 using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
 using mozilla::net::NetAddr from "mozilla/net/DNS.h";
 using struct mozilla::net::ResourceTimingStruct from "mozilla/net/TimingStruct.h";
-using class IPC::SerializedLoadContext from "SerializedLoadContext.h";
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 protocol PHttpChannel
 {
   manager PNecko;
 
 parent:
-  async AsyncOpen(PBrowserOrId browser,
-                  SerializedLoadContext loadContext,
-                  HttpChannelCreationArgs args);
+  // Note: channels are opened during construction, so no open method here:
+  // see PNecko.ipdl
 
   async SetClassOfService(uint32_t cos);
 
   async SetCacheTokenCachedCharset(nsCString charset);
 
   async Suspend();
   async Resume();