зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1521808 - Implement process switching based on Cross-Opener-Origin-Policy header r=nika,qdot
* New topLevel loads get the nsILoadInfo.openerPolicy of the current top level document * Parsing the Cross-Opener-Origin-Policy of a channel will update mLoadInfo.openerPolicy and this value will get propagated to the child process. * SessionStore now checks nsIHttpChannel.hasCrossOriginOpenerPolicyMismatch (preffed off) and performs a process switch if needed Differential Revision: https://phabricator.services.mozilla.com/D19000 --HG-- rename : toolkit/components/remotebrowserutils/tests/browser/browser_httpResponseProcessSelection.js => toolkit/components/remotebrowserutils/tests/browser/browser_httpCrossOriginOpenerPolicy.js extra : moz-landing-system : lando
This commit is contained in:
Родитель
646e6529a2
Коммит
3d45f28bb0
|
@ -2315,7 +2315,8 @@ var SessionStoreInternal = {
|
|||
// Examine the channel response to see if we should change the process
|
||||
// performing the given load.
|
||||
onMayChangeProcess(aChannel) {
|
||||
if (!E10SUtils.useHttpResponseProcessSelection()) {
|
||||
if (!E10SUtils.useHttpResponseProcessSelection() &&
|
||||
!E10SUtils.useCrossOriginOpenerPolicy()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2370,6 +2371,7 @@ var SessionStoreInternal = {
|
|||
let browser = tabParent.ownerElement;
|
||||
if (!browser) {
|
||||
debug(`[process-switch]: TabParent has no ownerElement - ignoring`);
|
||||
return;
|
||||
}
|
||||
|
||||
let tabbrowser = browser.ownerGlobal.gBrowser;
|
||||
|
@ -2391,7 +2393,9 @@ var SessionStoreInternal = {
|
|||
true,
|
||||
browser.remoteType,
|
||||
currentPrincipal);
|
||||
if (browser.remoteType == remoteType) {
|
||||
if (browser.remoteType == remoteType &&
|
||||
(!E10SUtils.useCrossOriginOpenerPolicy() ||
|
||||
!aChannel.hasCrossOriginOpenerPolicyMismatch())) {
|
||||
debug(`[process-switch]: type (${remoteType}) is compatible - ignoring`);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9805,8 +9805,6 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
|
|||
securityFlags |= nsILoadInfo::SEC_SANDBOXED;
|
||||
}
|
||||
|
||||
// TODO: pass openerPolicy through loadInfo?
|
||||
|
||||
RefPtr<LoadInfo> loadInfo =
|
||||
(contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT)
|
||||
? new LoadInfo(loadingWindow, aLoadState->TriggeringPrincipal(),
|
||||
|
@ -9830,6 +9828,12 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
|
|||
(contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||
GetIsMozBrowser());
|
||||
|
||||
if (isTopLevelDoc && GetDocument() && GetDocument()->GetChannel()) {
|
||||
nsCOMPtr<nsILoadInfo> oldLoadInfo =
|
||||
GetDocument()->GetChannel()->GetLoadInfo();
|
||||
loadInfo->SetOpenerPolicy(oldLoadInfo->GetOpenerPolicy());
|
||||
}
|
||||
|
||||
OriginAttributes attrs;
|
||||
|
||||
// Inherit origin attributes from PrincipalToInherit if inheritAttrs is
|
||||
|
|
|
@ -715,7 +715,8 @@ nsresult MergeParentLoadInfoForwarder(
|
|||
aLoadInfo->MaybeIncreaseTainting(aForwarderArgs.tainting());
|
||||
}
|
||||
|
||||
// TODO: merge openerPolicy
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
aLoadInfo->SetOpenerPolicy(aForwarderArgs.openerPolicy()));
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetDocumentHasUserInteracted(
|
||||
aForwarderArgs.documentHasUserInteracted()));
|
||||
|
|
|
@ -7257,6 +7257,8 @@ nsHttpChannel::HasCrossOriginOpenerPolicyMismatch(bool *aMismatch) {
|
|||
nsILoadInfo::CrossOriginOpenerPolicy resultPolicy =
|
||||
GetCrossOriginOpenerPolicy(head);
|
||||
|
||||
mLoadInfo->SetOpenerPolicy(resultPolicy);
|
||||
|
||||
// We use the top window principal as the documentOrigin
|
||||
if (!mTopWindowPrincipal) {
|
||||
GetTopWindowPrincipal(getter_AddRefs(mTopWindowPrincipal));
|
||||
|
|
|
@ -5,7 +5,9 @@ support-files =
|
|||
print_postdata.sjs
|
||||
307redirect.sjs
|
||||
head.js
|
||||
coop_header.sjs
|
||||
|
||||
[browser_RemoteWebNavigation.js]
|
||||
[browser_httpResponseProcessSelection.js]
|
||||
[browser_httpCrossOriginOpenerPolicy.js]
|
||||
[browser_httpToFileHistory.js]
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
||||
"use strict";
|
||||
|
||||
const {E10SUtils} = ChromeUtils.import("resource://gre/modules/E10SUtils.jsm");
|
||||
|
||||
const PREF_NAME = "browser.tabs.remote.useCrossOriginOpenerPolicy";
|
||||
|
||||
function httpURL(filename, host = "https://example.com") {
|
||||
let root = getRootDirectory(gTestPath)
|
||||
.replace("chrome://mochitests/content", host);
|
||||
return root + filename;
|
||||
}
|
||||
|
||||
async function performLoad(browser, opts, action) {
|
||||
let loadedPromise = BrowserTestUtils.browserStopped(
|
||||
browser, opts.url, opts.maybeErrorPage);
|
||||
await action();
|
||||
await loadedPromise;
|
||||
}
|
||||
|
||||
async function test_coop(start, target, expectedProcessSwitch) {
|
||||
return BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: start,
|
||||
waitForStateStop: true,
|
||||
}, async function(_browser) {
|
||||
info(`Test tab ready: ${start}`);
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 20));
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let firstProcessID = await ContentTask.spawn(browser, null, () => {
|
||||
return Services.appinfo.processID;
|
||||
});
|
||||
|
||||
info(`firstProcessID: ${firstProcessID}`);
|
||||
|
||||
await performLoad(browser, {
|
||||
url: target,
|
||||
maybeErrorPage: false,
|
||||
}, async () => {
|
||||
BrowserTestUtils.loadURI(browser, target);
|
||||
if (expectedProcessSwitch) {
|
||||
await BrowserTestUtils.waitForEvent(gBrowser.getTabForBrowser(browser), "SSTabRestored");
|
||||
}
|
||||
});
|
||||
|
||||
info(`Navigated to: ${target}`);
|
||||
await new Promise(resolve => setTimeout(resolve, 20));
|
||||
browser = gBrowser.selectedBrowser;
|
||||
let secondProcessID = await ContentTask.spawn(browser, null, () => {
|
||||
return Services.appinfo.processID;
|
||||
});
|
||||
|
||||
info(`secondProcessID: ${secondProcessID}`);
|
||||
if (expectedProcessSwitch) {
|
||||
Assert.notEqual(firstProcessID, secondProcessID, `from: ${start} to ${target}`);
|
||||
} else {
|
||||
Assert.equal(firstProcessID, secondProcessID, `from: ${start} to ${target}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function test_disabled() {
|
||||
await SpecialPowers.pushPrefEnv({set: [[PREF_NAME, false]]});
|
||||
await test_coop(httpURL("coop_header.sjs", "https://example.com"), httpURL("coop_header.sjs", "https://example.com"), false);
|
||||
await test_coop(httpURL("coop_header.sjs?same-origin", "http://example.com"), httpURL("coop_header.sjs", "http://example.com"), false);
|
||||
await test_coop(httpURL("coop_header.sjs", "http://example.com"), httpURL("coop_header.sjs?same-origin", "http://example.com"), false);
|
||||
await test_coop(httpURL("coop_header.sjs?same-origin", "http://example.com"), httpURL("coop_header.sjs?same-site", "http://example.com"), false); // assuming we don't have fission yet :)
|
||||
});
|
||||
|
||||
add_task(async function test_enabled() {
|
||||
await SpecialPowers.pushPrefEnv({set: [[PREF_NAME, true]]});
|
||||
await test_coop(httpURL("coop_header.sjs", "https://example.com"), httpURL("coop_header.sjs", "https://example.com"), false);
|
||||
await test_coop(httpURL("coop_header.sjs", "https://example.com"), httpURL("coop_header.sjs?same-origin", "https://example.org"), true);
|
||||
await test_coop(httpURL("coop_header.sjs?same-origin#1", "https://example.com"), httpURL("coop_header.sjs?same-origin#1", "https://example.org"), true);
|
||||
await test_coop(httpURL("coop_header.sjs?same-origin#2", "https://example.com"), httpURL("coop_header.sjs?same-site#2", "https://example.org"), true);
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
function handleRequest(request, response)
|
||||
{
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
|
||||
let coop = request.queryString;
|
||||
if (coop.length > 0) {
|
||||
response.setHeader("Cross-Origin-Opener-Policy", unescape(coop), false);
|
||||
}
|
||||
|
||||
response.setHeader("Content-Type", "text/html; charset=utf-8", false);
|
||||
|
||||
response.write("<!DOCTYPE html><html><body><p>Hello world</p></body></html>");
|
||||
}
|
|
@ -17,9 +17,12 @@ XPCOMUtils.defineLazyPreferenceGetter(this, "useSeparatePrivilegedContentProcess
|
|||
"browser.tabs.remote.separatePrivilegedContentProcess", false);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "useHttpResponseProcessSelection",
|
||||
"browser.tabs.remote.useHTTPResponseProcessSelection", false);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "useCrossOriginOpenerPolicy",
|
||||
"browser.tabs.remote.useCrossOriginOpenerPolicy", false);
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "serializationHelper",
|
||||
"@mozilla.org/network/serialization-helper;1",
|
||||
"nsISerializationHelper");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "Utils",
|
||||
"resource://gre/modules/sessionstore/Utils.jsm");
|
||||
|
||||
|
@ -98,6 +101,9 @@ var E10SUtils = {
|
|||
useHttpResponseProcessSelection() {
|
||||
return useHttpResponseProcessSelection;
|
||||
},
|
||||
useCrossOriginOpenerPolicy() {
|
||||
return useCrossOriginOpenerPolicy;
|
||||
},
|
||||
|
||||
canLoadURIInRemoteType(aURL, aRemoteType = DEFAULT_REMOTE_TYPE,
|
||||
aPreferredRemoteType = undefined) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче