Bug 1593560 - Support non-http channels in SendCrossProcessRedirect. r=jya
☠☠ backed out by ffed8d3b4ac5 ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 06 Nov 2019 18:22:47 +0000
changeset 500914 3e3948e9531c5a46195b5f0dcd55147fcb068d83
parent 500913 a7d04e276b448311a6466acca1240aeb2997be57
child 500915 d67a10437af7afe68ac7f43eab4e341040ea37f1
push id114166
push userapavel@mozilla.com
push dateThu, 07 Nov 2019 10:04:01 +0000
treeherdermozilla-inbound@d271c572a9bc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1593560
milestone72.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 1593560 - Support non-http channels in SendCrossProcessRedirect. r=jya Differential Revision: https://phabricator.services.mozilla.com/D51550
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/PContent.ipdl
netwerk/ipc/DocumentChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.cpp
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -3657,82 +3657,87 @@ mozilla::ipc::IPCResult ContentChild::Re
 mozilla::ipc::IPCResult ContentChild::RecvSaveRecording(
     const FileDescriptor& aFile) {
   recordreplay::parent::SaveRecording(aFile);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
     const uint32_t& aRegistrarId, nsIURI* aURI,
-    const ReplacementChannelConfigInit& aConfig,
+    const Maybe<ReplacementChannelConfigInit>& aConfig,
     const Maybe<LoadInfoArgs>& aLoadInfo, const uint64_t& aChannelId,
     nsIURI* aOriginalURI, const uint64_t& aIdentifier,
     const uint32_t& aRedirectMode, CrossProcessRedirectResolver&& aResolve) {
   nsCOMPtr<nsILoadInfo> loadInfo;
   nsresult rv =
       mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfo, getter_AddRefs(loadInfo));
   if (NS_FAILED(rv)) {
     MOZ_DIAGNOSTIC_ASSERT(false, "LoadInfoArgsToLoadInfo failed");
     return IPC_OK();
   }
 
   nsCOMPtr<nsIChannel> newChannel;
   rv = NS_NewChannelInternal(getter_AddRefs(newChannel), aURI, loadInfo);
 
-  // We are sure this is a HttpChannelChild because the parent
-  // is always a HTTP channel.
-  RefPtr<HttpChannelChild> httpChild = do_QueryObject(newChannel);
-  if (NS_FAILED(rv) || !httpChild) {
+  RefPtr<nsIChildChannel> childChannel = do_QueryObject(newChannel);
+  if (NS_FAILED(rv) || !childChannel) {
     MOZ_DIAGNOSTIC_ASSERT(false, "NS_NewChannelInternal failed");
     return IPC_OK();
   }
 
   // This is used to report any errors back to the parent by calling
   // CrossProcessRedirectFinished.
+  RefPtr<HttpChannelChild> httpChild = do_QueryObject(newChannel);
   auto scopeExit = MakeScopeExit([&]() {
-    rv = httpChild->CrossProcessRedirectFinished(rv);
+    if (httpChild) {
+      rv = httpChild->CrossProcessRedirectFinished(rv);
+    }
     nsCOMPtr<nsILoadInfo> loadInfo;
     MOZ_ALWAYS_SUCCEEDS(newChannel->GetLoadInfo(getter_AddRefs(loadInfo)));
     Maybe<LoadInfoArgs> loadInfoArgs;
     MOZ_ALWAYS_SUCCEEDS(
         mozilla::ipc::LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs));
     aResolve(
         Tuple<const nsresult&, const Maybe<LoadInfoArgs>&>(rv, loadInfoArgs));
   });
 
