Bug 1329032 - Extend loadURIWithOptions by a triggeringPrincipal. r=bz,gijs
authorChristoph Kerschbaumer <ckerschb@christophkerschbaumer.com>
Wed, 18 Jan 2017 08:24:55 +0100
changeset 374796 a385d2425a76099cf77d1dddbc24a0915dd02077
parent 374795 e6541dbce2b258674754bb28b35550d24334a78e
child 374797 5b544b8ab06b0d75bb3abb4095cceefeeebec525
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, gijs
bugs1329032
milestone53.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 1329032 - Extend loadURIWithOptions by a triggeringPrincipal. r=bz,gijs
browser/base/content/browser.js
browser/base/content/tab-content.js
browser/components/sessionstore/ContentRestore.jsm
browser/modules/E10SUtils.jsm
devtools/client/responsive.html/browser/web-navigation.js
docshell/base/nsDocShell.cpp
docshell/base/nsIWebNavigation.idl
docshell/shistory/nsSHistory.cpp
dom/base/nsContentUtils.cpp
toolkit/components/browser/nsIWebBrowserChrome3.idl
toolkit/components/browser/nsWebBrowser.cpp
toolkit/components/remotebrowserutils/RemoteWebNavigation.js
toolkit/content/browser-child.js
xpfe/appshell/nsContentTreeOwner.cpp
xpfe/appshell/nsIXULBrowserWindow.idl
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4361,31 +4361,31 @@ var XULBrowserWindow = {
   // Called before links are navigated to to allow us to retarget them if needed.
   onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) {
     let target = BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
     SocialUI.closeSocialPanelForLinkTraversal(target, linkNode);
     return target;
   },
 
   // Check whether this URI should load in the current process
-  shouldLoadURI(aDocShell, aURI, aReferrer) {
+  shouldLoadURI(aDocShell, aURI, aReferrer, aTriggeringPrincipal) {
     if (!gMultiProcessBrowser)
       return true;
 
     let browser = aDocShell.QueryInterface(Ci.nsIDocShellTreeItem)
                            .sameTypeRootTreeItem
                            .QueryInterface(Ci.nsIDocShell)
                            .chromeEventHandler;
 
     // Ignore loads that aren't in the main tabbrowser
     if (browser.localName != "browser" || !browser.getTabBrowser || browser.getTabBrowser() != gBrowser)
       return true;
 
     if (!E10SUtils.shouldLoadURI(aDocShell, aURI, aReferrer)) {
-      E10SUtils.redirectLoad(aDocShell, aURI, aReferrer);
+      E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, false);
       return false;
     }
 
     return true;
   },
 
   onProgressChange(aWebProgress, aRequest,
                              aCurSelfProgress, aMaxSelfProgress,
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -699,32 +699,32 @@ if (Services.appinfo.processType == Serv
 }
 
 var WebBrowserChrome = {
   onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) {
     return BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
   },
 
   // Check whether this URI should load in the current process
-  shouldLoadURI(aDocShell, aURI, aReferrer) {
+  shouldLoadURI(aDocShell, aURI, aReferrer, aTriggeringPrincipal) {
     if (!E10SUtils.shouldLoadURI(aDocShell, aURI, aReferrer)) {
-      E10SUtils.redirectLoad(aDocShell, aURI, aReferrer);
+      E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, false);
       return false;
     }
 
     return true;
   },
 
   shouldLoadURIInThisProcess(aURI) {
     return E10SUtils.shouldLoadURIInThisProcess(aURI);
   },
 
   // Try to reload the currently active or currently loading page in a new process.
-  reloadInFreshProcess(aDocShell, aURI, aReferrer) {
-    E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, true);
+  reloadInFreshProcess(aDocShell, aURI, aReferrer, aTriggeringPrincipal) {
+    E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, true);
     return true;
   },
 
   startPrerenderingDocument(aHref, aReferrer) {
     if (PrerenderContentHandler.initialized) {
       PrerenderContentHandler.startPrerenderingDocument(aHref, aReferrer);
     }
   },
