Bug 1528695 - Part 1 : Use referrerInfo in openWindow, cpp file r=smaug
authorThomas Nguyen <tnguyen@mozilla.com>
Fri, 15 Mar 2019 05:11:43 +0000
changeset 522015 e5b9c443c421
parent 522014 6c08bfd19a36
child 522016 4d62ab0e31fd
push id10870
push usernbeleuzu@mozilla.com
push dateFri, 15 Mar 2019 20:00:07 +0000
treeherdermozilla-beta@c594aee5b7a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1528695
milestone67.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 1528695 - Part 1 : Use referrerInfo in openWindow, cpp file r=smaug Differential Revision: https://phabricator.services.mozilla.com/D21910
docshell/base/nsDocShellLoadState.cpp
dom/base/nsOpenURIInFrameParams.cpp
dom/base/nsOpenURIInFrameParams.h
dom/interfaces/base/nsIBrowserDOMWindow.idl
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/DOMTypes.ipdlh
dom/ipc/PContent.ipdl
dom/ipc/ReferrerInfoUtils.cpp
dom/ipc/ReferrerInfoUtils.h
dom/ipc/moz.build
--- a/docshell/base/nsDocShellLoadState.cpp
+++ b/docshell/base/nsDocShellLoadState.cpp
@@ -49,19 +49,17 @@ nsDocShellLoadState::nsDocShellLoadState
   mLoadType = aLoadState.LoadType();
   mTarget = aLoadState.Target();
   mLoadFlags = aLoadState.LoadFlags();
   mFirstParty = aLoadState.FirstParty();
   mTypeHint = aLoadState.TypeHint();
   mFileName = aLoadState.FileName();
   mIsFromProcessingFrameAttributes =
       aLoadState.IsFromProcessingFrameAttributes();
-  mReferrerInfo =
-      new ReferrerInfo(aLoadState.Referrer(), aLoadState.ReferrerPolicy(),
-                       aLoadState.SendReferrer());
+  mReferrerInfo = aLoadState.ReferrerInfo();
   mURI = aLoadState.URI();
   mOriginalURI = aLoadState.OriginalURI();
   mBaseURI = aLoadState.BaseURI();
   mTriggeringPrincipal = aLoadState.TriggeringPrincipal();
   mPrincipalToInherit = aLoadState.PrincipalToInherit();
   mCsp = aLoadState.Csp();
 }
 
@@ -462,13 +460,11 @@ DocShellLoadStateInit nsDocShellLoadStat
   loadState.IsFromProcessingFrameAttributes() =
       mIsFromProcessingFrameAttributes;
   loadState.URI() = mURI;
   loadState.OriginalURI() = mOriginalURI;
   loadState.BaseURI() = mBaseURI;
   loadState.TriggeringPrincipal() = mTriggeringPrincipal;
   loadState.PrincipalToInherit() = mPrincipalToInherit;
   loadState.Csp() = mCsp;
-  loadState.Referrer() = mReferrerInfo->GetOriginalReferrer();
-  loadState.SendReferrer() = mReferrerInfo->GetSendReferrer();
-  loadState.ReferrerPolicy() = mReferrerInfo->GetReferrerPolicy();
+  loadState.ReferrerInfo() = mReferrerInfo;
   return loadState;
 }
--- a/dom/base/nsOpenURIInFrameParams.cpp
+++ b/dom/base/nsOpenURIInFrameParams.cpp
@@ -16,43 +16,29 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION(nsOpenURIInFrameParams, mOpenerBrowser)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsOpenURIInFrameParams)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsOpenURIInFrameParams)
 
 nsOpenURIInFrameParams::nsOpenURIInFrameParams(
     const mozilla::OriginAttributes& aOriginAttributes, Element* aOpener)
-    : mOpenerOriginAttributes(aOriginAttributes),
-      mOpenerBrowser(aOpener),
-      mReferrerPolicy(mozilla::net::RP_Unset) {}
+    : mOpenerOriginAttributes(aOriginAttributes), mOpenerBrowser(aOpener) {}
 
 nsOpenURIInFrameParams::~nsOpenURIInFrameParams() {}
 
 NS_IMETHODIMP
-nsOpenURIInFrameParams::GetReferrer(nsAString& aReferrer) {
-  aReferrer = mReferrer;
+nsOpenURIInFrameParams::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) {
+  NS_IF_ADDREF(*aReferrerInfo = mReferrerInfo);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsOpenURIInFrameParams::SetReferrer(const nsAString& aReferrer) {
-  mReferrer = aReferrer;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsOpenURIInFrameParams::GetReferrerPolicy(uint32_t* aReferrerPolicy) {
-  *aReferrerPolicy = mReferrerPolicy;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsOpenURIInFrameParams::SetReferrerPolicy(uint32_t aReferrerPolicy) {
-  mReferrerPolicy = aReferrerPolicy;
+nsOpenURIInFrameParams::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
+  mReferrerInfo = aReferrerInfo;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsOpenURIInFrameParams::GetIsPrivate(bool* aIsPrivate) {
   NS_ENSURE_ARG_POINTER(aIsPrivate);
   *aIsPrivate = mOpenerOriginAttributes.mPrivateBrowsingId > 0;
   return NS_OK;
--- a/dom/base/nsOpenURIInFrameParams.h
+++ b/dom/base/nsOpenURIInFrameParams.h
@@ -3,16 +3,17 @@
 /* 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/BasePrincipal.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIBrowserDOMWindow.h"
 #include "nsFrameLoaderOwner.h"
+#include "nsIReferrerInfo.h"
 #include "nsString.h"
 
 namespace mozilla {
 class OriginAttributes;
 }
 
 class nsOpenURIInFrameParams final : public nsIOpenURIInFrameParams {
  public:
@@ -23,13 +24,12 @@ class nsOpenURIInFrameParams final : pub
   explicit nsOpenURIInFrameParams(
       const mozilla::OriginAttributes& aOriginAttributes, Element* aOpener);
 
  private:
   ~nsOpenURIInFrameParams();
 
   mozilla::OriginAttributes mOpenerOriginAttributes;
   RefPtr<Element> mOpenerBrowser;
-  nsString mReferrer;
-  uint32_t mReferrerPolicy;
+  nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   nsCOMPtr<nsIContentSecurityPolicy> mCsp;
 };
--- a/dom/interfaces/base/nsIBrowserDOMWindow.idl
+++ b/dom/interfaces/base/nsIBrowserDOMWindow.idl
@@ -5,23 +5,23 @@
 
 #include "nsISupports.idl"
 
 interface mozIDOMWindowProxy;
 interface nsIDOMWindow;
 interface nsIURI;
 interface nsIPrincipal;
 interface nsIContentSecurityPolicy;
+interface nsIReferrerInfo;
 webidl Element;
 
 [scriptable, uuid(e774db14-79ac-4156-a7a3-aa3fd0a22c10)]
 interface nsIOpenURIInFrameParams : nsISupports
 {
-  attribute AString referrer;
-  attribute unsigned long referrerPolicy;
+  attribute nsIReferrerInfo referrerInfo;
   readonly attribute boolean isPrivate;
   attribute nsIPrincipal triggeringPrincipal;
   attribute nsIContentSecurityPolicy csp;
 
   // The browser or frame element in the parent process which holds the
   // opener window in the content process. May be null.
   readonly attribute Element openerBrowser;
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -162,17 +162,17 @@
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsContentPermissionHelper.h"
 #include "nsPluginHost.h"
 #ifdef NS_PRINTING
 #  include "nsPrintingProxy.h"
 #endif
 #include "nsWindowMemoryReporter.h"
-#include "nsIReferrerInfo.h"
+#include "ReferrerInfo.h"
 
 #include "IHistory.h"
 #include "nsNetUtil.h"
 
 #include "base/message_loop.h"
 #include "base/process_util.h"
 #include "base/task.h"
 
@@ -753,29 +753,48 @@ ContentChild::ProvideWindow(mozIDOMWindo
                             nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
                             mozIDOMWindowProxy** aReturn) {
   return ProvideWindowCommon(nullptr, aParent, false, aChromeFlags,
                              aCalledFromJS, aPositionSpecified, aSizeSpecified,
                              aURI, aName, aFeatures, aForceNoOpener, aLoadState,
                              aWindowIsNew, aReturn);
 }
 
-static nsresult GetCreateWindowParams(
-    mozIDOMWindowProxy* aParent, nsDocShellLoadState* aLoadState,
-    nsACString& aBaseURIString, float* aFullZoom, uint32_t* aReferrerPolicy,
-    nsIPrincipal** aTriggeringPrincipal, nsIContentSecurityPolicy** aCsp) {
+static nsresult GetCreateWindowParams(mozIDOMWindowProxy* aParent,
+                                      nsDocShellLoadState* aLoadState,
+                                      float* aFullZoom,
+                                      nsIReferrerInfo** aReferrerInfo,
+                                      nsIPrincipal** aTriggeringPrincipal,
+                                      nsIContentSecurityPolicy** aCsp) {
   *aFullZoom = 1.0f;
   if (!aTriggeringPrincipal || !aCsp) {
     NS_ERROR("aTriggeringPrincipal || aCsp is null");
     return NS_ERROR_FAILURE;
   }
+
+  if (!aReferrerInfo) {
+    NS_ERROR("aReferrerInfo is null");
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIReferrerInfo> referrerInfo;
+  if (aLoadState) {
+    referrerInfo = aLoadState->GetReferrerInfo();
+  }
+
   auto* opener = nsPIDOMWindowOuter::From(aParent);
   if (!opener) {
     nsCOMPtr<nsIPrincipal> nullPrincipal =
         NullPrincipal::CreateWithoutOriginAttributes();
+    if (!referrerInfo) {
+      referrerInfo =
+          new ReferrerInfo(nullptr, mozilla::net::ReferrerPolicy::RP_Unset);
+    }
+
+    referrerInfo.swap(*aReferrerInfo);
     NS_ADDREF(*aTriggeringPrincipal = nullPrincipal);
     return NS_OK;
   }
 
   nsCOMPtr<Document> doc = opener->GetDoc();
   NS_ADDREF(*aTriggeringPrincipal = doc->NodePrincipal());
 
   // Currently we query the CSP from the doc->NodePrincipal(). After
@@ -787,26 +806,23 @@ static nsresult GetCreateWindowParams(
   }
 
   nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
   if (!baseURI) {
     NS_ERROR("Document didn't return a base URI");
     return NS_ERROR_FAILURE;
   }
 
-  baseURI->GetSpec(aBaseURIString);
-  if (aLoadState) {
-    nsCOMPtr<nsIReferrerInfo> referrerInfo = aLoadState->GetReferrerInfo();
-    if (referrerInfo && referrerInfo->GetSendReferrer()) {
-      referrerInfo->GetReferrerPolicy(aReferrerPolicy);
-    } else {
-      *aReferrerPolicy = mozilla::net::RP_No_Referrer;
-    }
+  if (!referrerInfo) {
+    referrerInfo =
+        new ReferrerInfo(doc->GetDocBaseURI(), doc->GetReferrerPolicy());
   }
 
+  referrerInfo.swap(*aReferrerInfo);
+
   RefPtr<nsDocShell> openerDocShell =
       static_cast<nsDocShell*>(opener->GetDocShell());
   if (!openerDocShell) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIContentViewer> cv;
   nsresult rv = openerDocShell->GetContentViewer(getter_AddRefs(cv));
@@ -858,34 +874,33 @@ nsresult ContentChild::ProvideWindowComm
       rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad);
       loadInDifferentProcess = NS_SUCCEEDED(rv) && !shouldLoad;
     }
   }
 
   // If we're in a content process and we have noopener set, there's no reason
   // to load in our process, so let's load it elsewhere!
   if (loadInDifferentProcess) {
-    nsAutoCString baseURIString;
     float fullZoom;
     nsCOMPtr<nsIPrincipal> triggeringPrincipal;
     nsCOMPtr<nsIContentSecurityPolicy> csp;
-    uint32_t referrerPolicy = mozilla::net::RP_Unset;
+    nsCOMPtr<nsIReferrerInfo> referrerInfo;
     rv = GetCreateWindowParams(
-        aParent, aLoadState, baseURIString, &fullZoom, &referrerPolicy,
+        aParent, aLoadState, &fullZoom, getter_AddRefs(referrerInfo),
         getter_AddRefs(triggeringPrincipal), getter_AddRefs(csp));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     Maybe<URIParams> uriToLoad;
     SerializeURI(aURI, uriToLoad);
     Unused << SendCreateWindowInDifferentProcess(
         aTabOpener, aChromeFlags, aCalledFromJS, aPositionSpecified,
-        aSizeSpecified, uriToLoad, features, baseURIString, fullZoom, name,
-        Principal(triggeringPrincipal), csp, referrerPolicy);
+        aSizeSpecified, uriToLoad, features, fullZoom, name,
+        Principal(triggeringPrincipal), csp, referrerInfo);
 
     // We return NS_ERROR_ABORT, so that the caller knows that we've abandoned
     // the window open as far as it is concerned.
     return NS_ERROR_ABORT;
   }
 
   if (aTabOpener) {
     PopupIPCTabContext context;
@@ -1064,38 +1079,36 @@ nsresult ContentChild::ProvideWindowComm
     }
 
     // NOTE: BrowserFrameOpenWindowPromise is the same type as
     // CreateWindowPromise, and this code depends on that fact.
     newChild->SendBrowserFrameOpenWindow(aTabOpener, NS_ConvertUTF8toUTF16(url),
                                          name, NS_ConvertUTF8toUTF16(features),
                                          std::move(resolve), std::move(reject));
   } else {
-    nsAutoCString baseURIString;
     float fullZoom;
     nsCOMPtr<nsIPrincipal> triggeringPrincipal;
     nsCOMPtr<nsIContentSecurityPolicy> csp;
-    uint32_t referrerPolicy = mozilla::net::RP_Unset;
+    nsCOMPtr<nsIReferrerInfo> referrerInfo;
     rv = GetCreateWindowParams(
-        aParent, aLoadState, baseURIString, &fullZoom, &referrerPolicy,
+        aParent, aLoadState, &fullZoom, getter_AddRefs(referrerInfo),
         getter_AddRefs(triggeringPrincipal), getter_AddRefs(csp));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     Maybe<URIParams> uriToLoad;
     if (aURI) {
       SerializeURI(aURI, uriToLoad);
     }
 
     SendCreateWindow(aTabOpener, newChild, aChromeFlags, aCalledFromJS,
                      aPositionSpecified, aSizeSpecified, uriToLoad, features,
-                     baseURIString, fullZoom, Principal(triggeringPrincipal),
-                     csp, referrerPolicy, std::move(resolve),
-                     std::move(reject));
+                     fullZoom, Principal(triggeringPrincipal), csp,
+                     referrerInfo, std::move(resolve), std::move(reject));
   }
 
   // =======================
   // Begin Nested Event Loop
   // =======================
 
   // We have to wait for a response from either SendCreateWindow or
   // SendBrowserFrameOpenWindow with information we're going to need to return
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -4689,21 +4689,21 @@ bool ContentParent::DeallocPWebBrowserPe
   delete aActor;
   return true;
 }
 
 mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
     PBrowserParent* aThisTab, bool aSetOpener, const uint32_t& aChromeFlags,
     const bool& aCalledFromJS, const bool& aPositionSpecified,
     const bool& aSizeSpecified, nsIURI* aURIToLoad, const nsCString& aFeatures,
-    const nsCString& aBaseURI, const float& aFullZoom,
-    uint64_t aNextTabParentId, const nsString& aName, nsresult& aResult,
-    nsCOMPtr<nsITabParent>& aNewTabParent, bool* aWindowIsNew,
-    int32_t& aOpenLocation, nsIPrincipal* aTriggeringPrincipal,
-    uint32_t aReferrerPolicy, bool aLoadURI, nsIContentSecurityPolicy* aCsp)
+    const float& aFullZoom, uint64_t aNextTabParentId, const nsString& aName,
+    nsresult& aResult, nsCOMPtr<nsITabParent>& aNewTabParent,
+    bool* aWindowIsNew, int32_t& aOpenLocation,
+    nsIPrincipal* aTriggeringPrincipal, nsIReferrerInfo* aReferrerInfo,
+    bool aLoadURI, nsIContentSecurityPolicy* aCsp)
 
 {
   // The content process should never be in charge of computing whether or
   // not a window should be private or remote - the parent will do that.
   const uint32_t badFlags = nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW |
                             nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW |
                             nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME |
                             nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
@@ -4773,20 +4773,19 @@ mozilla::ipc::IPCResult ContentParent::C
       aResult = NS_ERROR_ABORT;
       return IPC_OK();
     }
 
     RefPtr<Element> openerElement = do_QueryObject(frame);
 
     nsCOMPtr<nsIOpenURIInFrameParams> params =
         new nsOpenURIInFrameParams(openerOriginAttributes, openerElement);
-    params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
+    params->SetReferrerInfo(aReferrerInfo);
     MOZ_ASSERT(aTriggeringPrincipal, "need a valid triggeringPrincipal");
     params->SetTriggeringPrincipal(aTriggeringPrincipal);
-    params->SetReferrerPolicy(aReferrerPolicy);
     params->SetCsp(aCsp);
 
     RefPtr<Element> el;
 
     if (aLoadURI) {
       aResult = browserDOMWin->OpenURIInFrame(
           aURIToLoad, params, aOpenLocation, nsIBrowserDOMWindow::OPEN_NEW,
           aNextTabParentId, aName, getter_AddRefs(el));
@@ -4893,19 +4892,19 @@ mozilla::ipc::IPCResult ContentParent::C
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
     PBrowserParent* aThisTab, PBrowserParent* aNewTab,
     const uint32_t& aChromeFlags, const bool& aCalledFromJS,
     const bool& aPositionSpecified, const bool& aSizeSpecified,
     const Maybe<URIParams>& aURIToLoad, const nsCString& aFeatures,
-    const nsCString& aBaseURI, const float& aFullZoom,
-    const IPC::Principal& aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
-    const uint32_t& aReferrerPolicy, CreateWindowResolver&& aResolve) {
+    const float& aFullZoom, const IPC::Principal& aTriggeringPrincipal,
+    nsIContentSecurityPolicy* aCsp, nsIReferrerInfo* aReferrerInfo,
+    CreateWindowResolver&& aResolve) {
   nsresult rv = NS_OK;
   CreatedWindowInfo cwi;
 
   // We always expect to open a new window here. If we don't, it's an error.
   cwi.windowOpened() = true;
   cwi.maxTouchPoints() = 0;
   cwi.hasSiblings() = false;
 
@@ -4938,19 +4937,19 @@ mozilla::ipc::IPCResult ContentParent::R
   sNextTabParents.Put(nextTabParentId, newTab);
 
   const nsCOMPtr<nsIURI> uriToLoad = DeserializeURI(aURIToLoad);
 
   nsCOMPtr<nsITabParent> newRemoteTab;
   int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
   mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
       aThisTab, /* aSetOpener = */ true, aChromeFlags, aCalledFromJS,
-      aPositionSpecified, aSizeSpecified, uriToLoad, aFeatures, aBaseURI,
-      aFullZoom, nextTabParentId, VoidString(), rv, newRemoteTab,
-      &cwi.windowOpened(), openLocation, aTriggeringPrincipal, aReferrerPolicy,
+      aPositionSpecified, aSizeSpecified, uriToLoad, aFeatures, aFullZoom,
+      nextTabParentId, VoidString(), rv, newRemoteTab, &cwi.windowOpened(),
+      openLocation, aTriggeringPrincipal, aReferrerInfo,
       /* aLoadUri = */ false, aCsp);
   if (!ipcResult) {
     return ipcResult;
   }
 
   if (NS_WARN_IF(NS_FAILED(rv)) || !newRemoteTab) {
     return IPC_OK();
   }
@@ -4973,32 +4972,30 @@ mozilla::ipc::IPCResult ContentParent::R
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvCreateWindowInDifferentProcess(
     PBrowserParent* aThisTab, const uint32_t& aChromeFlags,
     const bool& aCalledFromJS, const bool& aPositionSpecified,
     const bool& aSizeSpecified, const Maybe<URIParams>& aURIToLoad,
-    const nsCString& aFeatures, const nsCString& aBaseURI,
-    const float& aFullZoom, const nsString& aName,
+    const nsCString& aFeatures, const float& aFullZoom, const nsString& aName,
     const IPC::Principal& aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
-    const uint32_t& aReferrerPolicy) {
+    nsIReferrerInfo* aReferrerInfo) {
   nsCOMPtr<nsITabParent> newRemoteTab;
   bool windowIsNew;
   nsCOMPtr<nsIURI> uriToLoad = DeserializeURI(aURIToLoad);
   int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
 
   nsresult rv;
   mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
       aThisTab, /* aSetOpener = */ false, aChromeFlags, aCalledFromJS,
-      aPositionSpecified, aSizeSpecified, uriToLoad, aFeatures, aBaseURI,
-      aFullZoom,
+      aPositionSpecified, aSizeSpecified, uriToLoad, aFeatures, aFullZoom,
       /* aNextTabParentId = */ 0, aName, rv, newRemoteTab, &windowIsNew,
-      openLocation, aTriggeringPrincipal, aReferrerPolicy,
+      openLocation, aTriggeringPrincipal, aReferrerInfo,
       /* aLoadUri = */ true, aCsp);
   if (!ipcResult) {
     return ipcResult;
   }
 
   if (NS_FAILED(rv)) {
     NS_WARNING("Call to CommonCreateWindow failed.");
   }
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -33,16 +33,17 @@
 #include "nsIInterfaceRequestor.h"
 #include "nsIObserver.h"
 #include "nsIThreadInternal.h"
 #include "nsIDOMGeoPositionCallback.h"
 #include "nsIDOMGeoPositionErrorCallback.h"
 #include "nsRefPtrHashtable.h"
 #include "PermissionMessageUtils.h"
 #include "DriverCrashGuard.h"
+#include "nsIReferrerInfo.h"
 
 #define CHILD_PROCESS_SHUTDOWN_MESSAGE \
   NS_LITERAL_STRING("child-process-shutdown")
 
 // These must match the similar ones in E10SUtils.jsm and ProcInfo.h.
 // Process names as reported by about:memory are defined in
 // ContentChild:RecvRemoteType.  Add your value there too or it will be called
 // "Web Content".
@@ -508,29 +509,27 @@ class ContentParent final : public PCont
 
   void ForkNewProcess(bool aBlocking);
 
   mozilla::ipc::IPCResult RecvCreateWindow(
       PBrowserParent* aThisTabParent, PBrowserParent* aNewTab,
       const uint32_t& aChromeFlags, const bool& aCalledFromJS,
       const bool& aPositionSpecified, const bool& aSizeSpecified,
       const Maybe<URIParams>& aURIToLoad, const nsCString& aFeatures,
-      const nsCString& aBaseURI, const float& aFullZoom,
-      const IPC::Principal& aTriggeringPrincipal,
-      nsIContentSecurityPolicy* aCsp, const uint32_t& aReferrerPolicy,
+      const float& aFullZoom, const IPC::Principal& aTriggeringPrincipal,
+      nsIContentSecurityPolicy* aCsp, nsIReferrerInfo* aReferrerInfo,
       CreateWindowResolver&& aResolve);
 
   mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess(
       PBrowserParent* aThisTab, const uint32_t& aChromeFlags,
       const bool& aCalledFromJS, const bool& aPositionSpecified,
       const bool& aSizeSpecified, const Maybe<URIParams>& aURIToLoad,
-      const nsCString& aFeatures, const nsCString& aBaseURI,
-      const float& aFullZoom, const nsString& aName,
+      const nsCString& aFeatures, const float& aFullZoom, const nsString& aName,
       const IPC::Principal& aTriggeringPrincipal,
-      nsIContentSecurityPolicy* aCsp, const uint32_t& aReferrerPolicy);
+      nsIContentSecurityPolicy* aCsp, nsIReferrerInfo* aReferrerInfo);
 
   static void BroadcastBlobURLRegistration(
       const nsACString& aURI, BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal,
       ContentParent* aIgnoreThisCP = nullptr);
 
   static void BroadcastBlobURLUnregistration(
       const nsACString& aURI, ContentParent* aIgnoreThisCP = nullptr);
 
@@ -658,22 +657,22 @@ class ContentParent final : public PCont
 
   // Set aLoadUri to true to load aURIToLoad and to false to only create the
   // window. aURIToLoad should always be provided, if available, to ensure
   // compatibility with GeckoView.
   mozilla::ipc::IPCResult CommonCreateWindow(
       PBrowserParent* aThisTab, bool aSetOpener, const uint32_t& aChromeFlags,
       const bool& aCalledFromJS, const bool& aPositionSpecified,
       const bool& aSizeSpecified, nsIURI* aURIToLoad,
-      const nsCString& aFeatures, const nsCString& aBaseURI,
-      const float& aFullZoom, uint64_t aNextTabParentId, const nsString& aName,
-      nsresult& aResult, nsCOMPtr<nsITabParent>& aNewTabParent,
-      bool* aWindowIsNew, int32_t& aOpenLocation,
-      nsIPrincipal* aTriggeringPrincipal, uint32_t aReferrerPolicy,
-      bool aLoadUri, nsIContentSecurityPolicy* aCsp);
+      const nsCString& aFeatures, const float& aFullZoom,
+      uint64_t aNextTabParentId, const nsString& aName, nsresult& aResult,
+      nsCOMPtr<nsITabParent>& aNewTabParent, bool* aWindowIsNew,
+      int32_t& aOpenLocation, nsIPrincipal* aTriggeringPrincipal,
+      nsIReferrerInfo* aReferrerInfo, bool aLoadUri,
+      nsIContentSecurityPolicy* aCsp);
 
   enum RecordReplayState { eNotRecordingOrReplaying, eRecording, eReplaying };
 
   explicit ContentParent(int32_t aPluginID)
       : ContentParent(nullptr, EmptyString(), eNotRecordingOrReplaying,
                       EmptyString(), aPluginID) {}
   ContentParent(ContentParent* aOpener, const nsAString& aRemoteType,
                 RecordReplayState aRecordReplayState = eNotRecordingOrReplaying,
--- a/dom/ipc/DOMTypes.ipdlh
+++ b/dom/ipc/DOMTypes.ipdlh
@@ -25,16 +25,17 @@ using CSSRect from "Units.h";
 using CSSSize from "Units.h";
 using mozilla::LayoutDeviceIntPoint from "Units.h";
 using hal::ScreenOrientation from "mozilla/HalScreenConfiguration.h";
 using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
 using refcounted class nsIPrincipal from "mozilla/dom/PermissionMessageUtils.h";
 using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
 using refcounted class nsIURI from "mozilla/ipc/URIUtils.h";
 using refcounted class nsIContentSecurityPolicy from "mozilla/dom/CSPMessageUtils.h";
+using refcounted class nsIReferrerInfo from "mozilla/dom/ReferrerInfoUtils.h";
 
 namespace mozilla {
 namespace dom {
 
 struct MessagePortIdentifier
 {
   nsID uuid;
   nsID destinationUuid;
@@ -192,31 +193,29 @@ struct WindowGlobalInit
   nsIPrincipal principal;
   BrowsingContext browsingContext;
   uint64_t innerWindowId;
   uint64_t outerWindowId;
 };
 
 struct DocShellLoadStateInit
 {
-  nsIURI Referrer;
   nsIURI URI;
   nsIURI OriginalURI;
   nsIURI ResultPrincipalURI;
   bool ResultPrincipalURIIsSome;
   nsIPrincipal TriggeringPrincipal;
+  nsIReferrerInfo ReferrerInfo;
   bool KeepResultPrincipalURIIfSet;
   bool LoadReplace;
   bool InheritPrincipal;
   bool PrincipalIsExplicit;
   nsIPrincipal PrincipalToInherit;
   bool ForceAllowDataURI;
   bool OriginalFrameSrc;
-  bool SendReferrer;
-  uint32_t ReferrerPolicy;
   uint32_t LoadType;
   nsString Target;
   nsIURI BaseURI;
   uint32_t LoadFlags;
   bool FirstParty;
   nsCString TypeHint;
   nsString FileName;
   bool IsFromProcessingFrameAttributes;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -1119,37 +1119,35 @@ parent:
     async CreateWindow(nullable PBrowser aThisTab,
                        PBrowser aNewTab,
                        uint32_t aChromeFlags,
                        bool aCalledFromJS,
                        bool aPositionSpecified,
                        bool aSizeSpecified,
                        URIParams? aURIToLoad,
                        nsCString aFeatures,
-                       nsCString aBaseURI,
                        float aFullZoom,
                        Principal aTriggeringPrincipal,
                        nsIContentSecurityPolicy aCsp,
-                       uint32_t aReferrerPolicy)
+                       nsIReferrerInfo aReferrerInfo)
         returns (CreatedWindowInfo window);
 
     async CreateWindowInDifferentProcess(
       PBrowser aThisTab,
       uint32_t aChromeFlags,
       bool aCalledFromJS,
       bool aPositionSpecified,
       bool aSizeSpecified,
       URIParams? aURIToLoad,
       nsCString aFeatures,
-      nsCString aBaseURI,
       float aFullZoom,
       nsString aName,
       Principal aTriggeringPrincipal,
       nsIContentSecurityPolicy aCsp,
-      uint32_t aReferrerPolicy);
+      nsIReferrerInfo aReferrerInfo);
 
     /**
      * Tells the parent to ungrab the pointer on the default display.
      *
      * This is for GTK platforms where we have to ensure the pointer ungrab happens in the
      * chrome process as that's the process that receives the pointer event.
      */
     sync UngrabPointer(uint32_t time);
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ReferrerInfoUtils.cpp
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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/dom/ReferrerInfoUtils.h"
+#include "nsISerializable.h"
+#include "nsSerializationHelper.h"
+
+namespace IPC {
+
+void ParamTraits<nsIReferrerInfo>::Write(Message* aMsg,
+                                         nsIReferrerInfo* aParam) {
+  bool isNull = !aParam;
+  WriteParam(aMsg, isNull);
+  if (isNull) {
+    return;
+  }
+  nsAutoCString infoString;
+  nsresult rv = NS_SerializeToString(aParam, infoString);
+  if (NS_FAILED(rv)) {
+    MOZ_CRASH("Unable to serialize referrer info.");
+    return;
+  }
+  WriteParam(aMsg, infoString);
+}
+
+bool ParamTraits<nsIReferrerInfo>::Read(const Message* aMsg,
+                                        PickleIterator* aIter,
+                                        RefPtr<nsIReferrerInfo>* aResult) {
+  bool isNull;
+  if (!ReadParam(aMsg, aIter, &isNull)) {
+    return false;
+  }
+  if (isNull) {
+    *aResult = nullptr;
+    return true;
+  }
+  nsAutoCString infoString;
+  if (!ReadParam(aMsg, aIter, &infoString)) {
+    return false;
+  }
+  nsCOMPtr<nsISupports> iSupports;
+  nsresult rv = NS_DeserializeObject(infoString, getter_AddRefs(iSupports));
+  NS_ENSURE_SUCCESS(rv, false);
+  nsCOMPtr<nsIReferrerInfo> referrerInfo = do_QueryInterface(iSupports);
+  NS_ENSURE_TRUE(referrerInfo, false);
+  *aResult = referrerInfo.forget();
+  return true;
+}
+
+}  // namespace IPC
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ReferrerInfoUtils.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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/. */
+
+#ifndef mozilla_dom_referrer_info_utils_h__
+#define mozilla_dom_referrer_info_utils_h__
+
+#include "ipc/IPCMessageUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIReferrerInfo.h"
+
+namespace IPC {
+
+template <>
+struct ParamTraits<nsIReferrerInfo> {
+  static void Write(Message* aMsg, nsIReferrerInfo* aParam);
+  static bool Read(const Message* aMsg, PickleIterator* aIter,
+                   RefPtr<nsIReferrerInfo>* aResult);
+};
+
+}  // namespace IPC
+
+#endif  // mozilla_dom_referrer_info_utils_h__
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -41,16 +41,17 @@ EXPORTS.mozilla.dom += [
     'CSPMessageUtils.h',
     'DocShellMessageUtils.h',
     'FilePickerParent.h',
     'JSWindowActorChild.h',
     'JSWindowActorParent.h',
     'JSWindowActorService.h',
     'MemoryReportRequest.h',
     'PermissionMessageUtils.h',
+    'ReferrerInfoUtils.h',
     'TabChild.h',
     'TabContext.h',
     'TabMessageUtils.h',
     'TabParent.h',
     'URLClassifierChild.h',
     'URLClassifierParent.h',
     'WindowGlobalChild.h',
     'WindowGlobalParent.h',
@@ -79,16 +80,17 @@ UNIFIED_SOURCES += [
     'JSWindowActorParent.cpp',
     'JSWindowActorService.cpp',
     'MemMapSnapshot.cpp',
     'MemoryReportRequest.cpp',
     'MMPrinter.cpp',
     'PermissionMessageUtils.cpp',
     'PreallocatedProcessManager.cpp',
     'ProcessPriorityManager.cpp',
+    'ReferrerInfoUtils.cpp',
     'SharedMap.cpp',
     'SharedStringMap.cpp',
     'StructuredCloneData.cpp',
     'TabChild.cpp',
     'TabContext.cpp',
     'TabMessageUtils.cpp',
     'TabParent.cpp',
     'URLClassifierParent.cpp',