-  rv = httpChild->SetChannelId(aChannelId);
-  if (NS_FAILED(rv)) {
-    return IPC_OK();
-  }
-
-  rv = httpChild->SetOriginalURI(aOriginalURI);
-  if (NS_FAILED(rv)) {
-    return IPC_OK();
+  if (httpChild) {
+    rv = httpChild->SetChannelId(aChannelId);
+    if (NS_FAILED(rv)) {
+      return IPC_OK();
+    }
+
+    rv = httpChild->SetOriginalURI(aOriginalURI);
+    if (NS_FAILED(rv)) {
+      return IPC_OK();
+    }
+
+    rv = httpChild->SetRedirectMode(aRedirectMode);
+    if (NS_FAILED(rv)) {
+      return IPC_OK();
+    }
   }
 
-  rv = httpChild->SetRedirectMode(aRedirectMode);
-  if (NS_FAILED(rv)) {
-    return IPC_OK();
+  if (aConfig) {
+    HttpBaseChannel::ReplacementChannelConfig config(*aConfig);
+    HttpBaseChannel::ConfigureReplacementChannel(
+        newChannel, config,
+        HttpBaseChannel::ConfigureReason::DocumentChannelReplacement);
   }
 
-  HttpBaseChannel::ReplacementChannelConfig config(aConfig);
-  HttpBaseChannel::ConfigureReplacementChannel(
-      newChannel, config,
-      HttpBaseChannel::ConfigureReason::DocumentChannelReplacement);
-
   // connect parent.
-  rv = httpChild->ConnectParent(aRegistrarId);  // creates parent channel
+  rv = childChannel->ConnectParent(aRegistrarId);  // creates parent channel
   if (NS_FAILED(rv)) {
     return IPC_OK();
   }
 
   nsCOMPtr<nsIChildProcessChannelListener> processListener =
       do_GetService("@mozilla.org/network/childProcessChannelListener;1");
   // The listener will call completeRedirectSetup on the channel.
-  rv = processListener->OnChannelReady(httpChild, aIdentifier);
+  rv = processListener->OnChannelReady(childChannel, aIdentifier);
   if (NS_FAILED(rv)) {
     return IPC_OK();
   }
 
   // scopeExit will call CrossProcessRedirectFinished(rv) here
   return IPC_OK();
 }
 
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -662,17 +662,17 @@ class ContentChild final : public PConte
       const ClientOpenWindowArgs& aArgs) override;
 
   bool DeallocPClientOpenWindowOpChild(PClientOpenWindowOpChild* aActor);
 
   mozilla::ipc::IPCResult RecvSaveRecording(const FileDescriptor& aFile);
 
   mozilla::ipc::IPCResult RecvCrossProcessRedirect(
       const uint32_t& aRegistrarId, nsIURI* aURI,
-      const ReplacementChannelConfigInit& aConfig,
+      const Maybe<ReplacementChannelConfigInit>& aConfig,
       const Maybe<LoadInfoArgs>& aLoadInfoForwarder, const uint64_t& aChannelId,
       nsIURI* aOriginalURI, const uint64_t& aIdentifier,
       const uint32_t& aRedirectMode, CrossProcessRedirectResolver&& aResolve);
 
   mozilla::ipc::IPCResult RecvStartDelayedAutoplayMediaComponents(
       BrowsingContext* aContext);
 
   mozilla::ipc::IPCResult RecvUpdateMediaAction(BrowsingContext* aContext,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -811,17 +811,17 @@ child:
     // new HttpChannelChild that will be connected to the parent channel
     // represented by registrarId.
     // This is on PContent not PNecko, as PNecko may not be initialized yet.
     // The returned loadInfo needs to be set on the channel - since the channel
     // moved to a new process it now has different properties.
 
     async CrossProcessRedirect(uint32_t aRegistrarId,
                                nsIURI aURI,
-                               ReplacementChannelConfigInit config,
+                               ReplacementChannelConfigInit? config,
                                LoadInfoArgs? aLoadInfo,
                                uint64_t aChannelId,
                                nsIURI aOriginalURI,
                                uint64_t aIdentifier,
                                uint32_t aRedirectMode)
         returns (nsresult rv, LoadInfoArgs? arg);
 
     /**
--- a/netwerk/ipc/DocumentChannelParent.cpp
+++ b/netwerk/ipc/DocumentChannelParent.cpp
@@ -521,19 +521,17 @@ void DocumentChannelParent::TriggerRedir
   if (aDestinationProcess) {
     dom::ContentParent* cp =
         dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
             ContentParentId{*aDestinationProcess});
     if (!cp) {
       return;
     }
 
-    MOZ_ASSERT(config);
-
-    cp->SendCrossProcessRedirect(mRedirectChannelId, uri, *config, loadInfoArgs,
+    cp->SendCrossProcessRedirect(mRedirectChannelId, uri, config, loadInfoArgs,
                                  channelId, originalURI, aIdentifier,
                                  redirectMode)
         ->Then(
             GetCurrentThreadSerialEventTarget(), __func__,
             [self](Tuple<nsresult, Maybe<LoadInfoArgs>>&& aResponse) {
               if (NS_SUCCEEDED(Get<0>(aResponse))) {
                 nsCOMPtr<nsILoadInfo> newLoadInfo;
                 MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -2680,19 +2680,19 @@ nsresult HttpChannelParent::TriggerCross
             httpChannel->CloneReplacementChannelConfig(true, 0).Serialize();
 
         dom::ContentParent* cp =
             dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
                 ContentParentId{cpId});
         if (!cp) {
           return;
         }
-        cp->SendCrossProcessRedirect(self->mRedirectChannelId, uri, config,
-                                     loadInfoArgs, channelId, originalURI,
-                                     aIdentifier, redirectMode)
+        cp->SendCrossProcessRedirect(self->mRedirectChannelId, uri,
+                                     Some(config), loadInfoArgs, channelId,
+                                     originalURI, aIdentifier, redirectMode)
             ->Then(
                 GetCurrentThreadSerialEventTarget(), __func__,
                 [self](Tuple<nsresult, Maybe<LoadInfoArgs>>&& aResponse) {
                   // We need to continue on the new HttpChannelParent.
                   MOZ_ASSERT(self->mRedirectChannelId);
                   nsCOMPtr<nsIRedirectChannelRegistrar> redirectReg =
                       RedirectChannelRegistrar::GetOrCreate();
                   MOZ_ASSERT(redirectReg);