--- a/browser/components/sessionstore/ContentRestore.jsm
+++ b/browser/components/sessionstore/ContentRestore.jsm
@@ -199,24 +199,27 @@ ContentRestoreInternal.prototype = {
         // same state it was before the load started then trigger the load.
         let referrer = loadArguments.referrer ?
                        Utils.makeURI(loadArguments.referrer) : null;
         let referrerPolicy = ('referrerPolicy' in loadArguments
             ? loadArguments.referrerPolicy
             : Ci.nsIHttpChannel.REFERRER_POLICY_UNSET);
         let postData = loadArguments.postData ?
                        Utils.makeInputStream(loadArguments.postData) : null;
+        let triggeringPrincipal = loadArguments.triggeringPrincipal
+                                  ? Utils.deserializePrincipal(loadArguments.triggeringPrincipal)
+                                  : null;
 
         if (loadArguments.userContextId) {
           webNavigation.setOriginAttributesBeforeLoading({ userContextId: loadArguments.userContextId });
         }
 
         webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags,
                                          referrer, referrerPolicy, postData,
-                                         null, null);
+                                         null, null, triggeringPrincipal);
       } else if (tabData.userTypedValue && tabData.userTypedClear) {
         // If the user typed a URL into the URL bar and hit enter right before
         // we crashed, we want to start loading that page again. A non-zero
         // userTypedClear value means that the load had started.
         // Load userTypedValue and fix up the URL if it's partial/broken.
         webNavigation.loadURI(tabData.userTypedValue,
                               Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP,
                               null, null, null);
--- a/browser/modules/E10SUtils.jsm
+++ b/browser/modules/E10SUtils.jsm
@@ -8,16 +8,18 @@ this.EXPORTED_SYMBOLS = ["E10SUtils"];
 
 const {interfaces: Ci, utils: Cu, classes: Cc} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyPreferenceGetter(this, "useRemoteWebExtensions",
                                       "extensions.webextensions.remote", false);
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+                                  "resource://gre/modules/sessionstore/Utils.jsm");
 
 function getAboutModule(aURL) {
   // Needs to match NS_GetAboutModuleName
   let moduleName = aURL.path.replace(/[#?].*/, "").toLowerCase();
   let contract = "@mozilla.org/network/protocol/about;1?what=" + moduleName;
   try {
     return Cc[contract].getService(Ci.nsIAboutModule);
   } catch (e) {
@@ -158,27 +160,30 @@ this.E10SUtils = {
     if (aDocShell.inFreshProcess && aDocShell.isOnlyToplevelInTabGroup) {
       return false;
     }
 
     // If the URI can be loaded in the current process then continue
     return this.shouldLoadURIInThisProcess(aURI);
   },
 
-  redirectLoad(aDocShell, aURI, aReferrer, aFreshProcess) {
+  redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, aFreshProcess) {
     // Retarget the load to the correct process
     let messageManager = aDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsIContentFrameMessageManager);
     let sessionHistory = aDocShell.getInterface(Ci.nsIWebNavigation).sessionHistory;
 
     messageManager.sendAsyncMessage("Browser:LoadURI", {
       loadOptions: {
         uri: aURI.spec,
         flags: Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
         referrer: aReferrer ? aReferrer.spec : null,
+        triggeringPrincipal: aTriggeringPrincipal
+                             ? Utils.serializePrincipal(aTriggeringPrincipal)
+                             : null,
         reloadInFreshProcess: !!aFreshProcess,
       },
       historyIndex: sessionHistory.requestedIndex,
     });
     return false;
   },
 
   wrapHandlingUserInput(aWindow, aIsHandling, aCallback) {
--- a/devtools/client/responsive.html/browser/web-navigation.js
+++ b/devtools/client/responsive.html/browser/web-navigation.js
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Ci, Cu, Cr } = require("chrome");
 const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
 const Services = require("Services");
 const { NetUtil } = require("resource://gre/modules/NetUtil.jsm");
+const { Utils } = require("resource://gre/modules/sessionstore/Utils.jsm");
 
 function readInputStreamToString(stream) {
   return NetUtil.readInputStreamToString(stream, stream.available());
 }
 
 /**
  * This object aims to provide the nsIWebNavigation interface for mozbrowser elements.
  * nsIWebNavigation is one of the interfaces expected on <xul:browser>s, so this wrapper
@@ -56,30 +57,33 @@ BrowserElementWebNavigation.prototype = 
     // No equivalent in the current BrowserElement API
     this._sendMessage("WebNavigation:GotoIndex", { index });
   },
 
   loadURI(uri, flags, referrer, postData, headers) {
     // No equivalent in the current BrowserElement API
     this.loadURIWithOptions(uri, flags, referrer,
                             Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
-                            postData, headers, null);
+                            postData, headers, null, null);
   },
 
   loadURIWithOptions(uri, flags, referrer, referrerPolicy, postData, headers,
-                     baseURI) {
+                     baseURI, triggeringPrincipal) {
     // No equivalent in the current BrowserElement API
     this._sendMessage("WebNavigation:LoadURI", {
       uri,
       flags,
       referrer: referrer ? referrer.spec : null,
       referrerPolicy: referrerPolicy,
       postData: postData ? readInputStreamToString(postData) : null,
       headers: headers ? readInputStreamToString(headers) : null,
       baseURI: baseURI ? baseURI.spec : null,
+      triggeringPrincipal: triggeringPrincipal
+                           ? Utils.serializePrincipal(triggeringPrincipal)
+                           : null,
     });
   },
 
   setOriginAttributesBeforeLoading(originAttributes) {
     // No equivalent in the current BrowserElement API
     this._sendMessage("WebNavigation:SetOriginAttributes", {
       originAttributes,
     });
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4693,27 +4693,28 @@ NS_IMETHODIMP
 nsDocShell::LoadURI(const char16_t* aURI,
                     uint32_t aLoadFlags,
                     nsIURI* aReferringURI,
                     nsIInputStream* aPostStream,
                     nsIInputStream* aHeaderStream)
 {
   return LoadURIWithOptions(aURI, aLoadFlags, aReferringURI,
                             mozilla::net::RP_Unset, aPostStream,
-                            aHeaderStream, nullptr);
+                            aHeaderStream, nullptr, nullptr);
 }
 
 NS_IMETHODIMP
 nsDocShell::LoadURIWithOptions(const char16_t* aURI,
                                uint32_t aLoadFlags,
                                nsIURI* aReferringURI,
                                uint32_t aReferrerPolicy,
                                nsIInputStream* aPostStream,
                                nsIInputStream* aHeaderStream,
-                               nsIURI* aBaseURI)
+                               nsIURI* aBaseURI,
+                               nsIPrincipal* aTriggeringPrincipal)
 {
   NS_ASSERTION((aLoadFlags & 0xf) == 0, "Unexpected flags");
 
   if (!IsNavigationAllowed()) {
     return NS_OK; // JS may not handle returning of an error code
   }
   nsCOMPtr<nsIURI> uri;
   nsCOMPtr<nsIInputStream> postStream(aPostStream);
@@ -4819,16 +4820,17 @@ nsDocShell::LoadURIWithOptions(const cha
   }
 
   loadInfo->SetLoadType(ConvertLoadTypeToDocShellLoadInfo(loadType));
   loadInfo->SetPostDataStream(postStream);
   loadInfo->SetReferrer(aReferringURI);
   loadInfo->SetReferrerPolicy(aReferrerPolicy);
   loadInfo->SetHeadersStream(aHeaderStream);
   loadInfo->SetBaseURI(aBaseURI);
+  loadInfo->SetTriggeringPrincipal(aTriggeringPrincipal);
 
   if (fixupInfo) {
     nsAutoString searchProvider, keyword;
     fixupInfo->GetKeywordProviderName(searchProvider);
     fixupInfo->GetKeywordAsSent(keyword);
     MaybeNotifyKeywordSearchLoading(searchProvider, keyword);
   }
 
@@ -10513,17 +10515,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
     // This ensures that the verifySignedContent flag is set on loadInfo in
     // DoURILoad.
     nsIURI* uriForShouldLoadCheck = aURI;
     if (IsAboutNewtab(aOriginalURI)) {
       uriForShouldLoadCheck = aOriginalURI;
     }
     bool shouldLoad;
     rv = browserChrome3->ShouldLoadURI(this, uriForShouldLoadCheck, aReferrer,
-                                       &shouldLoad);
+                                       aTriggeringPrincipal, &shouldLoad);
     if (NS_SUCCEEDED(rv) && !shouldLoad) {
       return NS_OK;
     }
   }
 
   if (browserChrome3 && aCheckForPrerender) {
     nsCOMPtr<nsIRunnable> ev =
       new InternalLoadEvent(this, aURI, aOriginalURI, aLoadReplace,
--- a/docshell/base/nsIWebNavigation.idl
+++ b/docshell/base/nsIWebNavigation.idl
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMDocument;
 interface nsIInputStream;
 interface nsISHistory;
 interface nsIURI;
+interface nsIPrincipal;
 
 /**
  * The nsIWebNavigation interface defines an interface for navigating the web.
  * It provides methods and attributes to direct an object to navigate to a new
  * location, stop or restart an in process load, or determine where the object
  * has previously gone.
  */
 [scriptable, uuid(3ade79d4-8cb9-4952-b18d-4f9b63ca0d31)]
@@ -277,24 +278,30 @@ interface nsIWebNavigation : nsISupports
    *        header stream is formatted as:
    *            ( HEADER "\r\n" )*
    *        This parameter is optional and may be null.
    * @param aBaseURI
    *        Set to indicate a base URI to be associated with the load. Note
    *        that at present this argument is only used with view-source aURIs
    *        and cannot be used to resolve aURI.
    *        This parameter is optional and may be null.
+   * @param aTriggeringPrincipal
+   *        The principal that initiated the load of aURI. If omitted docShell
+   *        tries to create a codeBasePrincipal from aReferrer if not null. If
+   *        aReferrer is also null docShell peforms a load using the
+   *        SystemPrincipal as the triggeringPrincipal.
    */
-  void loadURIWithOptions(in wstring        aURI,
-                          in unsigned long  aLoadFlags,
-                          in nsIURI         aReferrer,
-                          in unsigned long  aReferrerPolicy,
-                          in nsIInputStream aPostData,
-                          in nsIInputStream aHeaders,
-                          in nsIURI         aBaseURI);
+  void loadURIWithOptions(in wstring                  aURI,
+                          in unsigned long            aLoadFlags,
+                          in nsIURI                   aReferrer,
+                          in unsigned long            aReferrerPolicy,
+                          in nsIInputStream           aPostData,
+                          in nsIInputStream           aHeaders,
+                          in nsIURI                   aBaseURI,
+                          [optional] in nsIPrincipal  aTriggeringPrincipal);
 
   /**
    * Tells the Object to reload the current page.  There may be cases where the
    * user will be asked to confirm the reload (for example, when it is
    * determined that the request is non-idempotent).
    *
    * @param aReloadFlags
    *        Flags modifying load behaviour.  This parameter is a bitwise
--- a/docshell/shistory/nsSHistory.cpp
+++ b/docshell/shistory/nsSHistory.cpp
@@ -1613,17 +1613,18 @@ nsSHistory::GetSessionHistory(nsISHistor
 
 NS_IMETHODIMP
 nsSHistory::LoadURIWithOptions(const char16_t* aURI,
                                uint32_t aLoadFlags,
                                nsIURI* aReferringURI,
                                uint32_t aReferrerPolicy,
                                nsIInputStream* aPostStream,
                                nsIInputStream* aExtraHeaderStream,
-                               nsIURI* aBaseURI)
+                               nsIURI* aBaseURI,
+                               nsIPrincipal* aTriggeringPrincipal)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSHistory::SetOriginAttributesBeforeLoading(JS::HandleValue aOriginAttributes)
 {
   return NS_OK;
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -9771,19 +9771,23 @@ nsContentUtils::AttemptLargeAllocationLo
   rv = aChannel->GetURI(getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, false);
   NS_ENSURE_TRUE(uri, false);
 
   nsCOMPtr<nsIURI> referrer;
   rv = aChannel->GetReferrer(getter_AddRefs(referrer));
   NS_ENSURE_SUCCESS(rv, false);
 
+  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
+  nsCOMPtr<nsIPrincipal> triggeringPrincipal = loadInfo->TriggeringPrincipal();
+
   // Actually perform the cross process load
   bool reloadSucceeded = false;
-  rv = wbc3->ReloadInFreshProcess(docShell, uri, referrer, &reloadSucceeded);
+  rv = wbc3->ReloadInFreshProcess(docShell, uri, referrer,
+                                  triggeringPrincipal, &reloadSucceeded);
   NS_ENSURE_SUCCESS(rv, false);
 
   return reloadSucceeded;
 }
 
 /* static */ void
 nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
     nsIDocument* aDocument,
--- a/toolkit/components/browser/nsIWebBrowserChrome3.idl
+++ b/toolkit/components/browser/nsIWebBrowserChrome3.idl
@@ -4,16 +4,17 @@
 
 #include "nsIWebBrowserChrome2.idl"
 #include "nsIURI.idl"
 #include "nsIDOMNode.idl"
 
 interface nsIDocShell;
 interface nsIInputStream;
 interface nsIRunnable;
+interface nsIPrincipal;
 
 /**
  * nsIWebBrowserChrome3 is an extension to nsIWebBrowserChrome2.
  */
 [scriptable, uuid(542b6625-35a9-426a-8257-c12a345383b0)]
 interface nsIWebBrowserChrome3 : nsIWebBrowserChrome2
 {
   /**
@@ -39,33 +40,37 @@ interface nsIWebBrowserChrome3 : nsIWebB
    * Determines whether a load should continue.
    *
    * @param aDocShell
    *        The docshell performing the load.
    * @param aURI
    *        The URI being loaded.
    * @param aReferrer
    *        The referrer of the load.
+   * @param aTriggeringPrincipal
+   *        The principal that initiated the load of aURI.
    */
   bool shouldLoadURI(in nsIDocShell    aDocShell,
                      in nsIURI         aURI,
-                     in nsIURI         aReferrer);
+                     in nsIURI         aReferrer,
+                     in nsIPrincipal   aTriggeringPrincipal);
 
   bool shouldLoadURIInThisProcess(in nsIURI aURI);
 
   /**
    * Attempts to load the currently loaded page into a fresh process to increase
    * available memory.
    *
    * @param aDocShell
    *        The docshell performing the load.
    */
   bool reloadInFreshProcess(in nsIDocShell aDocShell,
                             in nsIURI aURI,
-                            in nsIURI aReferrer);
+                            in nsIURI aReferrer,
+                            in nsIPrincipal aTriggeringPrincipal);
 
   /**
    * Tell the browser to start prerendering the given document. This prerendering
    * _must_ be for the toplevel document.
    *
    * @param aHref The URI to begin prerendering
    * @param aReferrer The URI of the document requesting the prerender.
    */
--- a/toolkit/components/browser/nsWebBrowser.cpp
+++ b/toolkit/components/browser/nsWebBrowser.cpp
@@ -648,23 +648,24 @@ nsWebBrowser::GoForward()
 }
 
 NS_IMETHODIMP
 nsWebBrowser::LoadURIWithOptions(const char16_t* aURI, uint32_t aLoadFlags,
                                  nsIURI* aReferringURI,
                                  uint32_t aReferrerPolicy,
                                  nsIInputStream* aPostDataStream,
                                  nsIInputStream* aExtraHeaderStream,
-                                 nsIURI* aBaseURI)
+                                 nsIURI* aBaseURI,
+                                 nsIPrincipal* aTriggeringPrincipal)
 {
   NS_ENSURE_STATE(mDocShell);
 
   return mDocShellAsNav->LoadURIWithOptions(
     aURI, aLoadFlags, aReferringURI, aReferrerPolicy, aPostDataStream,
-    aExtraHeaderStream, aBaseURI);
+    aExtraHeaderStream, aBaseURI, aTriggeringPrincipal);
 }
 
 NS_IMETHODIMP
 nsWebBrowser::SetOriginAttributesBeforeLoading(JS::Handle<JS::Value> aOriginAttributes)
 {
   return mDocShellAsNav->SetOriginAttributesBeforeLoading(aOriginAttributes);
 }
 
--- a/toolkit/components/remotebrowserutils/RemoteWebNavigation.js
+++ b/toolkit/components/remotebrowserutils/RemoteWebNavigation.js
@@ -6,16 +6,18 @@
 const { interfaces: Ci, classes: Cc, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
   "resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
   "resource://gre/modules/NetUtil.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+  "resource://gre/modules/sessionstore/Utils.jsm");
 
 function makeURI(url) {
   return Services.io.newURI(url);
 }
 
 function readInputStreamToString(aStream) {
   return NetUtil.readInputStreamToString(aStream, aStream.available());
 }
@@ -68,25 +70,28 @@ RemoteWebNavigation.prototype = {
     this._sendMessage("WebNavigation:GotoIndex", {index: aIndex});
   },
   loadURI(aURI, aLoadFlags, aReferrer, aPostData, aHeaders) {
     this.loadURIWithOptions(aURI, aLoadFlags, aReferrer,
                             Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
                             aPostData, aHeaders, null);
   },
   loadURIWithOptions(aURI, aLoadFlags, aReferrer, aReferrerPolicy,
-                               aPostData, aHeaders, aBaseURI) {
+                     aPostData, aHeaders, aBaseURI, aTriggeringPrincipal) {
     this._sendMessage("WebNavigation:LoadURI", {
       uri: aURI,
       flags: aLoadFlags,
       referrer: aReferrer ? aReferrer.spec : null,
       referrerPolicy: aReferrerPolicy,
       postData: aPostData ? readInputStreamToString(aPostData) : null,
       headers: aHeaders ? readInputStreamToString(aHeaders) : null,
       baseURI: aBaseURI ? aBaseURI.spec : null,
+      triggeringPrincipal: aTriggeringPrincipal
+                           ? Utils.serializePrincipal(aTriggeringPrincipal)
+                           : null,
     });
   },
   setOriginAttributesBeforeLoading(aOriginAttributes) {
     this._sendMessage("WebNavigation:SetOriginAttributes", {
       originAttributes: aOriginAttributes,
     });
   },
   reload(aReloadFlags) {
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -12,16 +12,19 @@ Cu.import("resource://gre/modules/Browse
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/RemoteAddonsChild.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PageThumbUtils",
   "resource://gre/modules/PageThumbUtils.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+  "resource://gre/modules/sessionstore/Utils.jsm");
+
 if (AppConstants.MOZ_CRASHREPORTER) {
   XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
                                      "@mozilla.org/xre/app-info;1",
                                      "nsICrashReporter");
 }
 
 function makeInputStream(aString) {
   let stream = Cc["@mozilla.org/io/string-input-stream;1"].
@@ -264,17 +267,17 @@ var WebNavigation =  {
         break;
       case "WebNavigation:GotoIndex":
         this.gotoIndex(message.data.index);
         break;
       case "WebNavigation:LoadURI":
         this.loadURI(message.data.uri, message.data.flags,
                      message.data.referrer, message.data.referrerPolicy,
                      message.data.postData, message.data.headers,
-                     message.data.baseURI);
+                     message.data.baseURI, message.data.triggeringPrincipal);
         break;
       case "WebNavigation:SetOriginAttributes":
         this.setOriginAttributes(message.data.originAttributes);
         break;
       case "WebNavigation:Reload":
         this.reload(message.data.flags);
         break;
       case "WebNavigation:Stop":
@@ -304,17 +307,17 @@ var WebNavigation =  {
       this._wrapURIChangeCall(() => this.webNavigation.goForward());
     }
   },
 
   gotoIndex(index) {
     this._wrapURIChangeCall(() => this.webNavigation.gotoIndex(index));
   },
 
-  loadURI(uri, flags, referrer, referrerPolicy, postData, headers, baseURI) {
+  loadURI(uri, flags, referrer, referrerPolicy, postData, headers, baseURI, triggeringPrincipal) {
     if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) {
       let annotation = uri;
       try {
         let url = Services.io.newURI(uri);
         // If the current URI contains a username/password, remove it.
         url.userPass = "";
         annotation = url.spec;
       } catch (ex) { /* Ignore failures to parse and failures
@@ -324,19 +327,21 @@ var WebNavigation =  {
     if (referrer)
       referrer = Services.io.newURI(referrer);
     if (postData)
       postData = makeInputStream(postData);
     if (headers)
       headers = makeInputStream(headers);
     if (baseURI)
       baseURI = Services.io.newURI(baseURI);
+    if (triggeringPrincipal)
+      triggeringPrincipal = Utils.deserializePrincipal(triggeringPrincipal)
     this._wrapURIChangeCall(() => {
       return this.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
-                                                   postData, headers, baseURI);
+                                                   postData, headers, baseURI, triggeringPrincipal);
     });
   },
 
   setOriginAttributes(originAttributes) {
     if (originAttributes) {
       this.webNavigation.setOriginAttributesBeforeLoading(originAttributes);
     }
   },
--- a/xpfe/appshell/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/nsContentTreeOwner.cpp
@@ -386,41 +386,44 @@ NS_IMETHODIMP nsContentTreeOwner::OnBefo
   
   _retval = originalTarget;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsContentTreeOwner::ShouldLoadURI(nsIDocShell *aDocShell,
                                                 nsIURI *aURI,
                                                 nsIURI *aReferrer,
+                                                nsIPrincipal* aTriggeringPrincipal,
                                                 bool *_retval)
 {
   NS_ENSURE_STATE(mXULWindow);
 
   nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
   mXULWindow->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
 
   if (xulBrowserWindow)
-    return xulBrowserWindow->ShouldLoadURI(aDocShell, aURI, aReferrer, _retval);
+    return xulBrowserWindow->ShouldLoadURI(aDocShell, aURI, aReferrer,
+                                           aTriggeringPrincipal, _retval);
 
   *_retval = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsContentTreeOwner::ShouldLoadURIInThisProcess(nsIURI* aURI,
                                                              bool* aRetVal)
 {
   MOZ_ASSERT_UNREACHABLE("Should only be called in child process.");
   *aRetVal = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsContentTreeOwner::ReloadInFreshProcess(nsIDocShell* aDocShell,
                                                        nsIURI* aURI,
                                                        nsIURI* aReferrer,
+                                                       nsIPrincipal* aTriggeringPrincipal,
                                                        bool* aRetVal)
 {
   NS_WARNING("Cannot reload in fresh process from a nsContentTreeOwner!");
   *aRetVal = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsContentTreeOwner::StartPrerenderingDocument(nsIURI* aHref,
--- a/xpfe/appshell/nsIXULBrowserWindow.idl
+++ b/xpfe/appshell/nsIXULBrowserWindow.idl
@@ -9,16 +9,17 @@
 #include "nsIDOMNode.idl"
 
 interface nsIBrowser;
 interface nsIRequest;
 interface nsIDOMElement;
 interface nsIInputStream;
 interface nsIDocShell;
 interface nsITabParent;
+interface nsIPrincipal;
 interface mozIDOMWindowProxy;
 
 /**
  * The nsIXULBrowserWindow supplies the methods that may be called from the
  * internals of the browser area to tell the containing xul window to update
  * its ui. 
  */
 [scriptable, uuid(a8675fa9-c8b4-4350-9803-c38f344a9e38)]
@@ -55,20 +56,23 @@ interface nsIXULBrowserWindow : nsISuppo
    * Determines whether a load should continue.
    *
    * @param aDocShell
    *        The docshell performing the load.
    * @param aURI
    *        The URI being loaded.
    * @param aReferrer
    *        The referrer of the load.
+   * @param aTriggeringPrincipal
+   *        The principal that initiated the load of aURI.
    */
   bool shouldLoadURI(in nsIDocShell    aDocShell,
                      in nsIURI         aURI,
-                     in nsIURI         aReferrer);
+                     in nsIURI         aReferrer,
+                     in nsIPrincipal   aTriggeringPrincipal);
   /**
    * Show/hide a tooltip (when the user mouses over a link, say).
    */
   void showTooltip(in long x, in long y, in AString tooltip, in AString direction);
   void hideTooltip();
 
   /**
    * Return the number of tabs in this window.