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:
Valentin Gosu 2019-02-12 12:16:58 +00:00
Родитель 1c83ed37de
Коммит 005dcbada4
8 изменённых файлов: 87 добавлений и 5 удалений

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

@ -2315,7 +2315,8 @@ var SessionStoreInternal = {
// Examine the channel response to see if we should change the process
// performing the given load.
onExamineResponse(aChannel) {
if (!E10SUtils.useHttpResponseProcessSelection()) {
if (!E10SUtils.useHttpResponseProcessSelection() &&
!E10SUtils.useCrossOriginOpenerPolicy()) {
return;
}
@ -2364,7 +2365,9 @@ var SessionStoreInternal = {
useRemoteTabs,
browser.remoteType,
currentPrincipal);
if (browser.remoteType == remoteType) {
if (browser.remoteType == remoteType &&
(!E10SUtils.useCrossOriginOpenerPolicy() ||
!aChannel.hasCrossOriginOpenerPolicyMismatch())) {
return; // Already in compatible process.
}

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

@ -9831,8 +9831,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(),
@ -9856,6 +9854,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

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

@ -711,7 +711,8 @@ nsresult MergeParentLoadInfoForwarder(
aLoadInfo->MaybeIncreaseTainting(aForwarderArgs.tainting());
}
// TODO: merge openerPolicy
MOZ_ALWAYS_SUCCEEDS(
aLoadInfo->SetOpenerPolicy(aForwarderArgs.openerPolicy()));
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetDocumentHasUserInteracted(
aForwarderArgs.documentHasUserInteracted()));

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

@ -7264,6 +7264,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));

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

@ -4,6 +4,8 @@ support-files =
dummy_page.html
print_postdata.sjs
307redirect.sjs
coop_header.sjs
[browser_RemoteWebNavigation.js]
[browser_httpResponseProcessSelection.js]
[browser_httpCrossOriginOpenerPolicy.js]

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

@ -0,0 +1,51 @@
"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 test_coop(start, target, expectedProcessSwitch) {
return BrowserTestUtils.withNewTab({
gBrowser, url: start,
}, async function(browser) {
info(`Test tab ready: ${start}`);
let firstProcessID = await ContentTask.spawn(browser, null, () => {
return Services.appinfo.processID;
});
info(`firstProcessID: ${firstProcessID}`);
BrowserTestUtils.loadURI(browser, target);
await BrowserTestUtils.browserLoaded(browser);
info(`Navigated to: ${target}`);
let secondProcessID = await ContentTask.spawn(browser, null, () => {
return Services.appinfo.processID;
});
is(firstProcessID != secondProcessID, expectedProcessSwitch, `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", "https://example.com"), httpURL("coop_header.sjs", "https://example.org"), true);
await test_coop(httpURL("coop_header.sjs?same-origin", "https://example.com"), httpURL("coop_header.sjs?same-site", "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,6 +17,9 @@ 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);
ChromeUtils.defineModuleGetter(this, "Utils",
"resource://gre/modules/sessionstore/Utils.jsm");
@ -95,6 +98,9 @@ var E10SUtils = {
useHttpResponseProcessSelection() {
return useHttpResponseProcessSelection;
},
useCrossOriginOpenerPolicy() {
return useCrossOriginOpenerPolicy;
},
canLoadURIInRemoteType(aURL, aRemoteType = DEFAULT_REMOTE_TYPE,
aPreferredRemoteType = undefined) {