Bug 1596665 - P3. Copy property bag from parent to child. r=kmag,mayhemer
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 26 Nov 2019 01:24:34 +0000
changeset 503790 4bd5a9363b0d05871982e5d8c4a66ea4b971724c
parent 503789 452793927396fbe72b7f78f676bbeef8cb0aeae4
child 503791 4949c8e7623bb01d5f1832a981a75fd7ac8025f7
push id101548
push userjyavenard@mozilla.com
push dateTue, 26 Nov 2019 03:06:04 +0000
treeherderautoland@5ccb0dc150d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag, mayhemer
bugs1596665
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 1596665 - P3. Copy property bag from parent to child. r=kmag,mayhemer Rather that setting the property bag on both the child and parent from the docshell; we first set it on the parent instead, and once the redirect (or process switch) has completed we carry that bag across. Differential Revision: https://phabricator.services.mozilla.com/D53924
docshell/base/nsDocShell.cpp
dom/ipc/ContentChild.cpp
netwerk/ipc/DocumentChannelChild.cpp
netwerk/ipc/DocumentLoadListener.cpp
netwerk/ipc/NeckoChannelParams.ipdlh
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9696,38 +9696,41 @@ static bool SchemeUsesDocChannel(nsIURI*
     aRv = channel->SetContentDisposition(nsIChannel::DISPOSITION_ATTACHMENT);
     NS_ENSURE_SUCCESS(aRv, false);
     if (!fileName.IsEmpty()) {
       aRv = channel->SetContentDispositionFilename(fileName);
       NS_ENSURE_SUCCESS(aRv, false);
     }
   }
 
