зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1568597 - Make RemoteWorkerManager::GetRemoteType/MatchRemoteType fission-aware. r=asuth,nika
Differential Revision: https://phabricator.services.mozilla.com/D81373
This commit is contained in:
Родитель
fa53a76810
Коммит
74b570aff1
|
@ -17,11 +17,18 @@
|
|||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/StaticPrefs_extensions.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIE10SUtils.h"
|
||||
#include "nsImportModule.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "RemoteWorkerServiceParent.h"
|
||||
|
||||
mozilla::LazyLogModule gRemoteWorkerManagerLog("RemoteWorkerManager");
|
||||
|
||||
#define LOG(fmt) \
|
||||
MOZ_LOG(gRemoteWorkerManagerLog, mozilla::LogLevel::Verbose, fmt)
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace ipc;
|
||||
|
@ -63,9 +70,9 @@ void TransmitPermissionsAndBlobURLsForPrincipalInfo(
|
|||
// static
|
||||
bool RemoteWorkerManager::MatchRemoteType(const nsACString& processRemoteType,
|
||||
const nsACString& workerRemoteType) {
|
||||
if (processRemoteType.Equals(workerRemoteType)) {
|
||||
return true;
|
||||
}
|
||||
LOG(("MatchRemoteType [processRemoteType=%s, workerRemoteType=%s]",
|
||||
PromiseFlatCString(processRemoteType).get(),
|
||||
PromiseFlatCString(workerRemoteType).get()));
|
||||
|
||||
// Respecting COOP and COEP requires processing headers in the parent
|
||||
// process in order to choose an appropriate content process, but the
|
||||
|
@ -75,18 +82,17 @@ bool RemoteWorkerManager::MatchRemoteType(const nsACString& processRemoteType,
|
|||
// The ultimate goal is to allow these worker types to be put in such
|
||||
// processes based on their script response headers.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1595206
|
||||
if (IsWebCoopCoepRemoteType(processRemoteType)) {
|
||||
return false;
|
||||
}
|
||||
//
|
||||
// RemoteWorkerManager::GetRemoteType should not select this remoteType
|
||||
// and so workerRemoteType is not expected to be set to a coop+coep
|
||||
// remoteType and here we can just assert that it is not happening.
|
||||
MOZ_ASSERT(!IsWebCoopCoepRemoteType(workerRemoteType));
|
||||
|
||||
// A worker for a non privileged child process can be launched in
|
||||
// any web child process that is not COOP and COEP.
|
||||
if ((workerRemoteType.IsEmpty() || IsWebRemoteType(workerRemoteType)) &&
|
||||
IsWebRemoteType(processRemoteType)) {
|
||||
return true;
|
||||
}
|
||||
// For similar reasons to the ones related to COOP+COEP processes,
|
||||
// we don't expect workerRemoteType to be set to a large allocation one.
|
||||
MOZ_ASSERT(workerRemoteType != LARGE_ALLOCATION_REMOTE_TYPE);
|
||||
|
||||
return false;
|
||||
return processRemoteType.Equals(workerRemoteType);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -94,59 +100,74 @@ Result<nsCString, nsresult> RemoteWorkerManager::GetRemoteType(
|
|||
const nsCOMPtr<nsIPrincipal>& aPrincipal, WorkerType aWorkerType) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (aWorkerType != WorkerType::WorkerTypeService &&
|
||||
aWorkerType != WorkerType::WorkerTypeShared) {
|
||||
// This methods isn't expected to be called for worker type that
|
||||
// aren't remote workers (currently Service and Shared workers).
|
||||
return Err(NS_ERROR_UNEXPECTED);
|
||||
MOZ_ASSERT_IF(aWorkerType == WorkerType::WorkerTypeService,
|
||||
aPrincipal->GetIsContentPrincipal());
|
||||
|
||||
nsCOMPtr<nsIE10SUtils> e10sUtils =
|
||||
do_ImportModule("resource://gre/modules/E10SUtils.jsm", "E10SUtils");
|
||||
if (NS_WARN_IF(!e10sUtils)) {
|
||||
LOG(("GetRemoteType Abort: could not import E10SUtils"));
|
||||
return Err(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
nsCString preferredRemoteType = DEFAULT_REMOTE_TYPE;
|
||||
if (aWorkerType == WorkerType::WorkerTypeShared) {
|
||||
if (auto* contentChild = ContentChild::GetSingleton()) {
|
||||
// For a shared worker set the preferred remote type to the content
|
||||
// child process remote type.
|
||||
preferredRemoteType = contentChild->GetRemoteType();
|
||||
} else if (aPrincipal->IsSystemPrincipal()) {
|
||||
preferredRemoteType = NOT_REMOTE_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
nsIE10SUtils::RemoteWorkerType workerType;
|
||||
|
||||
switch (aWorkerType) {
|
||||
case WorkerType::WorkerTypeService:
|
||||
workerType = nsIE10SUtils::REMOTE_WORKER_TYPE_SERVICE;
|
||||
break;
|
||||
case WorkerType::WorkerTypeShared:
|
||||
workerType = nsIE10SUtils::REMOTE_WORKER_TYPE_SHARED;
|
||||
break;
|
||||
default:
|
||||
// This method isn't expected to be called for worker types that
|
||||
// aren't remote workers (currently Service and Shared workers).
|
||||
LOG(("GetRemoteType Error on unexpected worker type"));
|
||||
MOZ_DIAGNOSTIC_ASSERT(false, "Unexpected worker type");
|
||||
return Err(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
// Here we do not have access to the window and so we can't use its
|
||||
// useRemoteTabs and useRemoteSubframes flags (for the service
|
||||
// worker there may not even be a window associated to the worker
|
||||
// yet), and so we have to use the prefs instead.
|
||||
bool isMultiprocess = BrowserTabsRemoteAutostart();
|
||||
bool isFission = FissionAutostart();
|
||||
|
||||
nsCString remoteType = NOT_REMOTE_TYPE;
|
||||
|
||||
// If Gecko is running in single process mode, there is no child process
|
||||
// to select, return without assigning any remoteType.
|
||||
if (!BrowserTabsRemoteAutostart()) {
|
||||
return remoteType;
|
||||
nsresult rv = e10sUtils->GetRemoteTypeForWorkerPrincipal(
|
||||
aPrincipal, workerType, isMultiprocess, isFission, preferredRemoteType,
|
||||
remoteType);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
LOG(
|
||||
("GetRemoteType Abort: E10SUtils.getRemoteTypeForWorkerPrincipal "
|
||||
"exception"));
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
false, "E10SUtils.getRemoteTypeForworkerPrincipal did throw");
|
||||
return Err(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
auto* contentChild = ContentChild::GetSingleton();
|
||||
if (MOZ_LOG_TEST(gRemoteWorkerManagerLog, LogLevel::Verbose)) {
|
||||
nsCString principalOrigin;
|
||||
aPrincipal->GetOrigin(principalOrigin);
|
||||
|
||||
bool isSystem = !!BasePrincipal::Cast(aPrincipal)->IsSystemPrincipal();
|
||||
bool isMozExtension =
|
||||
!isSystem && !!BasePrincipal::Cast(aPrincipal)->AddonPolicy();
|
||||
|
||||
if (aWorkerType == WorkerType::WorkerTypeShared && !contentChild &&
|
||||
!isSystem) {
|
||||
// Prevent content principals SharedWorkers to be launched in the main
|
||||
// process while running in multiprocess mode.
|
||||
//
|
||||
// NOTE this also prevents moz-extension SharedWorker to be created
|
||||
// while the extension process is disabled by prefs, allowing it would
|
||||
// also trigger an assertion failure in
|
||||
// RemoteWorkerManager::SelectorTargetActor, due to an unexpected
|
||||
// content-principal parent-process workers while e10s is on).
|
||||
return Err(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
bool separatePrivilegedMozilla = Preferences::GetBool(
|
||||
"browser.tabs.remote.separatePrivilegedMozillaWebContentProcess", false);
|
||||
|
||||
if (isMozExtension) {
|
||||
remoteType = EXTENSION_REMOTE_TYPE;
|
||||
} else if (separatePrivilegedMozilla) {
|
||||
bool isPrivilegedMozilla = false;
|
||||
aPrincipal->IsURIInPrefList("browser.tabs.remote.separatedMozillaDomains",
|
||||
&isPrivilegedMozilla);
|
||||
|
||||
if (isPrivilegedMozilla) {
|
||||
remoteType = PRIVILEGEDMOZILLA_REMOTE_TYPE;
|
||||
} else if (aWorkerType == WorkerType::WorkerTypeShared && contentChild) {
|
||||
remoteType = contentChild->GetRemoteType();
|
||||
} else {
|
||||
remoteType = DEFAULT_REMOTE_TYPE;
|
||||
}
|
||||
} else {
|
||||
remoteType = DEFAULT_REMOTE_TYPE;
|
||||
LOG(
|
||||
("GetRemoteType workerType=%s, principal=%s, "
|
||||
"preferredRemoteType=%s, selectedRemoteType=%s",
|
||||
aWorkerType == WorkerType::WorkerTypeService ? "service" : "shared",
|
||||
principalOrigin.get(), preferredRemoteType.get(), remoteType.get()));
|
||||
}
|
||||
|
||||
return remoteType;
|
||||
|
@ -202,6 +223,7 @@ bool RemoteWorkerManager::IsRemoteTypeAllowed(const RemoteWorkerData& aData) {
|
|||
auto remoteType = GetRemoteType(
|
||||
principal, isServiceWorker ? WorkerTypeService : WorkerTypeShared);
|
||||
if (NS_WARN_IF(remoteType.isErr())) {
|
||||
LOG(("IsRemoteTypeAllowed: Error to retrieve remote type"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -262,6 +284,8 @@ void RemoteWorkerManager::RegisterActor(RemoteWorkerServiceParent* aActor) {
|
|||
const auto& workerRemoteType = p.mData.remoteType();
|
||||
|
||||
if (MatchRemoteType(remoteType, workerRemoteType)) {
|
||||
LOG(("RegisterActor - Launch Pending, workerRemoteType=%s",
|
||||
workerRemoteType.get()));
|
||||
LaunchInternal(p.mController, aActor, p.mData);
|
||||
} else {
|
||||
unlaunched.AppendElement(std::move(p));
|
||||
|
@ -278,6 +302,8 @@ void RemoteWorkerManager::RegisterActor(RemoteWorkerServiceParent* aActor) {
|
|||
if (mPendings.IsEmpty()) {
|
||||
Release();
|
||||
}
|
||||
|
||||
LOG(("RegisterActor - mPendings length: %zu", mPendings.Length()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,6 +603,7 @@ void RemoteWorkerManager::LaunchNewContentProcess(
|
|||
const CallbackParamType& aValue,
|
||||
const nsCString& remoteType) mutable {
|
||||
if (aValue.IsResolve()) {
|
||||
LOG(("LaunchNewContentProcess: successfully got child process"));
|
||||
if (isServiceWorker) {
|
||||
TransmitPermissionsAndBlobURLsForPrincipalInfo(aValue.ResolveValue(),
|
||||
principalInfo);
|
||||
|
@ -595,6 +622,10 @@ void RemoteWorkerManager::LaunchNewContentProcess(
|
|||
for (const auto& pending : pendings) {
|
||||
const auto& workerRemoteType = pending.mData.remoteType();
|
||||
if (self->MatchRemoteType(remoteType, workerRemoteType)) {
|
||||
LOG(
|
||||
("LaunchNewContentProcess: Cancel pending with "
|
||||
"workerRemoteType=%s",
|
||||
workerRemoteType.get()));
|
||||
pending.mController->CreationFailed();
|
||||
} else {
|
||||
uncancelled.AppendElement(pending);
|
||||
|
@ -608,6 +639,8 @@ void RemoteWorkerManager::LaunchNewContentProcess(
|
|||
}
|
||||
};
|
||||
|
||||
LOG(("LaunchNewContentProcess: remoteType=%s", aData.remoteType().get()));
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__, [callback = std::move(processLaunchCallback),
|
||||
workerRemoteType = aData.remoteType()]() mutable {
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/* -*- 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 "gtest/gtest.h"
|
||||
#include "../RemoteWorkerManager.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
TEST(RemoteWorkerManager, TestMatchRemoteType)
|
||||
{
|
||||
static const struct {
|
||||
const nsCString processRemoteType;
|
||||
const nsCString workerRemoteType;
|
||||
const bool shouldMatch;
|
||||
} tests[] = {
|
||||
// Test exact matches between process and worker remote types.
|
||||
{DEFAULT_REMOTE_TYPE, DEFAULT_REMOTE_TYPE, true},
|
||||
{EXTENSION_REMOTE_TYPE, EXTENSION_REMOTE_TYPE, true},
|
||||
{PRIVILEGEDMOZILLA_REMOTE_TYPE, PRIVILEGEDMOZILLA_REMOTE_TYPE, true},
|
||||
|
||||
// Test workers with remoteType "web" not launched on non-web or coop+coep
|
||||
// processes.
|
||||
{PRIVILEGEDMOZILLA_REMOTE_TYPE, DEFAULT_REMOTE_TYPE, false},
|
||||
{PRIVILEGEDABOUT_REMOTE_TYPE, DEFAULT_REMOTE_TYPE, false},
|
||||
{EXTENSION_REMOTE_TYPE, DEFAULT_REMOTE_TYPE, false},
|
||||
{FILE_REMOTE_TYPE, DEFAULT_REMOTE_TYPE, false},
|
||||
{WITH_COOP_COEP_REMOTE_TYPE_PREFIX, DEFAULT_REMOTE_TYPE, false},
|
||||
|
||||
// Test workers with remoteType "web" launched in web child processes.
|
||||
{LARGE_ALLOCATION_REMOTE_TYPE, DEFAULT_REMOTE_TYPE, true},
|
||||
{FISSION_WEB_REMOTE_TYPE, DEFAULT_REMOTE_TYPE, true},
|
||||
|
||||
// Test empty remoteType default to "web" remoteType.
|
||||
{DEFAULT_REMOTE_TYPE, NOT_REMOTE_TYPE, true},
|
||||
{WITH_COOP_COEP_REMOTE_TYPE_PREFIX, NOT_REMOTE_TYPE, false},
|
||||
{PRIVILEGEDMOZILLA_REMOTE_TYPE, NOT_REMOTE_TYPE, false},
|
||||
{EXTENSION_REMOTE_TYPE, NOT_REMOTE_TYPE, false},
|
||||
};
|
||||
|
||||
for (const auto& test : tests) {
|
||||
auto message = nsPrintfCString(
|
||||
R"(MatchRemoteType("%s", "%s") should return %s)",
|
||||
test.processRemoteType.get(), test.workerRemoteType.get(),
|
||||
test.shouldMatch ? "true" : "false");
|
||||
ASSERT_EQ(RemoteWorkerManager::MatchRemoteType(test.processRemoteType,
|
||||
test.workerRemoteType),
|
||||
test.shouldMatch)
|
||||
<< message;
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
UNIFIED_SOURCES = [
|
||||
'TestMatchRemoteType.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul-gtest'
|
|
@ -40,8 +40,6 @@ IPDL_SOURCES += [
|
|||
'RemoteWorkerTypes.ipdlh',
|
||||
]
|
||||
|
||||
TEST_DIRS += ['gtest']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
@ -21,9 +21,7 @@ do_get_profile(true);
|
|||
|
||||
AddonTestUtils.init(this);
|
||||
|
||||
const server = createHttpServer({
|
||||
hosts: ["localhost", "example.org"],
|
||||
});
|
||||
const server = createHttpServer({ hosts: ["localhost"] });
|
||||
|
||||
server.registerPathHandler("/sw.js", (request, response) => {
|
||||
info(`/sw.js is being requested: ${JSON.stringify(request)}`);
|
||||
|
@ -41,23 +39,8 @@ add_task(async function setup_prefs() {
|
|||
// Enable nsIServiceWorkerManager.registerForTest.
|
||||
Services.prefs.setBoolPref("dom.serviceWorkers.testing.enabled", true);
|
||||
|
||||
// Configure prefs to configure example.org as a domain to load
|
||||
// in a privilegedmozilla content child process.
|
||||
Services.prefs.setBoolPref(
|
||||
"browser.tabs.remote.separatePrivilegedMozillaWebContentProcess",
|
||||
true
|
||||
);
|
||||
Services.prefs.setCharPref(
|
||||
"browser.tabs.remote.separatedMozillaDomains",
|
||||
"example.org"
|
||||
);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("dom.serviceWorkers.testing.enabled");
|
||||
Services.prefs.clearUserPref(
|
||||
"browser.tabs.remote.separatePrivilegedMozillaWebContentProcess"
|
||||
);
|
||||
Services.prefs.clearUserPref("browser.tabs.remote.separatedMozillaDomains");
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -96,24 +79,9 @@ add_task(async function launch_remoteworkers_in_new_processes() {
|
|||
})}`
|
||||
);
|
||||
|
||||
// A test service worker that should spawn a privilegedmozilla child process.
|
||||
const swRegInfoPriv = await swm.registerForTest(
|
||||
ssm.createContentPrincipal(Services.io.newURI("http://example.org"), {}),
|
||||
"http://example.org/scope",
|
||||
"http://example.org/sw.js"
|
||||
);
|
||||
swRegInfoPriv.QueryInterface(Ci.nsIServiceWorkerRegistrationInfo);
|
||||
|
||||
info(
|
||||
`privilegedmozilla service worker registered: ${JSON.stringify({
|
||||
principal: swRegInfoPriv.principal.spec,
|
||||
scope: swRegInfoPriv.scope,
|
||||
})}`
|
||||
);
|
||||
|
||||
info("Wait new process to be launched");
|
||||
await TestUtils.waitForCondition(() => {
|
||||
return Services.ppmm.childCount - initialChildCount >= 2;
|
||||
return Services.ppmm.childCount - initialChildCount >= 1;
|
||||
}, "wait for a new child processes to be started");
|
||||
|
||||
// Wait both workers to become active to be sure that. besides spawning
|
||||
|
@ -122,13 +90,7 @@ add_task(async function launch_remoteworkers_in_new_processes() {
|
|||
// pass successfull the IsRemoteTypeAllowed check in RemoteworkerChild).
|
||||
info("Wait for webcontent worker to become active");
|
||||
await TestUtils.waitForCondition(
|
||||
() => swRegInfoPriv.activeWorker,
|
||||
`wait workers for scope ${swRegInfoPriv.scope} to be active`
|
||||
);
|
||||
|
||||
info("Wait for privilegedmozille worker to become active");
|
||||
await TestUtils.waitForCondition(
|
||||
() => swRegInfoPriv.activeWorker,
|
||||
`wait workers for scope ${swRegInfoPriv.scope} to be active`
|
||||
() => swRegInfoWeb.activeWorker,
|
||||
`wait workers for scope ${swRegInfoWeb.scope} to be active`
|
||||
);
|
||||
});
|
||||
|
|
|
@ -169,7 +169,8 @@ function validatedWebRemoteType(
|
|||
aTargetUri,
|
||||
aCurrentUri,
|
||||
aResultPrincipal,
|
||||
aRemoteSubframes
|
||||
aRemoteSubframes,
|
||||
aIsWorker = false
|
||||
) {
|
||||
// To load into the Privileged Mozilla Content Process you must be https,
|
||||
// and be an exact match or a subdomain of an allowlisted domain.
|
||||
|
@ -189,6 +190,15 @@ function validatedWebRemoteType(
|
|||
// If we're in the parent and we were passed a web-handled scheme,
|
||||
// transform it now to avoid trying to load it in the wrong process.
|
||||
if (aRemoteSubframes && hasPotentiallyWebHandledScheme(aTargetUri)) {
|
||||
// We shouldn't even get to this for a worker, throw an unexpected error
|
||||
// if we do.
|
||||
if (aIsWorker) {
|
||||
throw Components.Exception(
|
||||
"Unexpected remote worker with a web handled scheme",
|
||||
Cr.NS_ERROR_UNEXPECTED
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT &&
|
||||
Services.appinfo.remoteType.startsWith(FISSION_WEB_REMOTE_TYPE + "=")
|
||||
|
@ -198,6 +208,7 @@ function validatedWebRemoteType(
|
|||
// we know the "real" URL to which we'll redirect.
|
||||
return Services.appinfo.remoteType;
|
||||
}
|
||||
|
||||
// This doesn't work (throws) in the child - see
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1589082
|
||||
// Even if it did, it'd cause sync IPC
|
||||
|
@ -222,7 +233,7 @@ function validatedWebRemoteType(
|
|||
// If the domain is whitelisted to allow it to use file:// URIs, then we have
|
||||
// to run it in a file content process, in case it uses file:// sub-resources.
|
||||
const sm = Services.scriptSecurityManager;
|
||||
if (sm.inFileURIAllowlist(aTargetUri)) {
|
||||
if (!aIsWorker && sm.inFileURIAllowlist(aTargetUri)) {
|
||||
return FILE_REMOTE_TYPE;
|
||||
}
|
||||
|
||||
|
@ -264,7 +275,11 @@ function validatedWebRemoteType(
|
|||
return aPreferredRemoteType;
|
||||
}
|
||||
|
||||
if (aPreferredRemoteType == FILE_REMOTE_TYPE && !aRemoteSubframes) {
|
||||
if (
|
||||
aPreferredRemoteType == FILE_REMOTE_TYPE &&
|
||||
!aRemoteSubframes &&
|
||||
!aIsWorker
|
||||
) {
|
||||
E10SUtils.log().debug("checking allowLinkedWebInFileUriProcess");
|
||||
if (!aCurrentUri) {
|
||||
E10SUtils.log().debug("No aCurrentUri");
|
||||
|
@ -294,6 +309,12 @@ function validatedWebRemoteType(
|
|||
return WEB_REMOTE_TYPE;
|
||||
}
|
||||
|
||||
// remoteTypes allowed to host system-principal remote workers.
|
||||
const SYSTEM_WORKERS_REMOTE_TYPES_ALLOWED = [
|
||||
NOT_REMOTE,
|
||||
PRIVILEGEDABOUT_REMOTE_TYPE,
|
||||
];
|
||||
|
||||
var E10SUtils = {
|
||||
DEFAULT_REMOTE_TYPE,
|
||||
NOT_REMOTE,
|
||||
|
@ -304,6 +325,7 @@ var E10SUtils = {
|
|||
PRIVILEGEDABOUT_REMOTE_TYPE,
|
||||
PRIVILEGEDMOZILLA_REMOTE_TYPE,
|
||||
LARGE_ALLOCATION_REMOTE_TYPE,
|
||||
FISSION_WEB_REMOTE_TYPE,
|
||||
|
||||
useCrossOriginOpenerPolicy() {
|
||||
return useCrossOriginOpenerPolicy;
|
||||
|
@ -429,7 +451,8 @@ var E10SUtils = {
|
|||
aPreferredRemoteType = DEFAULT_REMOTE_TYPE,
|
||||
aCurrentUri = null,
|
||||
aResultPrincipal = null,
|
||||
aIsSubframe = false
|
||||
aIsSubframe = false,
|
||||
aIsWorker = false
|
||||
) {
|
||||
if (!aMultiProcess) {
|
||||
return NOT_REMOTE;
|
||||
|
@ -527,6 +550,15 @@ var E10SUtils = {
|
|||
// Protocols that redirect to http(s) will just flip back to a
|
||||
// regular content process after the redirect.
|
||||
if (aURI.scheme.startsWith("ext+")) {
|
||||
// We shouldn't even get to this for a worker, throw an unexpected error
|
||||
// if we do.
|
||||
if (aIsWorker) {
|
||||
throw Components.Exception(
|
||||
"Unexpected remote worker with extension handled scheme",
|
||||
Cr.NS_ERROR_UNEXPECTED
|
||||
);
|
||||
}
|
||||
|
||||
return WebExtensionPolicy.useRemoteWebExtensions
|
||||
? EXTENSION_REMOTE_TYPE
|
||||
: NOT_REMOTE;
|
||||
|
@ -540,6 +572,15 @@ var E10SUtils = {
|
|||
// innermost URI. Any URIs like this will need to be handled in the
|
||||
// cases above, so we don't still end up using the fake inner URI here.
|
||||
if (aURI instanceof Ci.nsINestedURI) {
|
||||
// We shouldn't even get to this for a worker, throw an unexpected error
|
||||
// if we do.
|
||||
if (aIsWorker) {
|
||||
throw Components.Exception(
|
||||
"Unexpected worker with a NestedURI",
|
||||
Cr.NS_ERROR_UNEXPECTED
|
||||
);
|
||||
}
|
||||
|
||||
let innerURI = aURI.QueryInterface(Ci.nsINestedURI).innerURI;
|
||||
return this.getRemoteTypeForURIObject(
|
||||
innerURI,
|
||||
|
@ -561,7 +602,8 @@ var E10SUtils = {
|
|||
aURI,
|
||||
aCurrentUri,
|
||||
aResultPrincipal,
|
||||
aRemoteSubframes
|
||||
aRemoteSubframes,
|
||||
aIsWorker
|
||||
);
|
||||
log.debug(` validatedWebRemoteType() returning: ${remoteType}`);
|
||||
return remoteType;
|
||||
|
@ -625,6 +667,90 @@ var E10SUtils = {
|
|||
);
|
||||
},
|
||||
|
||||
getRemoteTypeForWorkerPrincipal(
|
||||
aPrincipal,
|
||||
aWorkerType,
|
||||
aIsMultiProcess,
|
||||
aIsFission,
|
||||
aPreferredRemoteType = DEFAULT_REMOTE_TYPE
|
||||
) {
|
||||
if (aPrincipal.isExpandedPrincipal) {
|
||||
// Explicitly disallow expanded principals:
|
||||
// The worker principal is based on the worker script, an expanded principal
|
||||
// is not expected.
|
||||
throw new Error("Unexpected expanded principal worker");
|
||||
}
|
||||
|
||||
if (
|
||||
aWorkerType === Ci.nsIE10SUtils.REMOTE_WORKER_TYPE_SERVICE &&
|
||||
!aPrincipal.isContentPrincipal
|
||||
) {
|
||||
// Fails earlier on service worker with a non content principal.
|
||||
throw new Error("Unexpected system or null principal service worker");
|
||||
}
|
||||
|
||||
if (!aIsMultiProcess) {
|
||||
// Return earlier when multiprocess is disabled.
|
||||
return NOT_REMOTE;
|
||||
}
|
||||
|
||||
if (
|
||||
// We don't want to launch workers in a large allocation remote type,
|
||||
// change it to the web remote type (then getRemoteTypeForURIObject
|
||||
// may change it to an isolated one).
|
||||
aPreferredRemoteType === LARGE_ALLOCATION_REMOTE_TYPE ||
|
||||
// Similarly to the large allocation remote type, we don't want to
|
||||
// launch the shared worker in a web coop+coep remote type even if
|
||||
// was registered from a frame loaded in a child process with that
|
||||
// remote type.
|
||||
aPreferredRemoteType?.startsWith(WEB_REMOTE_COOP_COEP_TYPE_PREFIX)
|
||||
) {
|
||||
aPreferredRemoteType = DEFAULT_REMOTE_TYPE;
|
||||
}
|
||||
|
||||
// System principal shared workers are allowed to run in the main process
|
||||
// or in the privilegedabout child process. Early return the preferred remote type
|
||||
// if it is one where a system principal worked is allowed to run.
|
||||
if (
|
||||
aPrincipal.isSystemPrincipal &&
|
||||
SYSTEM_WORKERS_REMOTE_TYPES_ALLOWED.includes(aPreferredRemoteType)
|
||||
) {
|
||||
return aPreferredRemoteType;
|
||||
}
|
||||
|
||||
// Allow null principal shared workers to run in the same process type where they
|
||||
// have been registered (the preferredRemoteType), but return the DEFAULT_REMOTE_TYPE
|
||||
// if the preferred remote type was NOT_REMOTE.
|
||||
if (aPrincipal.isNullPrincipal) {
|
||||
return aPreferredRemoteType === NOT_REMOTE
|
||||
? DEFAULT_REMOTE_TYPE
|
||||
: aPreferredRemoteType;
|
||||
}
|
||||
|
||||
// Sanity check, there shouldn't be any system or null principal after this point.
|
||||
if (aPrincipal.isContentPrincipal) {
|
||||
// For content principal, get a remote type based on the worker principal URI
|
||||
// (which is based on the worker script url) and an initial preferredRemoteType
|
||||
// (only set for shared worker, based on the remote type where the shared worker
|
||||
// was registered from).
|
||||
return E10SUtils.getRemoteTypeForURIObject(
|
||||
aPrincipal.URI,
|
||||
aIsMultiProcess,
|
||||
aIsFission,
|
||||
aPreferredRemoteType,
|
||||
null,
|
||||
aPrincipal,
|
||||
false, // aIsSubFrame
|
||||
true // aIsWorker
|
||||
);
|
||||
}
|
||||
|
||||
// Throw explicitly if we were unable to get a remoteType for the worker.
|
||||
throw new Error(
|
||||
"Failed to get a remoteType for a non content principal worker"
|
||||
);
|
||||
},
|
||||
|
||||
makeInputStream(data) {
|
||||
if (typeof data == "string") {
|
||||
let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
|
|
|
@ -15,6 +15,11 @@ interface nsIURI;
|
|||
*/
|
||||
[scriptable, uuid(1e18680e-052d-4509-a17e-678f5c495e02)]
|
||||
interface nsIE10SUtils : nsISupports {
|
||||
cenum RemoteWorkerType: 8 {
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
REMOTE_WORKER_TYPE_SERVICE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine what remote type should be used to load a document with the given
|
||||
* principal.
|
||||
|
@ -39,4 +44,28 @@ interface nsIE10SUtils : nsISupports {
|
|||
in AUTF8String aPreferredRemoteType,
|
||||
in nsIPrincipal aCurrentPrincipal,
|
||||
in boolean aIsSubframe);
|
||||
|
||||
/**
|
||||
* Determine what remote type should be used to launch a worker script with
|
||||
* the given principal.
|
||||
*
|
||||
* @param aPrincipal
|
||||
* The result principal for the document being loaded.
|
||||
* @param aWorkerTypeName
|
||||
* The type of remote worker being launched (Ci.nsIE10SUtils.REMOTE_WORKER_TYPE_*).
|
||||
* @param aIsMultiProcess
|
||||
* A boolean to indicate if e10s enabled.
|
||||
* @param aIsFission
|
||||
* A boolean to indicate if fission is enabled.
|
||||
* @param aPreferredRemoteType
|
||||
* If multiple remote types are compatible with the worker,
|
||||
* prefer staying in this remote type.
|
||||
*
|
||||
* @return The remote type to launch the worker in.
|
||||
*/
|
||||
AUTF8String getRemoteTypeForWorkerPrincipal(in nsIPrincipal aPrincipal,
|
||||
in nsIE10SUtils_RemoteWorkerType aWorkerType,
|
||||
in boolean aIsMultiProcess,
|
||||
in boolean aIsFission,
|
||||
in AUTF8String aPreferredRemoteType);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,428 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
|
||||
const { E10SUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/E10SUtils.jsm"
|
||||
);
|
||||
|
||||
const URI_SECURE_COM = Services.io.newURI("https://example.com");
|
||||
const URI_SECURE_ORG = Services.io.newURI("https://example.org");
|
||||
const URI_INSECURE_ORG = Services.io.newURI("http://example.org");
|
||||
const URI_FILE = Services.io.newURI("file:///path/to/dir");
|
||||
const URI_EXTENSION = Services.io.newURI("moz-extension://fake-uuid");
|
||||
const URI_EXT_PROTOCOL = Services.io.newURI("ext+custom://fake-url");
|
||||
const URI_WEB_PROTOCOL = Services.io.newURI("web+custom://fake-url");
|
||||
const URI_PRIVILEGEDMOZILLA = Services.io.newURI("https://addons.mozilla.org");
|
||||
|
||||
const fakeContentScriptSandbox = Cu.Sandbox(
|
||||
["https://example.org", "moz-extension://fake-uuid"],
|
||||
{}
|
||||
);
|
||||
|
||||
const ssm = Services.scriptSecurityManager;
|
||||
const systemPrincipal = ssm.getSystemPrincipal();
|
||||
const nullPrincipal = ssm.createNullPrincipal({});
|
||||
const principalSecureCom = ssm.createContentPrincipal(URI_SECURE_COM, {});
|
||||
const principalSecureOrg = ssm.createContentPrincipal(URI_SECURE_ORG, {});
|
||||
const principalInsecureOrg = ssm.createContentPrincipal(URI_INSECURE_ORG, {});
|
||||
const principalFile = ssm.createContentPrincipal(URI_FILE, {});
|
||||
const principalExtension = ssm.createContentPrincipal(URI_EXTENSION, {});
|
||||
const principalExpanded = Cu.getObjectPrincipal(fakeContentScriptSandbox);
|
||||
const principalExtProtocol = ssm.createContentPrincipal(URI_EXT_PROTOCOL, {});
|
||||
const principalWebProtocol = ssm.createContentPrincipal(URI_WEB_PROTOCOL, {});
|
||||
const principalPrivilegedMozilla = ssm.createContentPrincipal(
|
||||
URI_PRIVILEGEDMOZILLA,
|
||||
{}
|
||||
);
|
||||
|
||||
const {
|
||||
DEFAULT_REMOTE_TYPE,
|
||||
EXTENSION_REMOTE_TYPE,
|
||||
FILE_REMOTE_TYPE,
|
||||
FISSION_WEB_REMOTE_TYPE,
|
||||
LARGE_ALLOCATION_REMOTE_TYPE,
|
||||
NOT_REMOTE,
|
||||
PRIVILEGEDABOUT_REMOTE_TYPE,
|
||||
PRIVILEGEDMOZILLA_REMOTE_TYPE,
|
||||
WEB_REMOTE_COOP_COEP_TYPE_PREFIX,
|
||||
WEB_REMOTE_TYPE,
|
||||
} = E10SUtils;
|
||||
|
||||
const {
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
REMOTE_WORKER_TYPE_SERVICE,
|
||||
} = Ci.nsIE10SUtils;
|
||||
|
||||
// Test ServiceWorker remoteType selection with multiprocess and/or site isolation enabled.
|
||||
add_task(function test_get_remote_type_for_service_worker() {
|
||||
// ServiceWorkers with system or null principal are unexpected and we expect
|
||||
// the method call to throw.
|
||||
for (const principal of [systemPrincipal, nullPrincipal]) {
|
||||
Assert.throws(
|
||||
() =>
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principal,
|
||||
REMOTE_WORKER_TYPE_SERVICE,
|
||||
true,
|
||||
false
|
||||
),
|
||||
/Unexpected system or null principal/,
|
||||
`Did raise an exception on "${principal.origin}" principal ServiceWorker`
|
||||
);
|
||||
}
|
||||
|
||||
// ServiceWorker test cases:
|
||||
// - e10s + fission disabled:
|
||||
// - extension principal + any preferred remote type => extension remote type
|
||||
// - content principal + any preferred remote type => web remote type
|
||||
// - fission enabled:
|
||||
// - extension principal + any preferred remote type => extension remote type
|
||||
// - content principal + any preferred remote type => webIsolated=siteOrigin remote type
|
||||
function* getTestCase(fission = false) {
|
||||
const TEST_PRINCIPALS = [
|
||||
principalSecureCom,
|
||||
principalSecureOrg,
|
||||
principalExtension,
|
||||
];
|
||||
|
||||
const PREFERRED_REMOTE_TYPES = [
|
||||
E10SUtils.DEFAULT_REMOTE_TYPE,
|
||||
E10SUtils.WEB_REMOTE_TYPE,
|
||||
"fakeRemoteType",
|
||||
];
|
||||
|
||||
for (const principal of TEST_PRINCIPALS) {
|
||||
for (const preferred of PREFERRED_REMOTE_TYPES) {
|
||||
const msg = `ServiceWorker, principal=${
|
||||
principal.origin
|
||||
}, preferredRemoteType=${preferred}, ${fission ? "fission" : "e10s"}`;
|
||||
yield [
|
||||
msg,
|
||||
principal,
|
||||
REMOTE_WORKER_TYPE_SERVICE,
|
||||
true,
|
||||
fission,
|
||||
preferred,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test cases for e10s mode + fission disabled.
|
||||
for (const testCase of getTestCase(false)) {
|
||||
const [msg, principal, ...args] = testCase;
|
||||
let expected = E10SUtils.WEB_REMOTE_TYPE;
|
||||
|
||||
if (principal == principalExtension) {
|
||||
expected = WebExtensionPolicy.useRemoteWebExtensions
|
||||
? E10SUtils.EXTENSION_REMOTE_TYPE
|
||||
: E10SUtils.NOT_REMOTE;
|
||||
}
|
||||
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(principal, ...args),
|
||||
expected,
|
||||
msg
|
||||
);
|
||||
}
|
||||
|
||||
// Test cases for e10s mode + fission enabled.
|
||||
for (const testCase of getTestCase(true)) {
|
||||
const [msg, principal, ...args] = testCase;
|
||||
let expected = `${FISSION_WEB_REMOTE_TYPE}=${principal.siteOrigin}`;
|
||||
|
||||
if (principal == principalExtension) {
|
||||
expected = WebExtensionPolicy.useRemoteWebExtensions
|
||||
? E10SUtils.EXTENSION_REMOTE_TYPE
|
||||
: E10SUtils.NOT_REMOTE;
|
||||
}
|
||||
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(principal, ...args),
|
||||
expected,
|
||||
msg
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Test SharedWorker remoteType selection with multiprocess and/or site isolation enabled.
|
||||
add_task(function test_get_remote_type_for_shared_worker() {
|
||||
// Verify that for shared worker registered from a large allocation or web
|
||||
// coop+coep remote types we are going to select a web or fission remote type.
|
||||
for (const [principal, preferredRemoteType] of [
|
||||
[principalSecureCom, LARGE_ALLOCATION_REMOTE_TYPE],
|
||||
[
|
||||
principalSecureCom,
|
||||
`${WEB_REMOTE_COOP_COEP_TYPE_PREFIX}=${principalSecureCom.siteOrigin}`,
|
||||
],
|
||||
]) {
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principal,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
false,
|
||||
preferredRemoteType
|
||||
),
|
||||
WEB_REMOTE_TYPE,
|
||||
`Got WEB_REMOTE_TYPE on preferred ${preferredRemoteType} and fission disabled`
|
||||
);
|
||||
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principal,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
true,
|
||||
preferredRemoteType
|
||||
),
|
||||
`${FISSION_WEB_REMOTE_TYPE}=${principal.siteOrigin}`,
|
||||
`Got WEB_REMOTE_TYPE on preferred ${preferredRemoteType} and fission enabled`
|
||||
);
|
||||
}
|
||||
|
||||
// For System principal shared worker we do select NOT_REMOTE or the preferred
|
||||
// remote type if is one of the explicitly allowed (NOT_REMOTE and
|
||||
// PRIVILEGEDABOUT_REMOTE_TYPE).
|
||||
for (const [principal, preferredRemoteType] of [
|
||||
[systemPrincipal, NOT_REMOTE],
|
||||
[systemPrincipal, PRIVILEGEDABOUT_REMOTE_TYPE],
|
||||
]) {
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principal,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
true,
|
||||
preferredRemoteType
|
||||
),
|
||||
preferredRemoteType,
|
||||
`Selected the preferred ${preferredRemoteType} on system principal shared worker`
|
||||
);
|
||||
}
|
||||
|
||||
Assert.throws(
|
||||
() =>
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
systemPrincipal,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
true,
|
||||
"fakeRemoteType"
|
||||
),
|
||||
/Failed to get a remoteType/,
|
||||
"Does fail explicitly on system worker for arbitrary preferredRemoteType"
|
||||
);
|
||||
|
||||
// Behavior NOT_REMOTE preferredRemoteType for content principals with
|
||||
// multiprocess enabled.
|
||||
for (const [principal, expectedRemoteType] of [
|
||||
[
|
||||
principalSecureCom,
|
||||
`${FISSION_WEB_REMOTE_TYPE}=${principalSecureCom.siteOrigin}`,
|
||||
],
|
||||
[
|
||||
principalExtension,
|
||||
WebExtensionPolicy.useRemoteWebExtensions
|
||||
? EXTENSION_REMOTE_TYPE
|
||||
: NOT_REMOTE,
|
||||
],
|
||||
]) {
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principal,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
true,
|
||||
NOT_REMOTE
|
||||
),
|
||||
expectedRemoteType,
|
||||
`Got ${expectedRemoteType} for content principal ${principal.siteOrigin}`
|
||||
);
|
||||
}
|
||||
|
||||
// Shared worker registered for web+custom urls.
|
||||
for (const [preferredRemoteType, expectedRemoteType] of [
|
||||
[WEB_REMOTE_TYPE, WEB_REMOTE_TYPE],
|
||||
[LARGE_ALLOCATION_REMOTE_TYPE, WEB_REMOTE_TYPE],
|
||||
["fakeRemoteType", "fakeRemoteType"],
|
||||
// This seems to be actually failing with a SecurityError
|
||||
// as soon as the SharedWorker constructor is being called with
|
||||
// a web+...:// url from an extension principal:
|
||||
//
|
||||
// [EXTENSION_REMOTE_TYPE, EXTENSION_REMOTE_TYPE],
|
||||
]) {
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principalWebProtocol,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
true,
|
||||
preferredRemoteType
|
||||
),
|
||||
expectedRemoteType,
|
||||
"Selected expected process for web+custom:// shared worker"
|
||||
);
|
||||
}
|
||||
|
||||
// Shared worker registered for ext+custom urls.
|
||||
for (const [preferredRemoteType, expectedRemoteType] of [
|
||||
[WEB_REMOTE_TYPE, WEB_REMOTE_TYPE],
|
||||
[LARGE_ALLOCATION_REMOTE_TYPE, WEB_REMOTE_TYPE],
|
||||
["fakeRemoteType", "fakeRemoteType"],
|
||||
// This seems to be actually prevented by failing a ClientIsValidPrincipalInfo
|
||||
// check (but only when the remote worker is being launched in the child process
|
||||
// and so after a remote Type has been selected).
|
||||
// [EXTENSION_REMOTE_TYPE, EXTENSION_REMOTE_TYPE],
|
||||
]) {
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principalExtProtocol,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
true,
|
||||
preferredRemoteType
|
||||
),
|
||||
expectedRemoteType,
|
||||
"Selected expected process for ext+custom:// shared worker"
|
||||
);
|
||||
}
|
||||
|
||||
// Shared worker with a file principal.
|
||||
// NOTE: on android useSeparateFileUriProcess will be false and file uri are
|
||||
// going to run in the default web process.
|
||||
const expectedFileRemoteType = Services.prefs.getBoolPref(
|
||||
"browser.tabs.remote.separateFileUriProcess",
|
||||
false
|
||||
)
|
||||
? FILE_REMOTE_TYPE
|
||||
: WEB_REMOTE_TYPE;
|
||||
|
||||
for (const [preferredRemoteType, expectedRemoteType] of [
|
||||
[WEB_REMOTE_TYPE, expectedFileRemoteType],
|
||||
["fakeRemoteType", expectedFileRemoteType],
|
||||
]) {
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principalFile,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
true,
|
||||
preferredRemoteType
|
||||
),
|
||||
expectedRemoteType,
|
||||
"Got expected remote type on file principal shared worker"
|
||||
);
|
||||
}
|
||||
|
||||
// Shared worker related to a privilegedmozilla domain.
|
||||
// NOTE: separatePrivilegedMozilla will be false on android builds.
|
||||
const usePrivilegedMozilla = Services.prefs.getBoolPref(
|
||||
"browser.tabs.remote.separatePrivilegedMozillaWebContentProcess",
|
||||
false
|
||||
);
|
||||
const expectedRemoteType = usePrivilegedMozilla
|
||||
? PRIVILEGEDMOZILLA_REMOTE_TYPE
|
||||
: `${FISSION_WEB_REMOTE_TYPE}=https://mozilla.org`;
|
||||
for (const preferredRemoteType of [
|
||||
PRIVILEGEDMOZILLA_REMOTE_TYPE,
|
||||
"fakeRemoteType",
|
||||
]) {
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principalPrivilegedMozilla,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
true,
|
||||
true,
|
||||
preferredRemoteType
|
||||
),
|
||||
expectedRemoteType,
|
||||
"Got expected remote type on privilegedmozilla principal shared worker"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Test that we do throw on expanded principals.
|
||||
add_task(function test_get_remote_type_throws_on_expanded_principals() {
|
||||
for (const workerType of [
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
REMOTE_WORKER_TYPE_SERVICE,
|
||||
]) {
|
||||
Assert.throws(
|
||||
() =>
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(
|
||||
principalExpanded,
|
||||
workerType,
|
||||
true,
|
||||
false
|
||||
),
|
||||
/Unexpected expanded principal/,
|
||||
"Did raise an exception as expected"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Test that NO_REMOTE is the remote type selected when multiprocess is disabled,
|
||||
// there is no other checks special behaviors on particular principal or worker type.
|
||||
add_task(function test_get_remote_type_multiprocess_disabled() {
|
||||
function* getTestCase() {
|
||||
const TEST_PRINCIPALS = [
|
||||
systemPrincipal,
|
||||
nullPrincipal,
|
||||
principalSecureCom,
|
||||
principalSecureOrg,
|
||||
principalInsecureOrg,
|
||||
principalFile,
|
||||
principalExtension,
|
||||
];
|
||||
|
||||
const PREFERRED_REMOTE_TYPES = [
|
||||
E10SUtils.DEFAULT_REMOTE_TYPE,
|
||||
E10SUtils.WEB_REMOTE_TYPE,
|
||||
"fakeRemoteType",
|
||||
];
|
||||
|
||||
for (const principal of TEST_PRINCIPALS) {
|
||||
for (const preferred of PREFERRED_REMOTE_TYPES) {
|
||||
const msg = `SharedWorker, principal=${principal.origin}, preferredRemoteType=${preferred}`;
|
||||
yield [
|
||||
msg,
|
||||
principal,
|
||||
REMOTE_WORKER_TYPE_SHARED,
|
||||
false,
|
||||
false,
|
||||
preferred,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
for (const principal of TEST_PRINCIPALS) {
|
||||
// system and null principals are disallowed for service workers, we throw
|
||||
// if passed to the E10SUtils method and we cover this scenario with a
|
||||
// separate test.
|
||||
if (principal.isSystemPrincipal || principal.isNullPrincipal) {
|
||||
continue;
|
||||
}
|
||||
for (const preferred of PREFERRED_REMOTE_TYPES) {
|
||||
const msg = `ServiceWorker with principal ${principal.origin} and preferredRemoteType ${preferred}`;
|
||||
yield [
|
||||
msg,
|
||||
principal,
|
||||
REMOTE_WORKER_TYPE_SERVICE,
|
||||
false,
|
||||
false,
|
||||
preferred,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const testCase of getTestCase()) {
|
||||
const [msg, ...args] = testCase;
|
||||
equal(
|
||||
E10SUtils.getRemoteTypeForWorkerPrincipal(...args),
|
||||
E10SUtils.NOT_REMOTE,
|
||||
`Expect NOT_REMOTE on disabled multiprocess: ${msg}`
|
||||
);
|
||||
}
|
||||
});
|
|
@ -17,6 +17,7 @@ support-files =
|
|||
[test_CreditCard.js]
|
||||
[test_DeferredTask.js]
|
||||
skip-if = toolkit == 'android' || (os == 'mac' && os_version=='10.14') # osx: Bug 1550141;
|
||||
[test_E10SUtils_workers_remote_types.js]
|
||||
[test_FileUtils.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_FinderIterator.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче