Bug 1113431 - Propagate referrer policy throughout the UI: command-click and context menu open link in new tab/window. r=gijskruitbosch

This commit is contained in:
Alex Verstak 2015-03-04 23:29:55 -08:00
Родитель d0c9d91dc1
Коммит 673fbec87c
8 изменённых файлов: 162 добавлений и 34 удалений

Просмотреть файл

@ -827,10 +827,16 @@ function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
// A shared function used by both remote and non-remote browser XBL bindings to
// load a URI or redirect it to the correct process.
function _loadURIWithFlags(browser, uri, flags, referrer, charset, postdata) {
function _loadURIWithFlags(browser, uri, params) {
if (!uri) {
uri = "about:blank";
}
let flags = params.flags || 0;
let referrer = params.referrerURI;
let referrerPolicy = ('referrerPolicy' in params ? params.referrerPolicy :
Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
let charset = params.charset;
let postdata = params.postData;
if (!(flags & browser.webNavigation.LOAD_FLAGS_FROM_EXTERNAL)) {
browser.userTypedClear++;
@ -842,12 +848,15 @@ function _loadURIWithFlags(browser, uri, flags, referrer, charset, postdata) {
!E10SUtils.canLoadURIInProcess(uri, process);
try {
if (!mustChangeProcess) {
browser.webNavigation.loadURI(uri, flags, referrer, postdata, null);
browser.webNavigation.loadURIWithOptions(uri, flags,
referrer, referrerPolicy,
postdata, null, null);
} else {
LoadInOtherProcess(browser, {
uri: uri,
flags: flags,
referrer: referrer ? referrer.spec : null,
referrerPolicy: referrerPolicy,
});
}
} catch (e) {
@ -856,7 +865,8 @@ function _loadURIWithFlags(browser, uri, flags, referrer, charset, postdata) {
// This might be necessary if SessionStore wasn't initialized yet i.e.
// when the homepage is a non-remote page.
gBrowser.updateBrowserRemotenessByURL(browser, uri);
browser.webNavigation.loadURI(uri, flags, referrer, postdata, null);
browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
postdata, null, null);
} finally {
if (browser.userTypedClear) {
browser.userTypedClear--;
@ -1177,12 +1187,23 @@ var gBrowserInit = {
Cu.reportError(e);
}
}
// window.arguments[2]: referrer (nsIURI)
// window.arguments[2]: referrer (nsIURI | string)
// [3]: postData (nsIInputStream)
// [4]: allowThirdPartyFixup (bool)
// [5]: referrerPolicy (int)
else if (window.arguments.length >= 3) {
loadURI(uriToLoad, window.arguments[2], window.arguments[3] || null,
window.arguments[4] || false);
let referrerURI = window.arguments[2];
if (typeof(referrerURI) == "string") {
try {
referrerURI = makeURI(referrerURI);
} catch (e) {
referrerURI = null;
}
}
let referrerPolicy = (window.arguments[5] != undefined ?
window.arguments[5] : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
loadURI(uriToLoad, referrerURI, window.arguments[3] || null,
window.arguments[4] || false, referrerPolicy);
window.focus();
}
// Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
@ -2065,10 +2086,11 @@ function BrowserTryToCloseWindow()
window.close(); // WindowIsClosing does all the necessary checks
}
function loadURI(uri, referrer, postData, allowThirdPartyFixup) {
function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy) {
try {
openLinkIn(uri, "current",
{ referrerURI: referrer,
referrerPolicy: referrerPolicy,
postData: postData,
allowThirdPartyFixup: allowThirdPartyFixup });
} catch (e) {}
@ -4601,7 +4623,8 @@ function nsBrowserAccess() { }
nsBrowserAccess.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]),
_openURIInNewTab: function(aURI, aReferrer, aIsPrivate, aIsExternal, aForceNotRemote=false) {
_openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
aIsExternal, aForceNotRemote=false) {
let win, needToFocusWin;
// try the current window. if we're in a popup, fall back on the most recent browser window
@ -4627,6 +4650,7 @@ nsBrowserAccess.prototype = {
let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
referrerURI: aReferrer,
referrerPolicy: aReferrerPolicy,
fromExternal: aIsExternal,
inBackground: loadInBackground,
forceNotRemote: aForceNotRemote});
@ -4668,7 +4692,14 @@ nsBrowserAccess.prototype = {
else
aWhere = gPrefService.getIntPref("browser.link.open_newwindow");
}
let referrer = aOpener ? makeURI(aOpener.location.href) : null;
let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT;
if (aOpener && aOpener.document) {
referrerPolicy = aOpener.document.referrerPolicy;
}
let isPrivate = PrivateBrowsingUtils.isWindowPrivate(aOpener || window);
switch (aWhere) {
case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW :
// FIXME: Bug 408379. So how come this doesn't send the
@ -4683,7 +4714,6 @@ nsBrowserAccess.prototype = {
newWindow = openDialog(getBrowserURL(), "_blank", features, url, null, null, null);
break;
case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB :
let referrer = aOpener ? makeURI(aOpener.location.href) : null;
// If we have an opener, that means that the caller is expecting access
// to the nsIDOMWindow of the opened tab right away. For e10s windows,
// this means forcing the newly opened browser to be non-remote so that
@ -4691,18 +4721,23 @@ nsBrowserAccess.prototype = {
// will do the job of shuttling off the newly opened browser to run in
// the right process once it starts loading a URI.
let forceNotRemote = !!aOpener;
let browser = this._openURIInNewTab(aURI, referrer, isPrivate, isExternal, forceNotRemote);
let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
isPrivate, isExternal,
forceNotRemote);
if (browser)
newWindow = browser.contentWindow;
break;
default : // OPEN_CURRENTWINDOW or an illegal value
newWindow = content;
if (aURI) {
let referrer = aOpener ? makeURI(aOpener.location.href) : null;
let loadflags = isExternal ?
Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
gBrowser.loadURIWithFlags(aURI.spec, loadflags, referrer, null, null);
gBrowser.loadURIWithFlags(aURI.spec, {
flags: loadflags,
referrerURI: referrer,
referrerPolicy: referrerPolicy,
});
}
if (!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
window.focus();
@ -4717,7 +4752,9 @@ nsBrowserAccess.prototype = {
}
var isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
let browser = this._openURIInNewTab(aURI, aParams.referrer, aParams.isPrivate, isExternal);
let browser = this._openURIInNewTab(aURI, aParams.referrer,
aParams.referrerPolicy,
aParams.isPrivate, isExternal);
if (browser)
return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
@ -5531,6 +5568,7 @@ function handleLinkClick(event, href, linkNode) {
let params = { charset: doc.characterSet,
allowMixedContent: persistAllowMixedContentInChildTab,
referrerURI: referrerURI,
referrerPolicy: doc.referrerPolicy,
noReferrer: BrowserUtils.linkHasNoReferrer(linkNode) };
openLinkIn(href, where, params);
event.preventDefault();

Просмотреть файл

@ -163,6 +163,7 @@ let handleContentContextMenu = function (event) {
let charSet = doc.characterSet;
let baseURI = doc.baseURI;
let referrer = doc.referrer;
let referrerPolicy = doc.referrerPolicy;
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
let editFlags = SpellCheckHelper.isEditable(event.target, content);
@ -177,7 +178,8 @@ let handleContentContextMenu = function (event) {
let principal = doc.nodePrincipal;
sendSyncMessage("contextmenu",
{ editFlags, spellInfo, customMenuItems, addonInfo,
principal, docLocation, charSet, baseURI, referrer },
principal, docLocation, charSet, baseURI, referrer,
referrerPolicy },
{ event, popupNode: event.target });
}
else {
@ -194,6 +196,7 @@ let handleContentContextMenu = function (event) {
docLocation: docLocation,
charSet: charSet,
referrer: referrer,
referrerPolicy: referrerPolicy,
};
}
}
@ -658,7 +661,7 @@ let ClickEventHandler = {
let json = { button: event.button, shiftKey: event.shiftKey,
ctrlKey: event.ctrlKey, metaKey: event.metaKey,
altKey: event.altKey, href: null, title: null,
bookmark: false };
bookmark: false, referrerPolicy: ownerDoc.referrerPolicy };
if (href) {
json.href = href;

Просмотреть файл

@ -870,6 +870,7 @@ nsContextMenu.prototype = {
_openLinkInParameters : function (extra) {
let params = { charset: gContextMenuContentData.charSet,
referrerURI: gContextMenuContentData.documentURIObject,
referrerPolicy: gContextMenuContentData.referrerPolicy,
noReferrer: this.linkHasNoReferrer };
for (let p in extra)
params[p] = extra[p];

Просмотреть файл

@ -1374,6 +1374,7 @@
<parameter name="aAllowThirdPartyFixup"/>
<body>
<![CDATA[
var aReferrerPolicy;
var aFromExternal;
var aRelatedToCurrent;
var aAllowMixedContent;
@ -1385,6 +1386,7 @@
!(arguments[1] instanceof Ci.nsIURI)) {
let params = arguments[1];
aReferrerURI = params.referrerURI;
aReferrerPolicy = params.referrerPolicy;
aCharset = params.charset;
aPostData = params.postData;
aLoadInBackground = params.inBackground;
@ -1402,6 +1404,7 @@
var owner = bgLoad ? null : this.selectedTab;
var tab = this.addTab(aURI, {
referrerURI: aReferrerURI,
referrerPolicy: aReferrerPolicy,
charset: aCharset,
postData: aPostData,
ownerTab: owner,
@ -1686,6 +1689,7 @@
<body>
<![CDATA[
const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var aReferrerPolicy;
var aFromExternal;
var aRelatedToCurrent;
var aSkipAnimation;
@ -1697,6 +1701,7 @@
!(arguments[1] instanceof Ci.nsIURI)) {
let params = arguments[1];
aReferrerURI = params.referrerURI;
aReferrerPolicy = params.referrerPolicy;
aCharset = params.charset;
aPostData = params.postData;
aOwner = params.ownerTab;
@ -1850,9 +1855,13 @@
if (aAllowMixedContent)
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT;
try {
b.loadURIWithFlags(aURI, flags,
aNoReferrer ? null : aReferrerURI,
aCharset, aPostData);
b.loadURIWithFlags(aURI, {
flags: flags,
referrerURI: aNoReferrer ? null: aReferrerURI,
referrerPolicy: aReferrerPolicy,
charset: aCharset,
postData: aPostData,
});
} catch (ex) {
Cu.reportError(ex);
}
@ -2929,6 +2938,11 @@
<parameter name="aPostData"/>
<body>
<![CDATA[
// Note - the callee understands both:
// (a) loadURIWithFlags(aURI, aFlags, ...)
// (b) loadURIWithFlags(aURI, { flags: aFlags, ... })
// Forwarding it as (a) here actually supports both (a) and (b),
// so you can call us either way too.
return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData);
]]>
</body>
@ -3227,7 +3241,9 @@
documentURIObject: documentURIObject,
docLocation: aMessage.data.docLocation,
charSet: aMessage.data.charSet,
referrer: aMessage.data.referrer };
referrer: aMessage.data.referrer,
referrerPolicy: aMessage.data.referrerPolicy,
};
let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
let event = gContextMenuContentData.event;
let pos = browser.mapScreenCoordinatesFromContent(event.screenX, event.screenY);
@ -5551,7 +5567,16 @@
<parameter name="aPostData"/>
<body>
<![CDATA[
_loadURIWithFlags(this, aURI, aFlags, aReferrerURI, aCharset, aPostData);
var params = arguments[1];
if (typeof(params) == "number") {
params = {
flags: aFlags,
referrerURI: aReferrerURI,
charset: aCharset,
postData: aPostData,
};
}
_loadURIWithFlags(this, aURI, params);
]]>
</body>
</method>
@ -5570,7 +5595,16 @@
<parameter name="aPostData"/>
<body>
<![CDATA[
_loadURIWithFlags(this, aURI, aFlags, aReferrerURI, aCharset, aPostData);
var params = arguments[1];
if (typeof(params) == "number") {
params = {
flags: aFlags,
referrerURI: aReferrerURI,
charset: aCharset,
postData: aPostData,
};
}
_loadURIWithFlags(this, aURI, params);
]]>
</body>
</method>

Просмотреть файл

@ -103,7 +103,8 @@ function openUILink(url, event, aIgnoreButton, aIgnoreAlt, aAllowThirdPartyFixup
allowThirdPartyFixup: aAllowThirdPartyFixup,
postData: aPostData,
referrerURI: aReferrerURI,
initiatingDoc: event ? event.target.ownerDocument : null
referrerPolicy: Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
initiatingDoc: event ? event.target.ownerDocument : null,
};
}
@ -197,7 +198,8 @@ function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI
params = {
allowThirdPartyFixup: aAllowThirdPartyFixup,
postData: aPostData,
referrerURI: aReferrerURI
referrerURI: aReferrerURI,
referrerPolicy: Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
};
}
@ -209,12 +211,16 @@ function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI
function openLinkIn(url, where, params) {
if (!where || !url)
return;
const Cc = Components.classes;
const Ci = Components.interfaces;
var aFromChrome = params.fromChrome;
var aAllowThirdPartyFixup = params.allowThirdPartyFixup;
var aPostData = params.postData;
var aCharset = params.charset;
var aReferrerURI = params.referrerURI;
var aReferrerPolicy = ('referrerPolicy' in params ?
params.referrerPolicy : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
var aRelatedToCurrent = params.relatedToCurrent;
var aAllowMixedContent = params.allowMixedContent;
var aInBackground = params.inBackground;
@ -231,11 +237,10 @@ function openLinkIn(url, where, params) {
"where == 'save' but without initiatingDoc. See bug 814264.");
return;
}
// TODO(1073187): propagate referrerPolicy.
saveURL(url, null, null, true, null, aNoReferrer ? null : aReferrerURI, aInitiatingDoc);
return;
}
const Cc = Components.classes;
const Ci = Components.interfaces;
var w = getTopWin();
if ((where == "tab" || where == "tabshifted") &&
@ -245,6 +250,7 @@ function openLinkIn(url, where, params) {
}
if (!w || where == "window") {
// This propagates to window.arguments.
var sa = Cc["@mozilla.org/supports-array;1"].
createInstance(Ci.nsISupportsArray);
@ -263,11 +269,23 @@ function openLinkIn(url, where, params) {
createInstance(Ci.nsISupportsPRBool);
allowThirdPartyFixupSupports.data = aAllowThirdPartyFixup;
var referrerURISupports = null;
if (aReferrerURI && !aNoReferrer) {
referrerURISupports = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
referrerURISupports.data = aReferrerURI.spec;
}
var referrerPolicySupports = Cc["@mozilla.org/supports-PRUint32;1"].
createInstance(Ci.nsISupportsPRUint32);
referrerPolicySupports.data = aReferrerPolicy;
sa.AppendElement(wuri);
sa.AppendElement(charset);
sa.AppendElement(aNoReferrer ? null : aReferrerURI);
sa.AppendElement(referrerURISupports);
sa.AppendElement(aPostData);
sa.AppendElement(allowThirdPartyFixupSupports);
sa.AppendElement(referrerPolicySupports);
let features = "chrome,dialog=no,all";
if (aIsPrivate) {
@ -327,7 +345,12 @@ function openLinkIn(url, where, params) {
if (aDisallowInheritPrincipal && !(uriObj && uriObj.schemeIs("javascript")))
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
w.gBrowser.loadURIWithFlags(url, flags, aNoReferrer ? null : aReferrerURI, null, aPostData);
w.gBrowser.loadURIWithFlags(url, {
flags: flags,
referrerURI: aNoReferrer ? null : aReferrerURI,
referrerPolicy: aReferrerPolicy,
postData: aPostData,
});
break;
case "tabshifted":
loadInBackground = !loadInBackground;
@ -335,6 +358,7 @@ function openLinkIn(url, where, params) {
case "tab":
w.gBrowser.loadOneTab(url, {
referrerURI: aReferrerURI,
referrerPolicy: aReferrerPolicy,
charset: aCharset,
postData: aPostData,
inBackground: loadInBackground,
@ -661,9 +685,11 @@ function makeURLAbsolute(aBase, aUrl)
* be undefined in which case it is treated as false.
* @param [optional] aReferrer
* This will be used as the referrer. There will be no security check.
* @param [optional] aReferrerPolicy
* Referrer policy - Ci.nsIHttpChannel.REFERRER_POLICY_*.
*/
function openNewTabWith(aURL, aDocument, aPostData, aEvent,
aAllowThirdPartyFixup, aReferrer) {
aAllowThirdPartyFixup, aReferrer, aReferrerPolicy) {
// As in openNewWindowWith(), we want to pass the charset of the
// current document over to a new tab.
@ -675,14 +701,17 @@ function openNewTabWith(aURL, aDocument, aPostData, aEvent,
{ charset: originCharset,
postData: aPostData,
allowThirdPartyFixup: aAllowThirdPartyFixup,
referrerURI: aReferrer });
referrerURI: aReferrer,
referrerPolicy: aReferrerPolicy,
});
}
/**
* @param aDocument
* Note this parameter is ignored. See openNewTabWith()
*/
function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup, aReferrer) {
function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup,
aReferrer, aReferrerPolicy) {
// Extract the current charset menu setting from the current document and
// use it to initialize the new browser window...
let originCharset = null;
@ -693,7 +722,9 @@ function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup, aR
{ charset: originCharset,
postData: aPostData,
allowThirdPartyFixup: aAllowThirdPartyFixup,
referrerURI: aReferrer });
referrerURI: aReferrer,
referrerPolicy: aReferrerPolicy,
});
}
// aCalledFromModal is optional

Просмотреть файл

@ -205,8 +205,12 @@ ContentRestoreInternal.prototype = {
}
let referrer = loadArguments.referrer ?
Utils.makeURI(loadArguments.referrer) : null;
webNavigation.loadURI(loadArguments.uri, loadArguments.flags,
referrer, null, null);
let referrerPolicy = ('referrerPolicy' in loadArguments
? loadArguments.referrerPolicy
: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags,
referrer, referrerPolicy, null, null,
null);
} 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

Просмотреть файл

@ -70,6 +70,7 @@ let ContentClick = {
let params = { charset: browser.characterSet,
referrerURI: browser.documentURI,
referrerPolicy: json.referrerPolicy,
noReferrer: json.noReferrer };
window.openLinkIn(json.href, where, params);

Просмотреть файл

@ -133,11 +133,27 @@
if (!aURI)
aURI = "about:blank";
var aReferrerPolicy = Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT;
// Check for loadURIWithFlags(uri, { ... });
var params = arguments[1];
if (params && typeof(params) == "object") {
aFlags = params.flags;
aReferrerURI = params.referrerURI;
if ('referrerPolicy' in params) {
aReferrerPolicy = params.referrerPolicy;
}
aCharset = params.charset;
aPostData = params.postData;
}
if (!(aFlags & this.webNavigation.LOAD_FLAGS_FROM_EXTERNAL))
this.userTypedClear++;
try {
this.webNavigation.loadURI(aURI, aFlags, aReferrerURI, aPostData, null);
this.webNavigation.loadURIWithOptions(
aURI, aFlags, aReferrerURI, aReferrerPolicy,
aPostData, null, null);
} finally {
if (this.userTypedClear)
this.userTypedClear--;