+  if (nsCOMPtr<nsIWritablePropertyBag2> props = do_QueryInterface(channel)) {
+    nsCOMPtr<nsIURI> referrer;
+    nsIReferrerInfo* referrerInfo = aLoadState->GetReferrerInfo();
+    if (referrerInfo) {
+      referrerInfo->GetOriginalReferrer(getter_AddRefs(referrer));
+    }
+    // save true referrer for those who need it (e.g. xpinstall whitelisting)
+    // Currently only http and ftp channels support this.
+    props->SetPropertyAsInterface(
+        NS_LITERAL_STRING("docshell.internalReferrer"), referrer);
+
+    if (aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_FIRST_LOAD)) {
+      props->SetPropertyAsBool(NS_LITERAL_STRING("docshell.newWindowTarget"),
+                               true);
+    }
+  }
+
   channel.forget(aChannel);
   return true;
 }
 
 /* static */ nsresult nsDocShell::ConfigureChannel(
     nsIChannel* aChannel, nsDocShellLoadState* aLoadState,
     const nsString* aInitiatorType, uint32_t aLoadType, uint32_t aCacheKey,
     bool aHasNonEmptySandboxingFlags) {
-  nsCOMPtr<nsIWritablePropertyBag2> props(do_QueryInterface(aChannel));
-  if (props) {
-    nsCOMPtr<nsIURI> referrer;
-    nsIReferrerInfo* referrerInfo = aLoadState->GetReferrerInfo();
-    if (referrerInfo) {
-      referrerInfo->GetOriginalReferrer(getter_AddRefs(referrer));
-    }
-
-    // save true referrer for those who need it (e.g. xpinstall whitelisting)
-    // Currently only http and ftp channels support this.
-    props->SetPropertyAsInterface(
-        NS_LITERAL_STRING("docshell.internalReferrer"), referrer);
-  }
-
   nsCOMPtr<nsILoadInfo> loadInfo;
   MOZ_ALWAYS_SUCCEEDS(aChannel->GetLoadInfo(getter_AddRefs(loadInfo)));
 
   nsCOMPtr<nsIURI> rpURI;
   loadInfo->GetResultPrincipalURI(getter_AddRefs(rpURI));
   Maybe<nsCOMPtr<nsIURI>> originalResultPrincipalURI;
   aLoadState->GetMaybeResultPrincipalURI(originalResultPrincipalURI);
   if (originalResultPrincipalURI &&
@@ -9808,24 +9811,16 @@ static bool SchemeUsesDocChannel(nsIURI*
   }
 
   nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(aChannel);
   if (scriptChannel) {
     // Allow execution against our context if the principals match
     scriptChannel->SetExecutionPolicy(nsIScriptChannel::EXECUTE_NORMAL);
   }
 
-  if (aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_FIRST_LOAD)) {
-    nsCOMPtr<nsIWritablePropertyBag2> props = do_QueryInterface(aChannel);
-    if (props) {
-      props->SetPropertyAsBool(NS_LITERAL_STRING("docshell.newWindowTarget"),
-                               true);
-    }
-  }
-
   // TODO: What should we do with this?
   nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(aChannel));
   if (timedChannel) {
     timedChannel->SetTimingEnabled(true);
 
     if (aInitiatorType) {
       timedChannel->SetInitiatorType(*aInitiatorType);
     }
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -3734,16 +3734,20 @@ mozilla::ipc::IPCResult ContentChild::Re
       do_GetService("@mozilla.org/network/childProcessChannelListener;1");
   // The listener will call completeRedirectSetup on the channel.
   rv =
       processListener->OnChannelReady(childChannel, aArgs.redirectIdentifier());
   if (NS_FAILED(rv)) {
     return IPC_OK();
   }
 
+  if (nsCOMPtr<nsIWritablePropertyBag> bag = do_QueryInterface(newChannel)) {
+    nsHashPropertyBag::CopyFrom(bag, aArgs.properties());
+  }
+
   // scopeExit will call CrossProcessRedirectFinished(rv) here
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentChild::RecvStartDelayedAutoplayMediaComponents(
     BrowsingContext* aContext) {
   MOZ_ASSERT(aContext);
   aContext->StartDelayedAutoplayMediaComponents();
--- a/netwerk/ipc/DocumentChannelChild.cpp
+++ b/netwerk/ipc/DocumentChannelChild.cpp
@@ -337,22 +337,24 @@ IPCResult DocumentChannelChild::RecvRedi
   // transfer any properties. This appears to be entirely a content-side
   // interface and isn't copied across to the parent. Copying the values
   // for this from this into the new actor will work, since the parent
   // won't have the right details anyway.
   // TODO: What about the process switch equivalent
   // (ContentChild::RecvCrossProcessRedirect)? In that case there is no local
   // existing actor in the destination process... We really need all information
   // to go up to the parent, and then come down to the new child actor.
-  nsCOMPtr<nsIWritablePropertyBag> bag(do_QueryInterface(newChannel));
-  if (bag) {
-    for (auto iter = mPropertyHash.Iter(); !iter.Done(); iter.Next()) {
-      bag->SetProperty(iter.Key(), iter.UserData());
-    }
+  if (nsCOMPtr<nsIWritablePropertyBag> bag = do_QueryInterface(newChannel)) {
+    nsHashPropertyBag::CopyFrom(bag, aArgs.properties());
   }
+  // We still need to copy the property bag to the DCC as the nsDocShell no
+  // longer set the properties on it during ConfigureChannel. This will go away
+  // once the nsDocShell no longer relies on the DCC to determine the history
+  // data and is instead provided that information from the parent.
+  nsHashPropertyBag::CopyFrom(this, aArgs.properties());
 
   // connect parent.
   if (childChannel) {
     rv = childChannel->ConnectParent(
         aArgs.registrarId());  // creates parent channel
     if (NS_FAILED(rv)) {
       return IPC_OK();
     }
--- a/netwerk/ipc/DocumentLoadListener.cpp
+++ b/netwerk/ipc/DocumentLoadListener.cpp
@@ -480,16 +480,17 @@ void DocumentLoadListener::SerializeRedi
   if (NS_SUCCEEDED(rv)) {
     aArgs.contentDispositionFilename() = Some(contentDispositionFilenameTemp);
   }
 
   aArgs.newLoadFlags() = aLoadFlags;
   aArgs.redirectFlags() = aRedirectFlags;
   aArgs.redirects() = mRedirects;
   aArgs.redirectIdentifier() = mCrossProcessRedirectIdentifier;
+  aArgs.properties() = do_QueryObject(mChannel);
 }
 
 void DocumentLoadListener::TriggerCrossProcessSwitch() {
   MOZ_ASSERT(mRedirectContentProcessIdPromise);
   MOZ_ASSERT(!mDoingProcessSwitch, "Already in the middle of switching?");
   MOZ_ASSERT(NS_IsMainThread());
 
   mDoingProcessSwitch = true;
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -16,16 +16,17 @@ include IPCStream;
 include PBackgroundSharedTypes;
 include DOMTypes;
 
 using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
 using RequestHeaderTuples from "mozilla/net/PHttpChannelParams.h";
 using struct nsHttpAtom from "nsHttp.h";
 using class mozilla::net::nsHttpResponseHead from "nsHttpResponseHead.h";
 using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
+using refcounted class nsIPropertyBag2 from "mozilla/dom/PropertyBagUtils.h";
 
 namespace mozilla {
 namespace net {
 
 //-----------------------------------------------------------------------------
 // CookieSettings IPDL structs
 //-----------------------------------------------------------------------------
 
@@ -385,14 +386,15 @@ struct RedirectToRealChannelArgs {
   DocumentChannelRedirect[] redirects;
   uint64_t channelId;
   nsIURI originalURI;
   uint32_t redirectMode;
   uint32_t redirectFlags;
   uint32_t? contentDisposition;
   nsString? contentDispositionFilename;
   uint64_t redirectIdentifier;
+  nsIPropertyBag2 properties;
 };
 
 
 
 } // namespace ipc
 } // namespace mozilla