<!doctype html>
<html>
<meta charset="utf-8">
<title>COEP - policy derivation for Shared Workers</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/worker-support.js"></script>
<body>
<p>Verify the Document Isolation Policy for Shared Workers by performing a
cross-origin "fetch" request for a resource that does not specify CORP. Only
Shared Workers with the default DIP should be able to successfully perform
this operation.</p>
<script>
'use strict';
function makeWorkerUrl(options) {
return resolveUrl("resources/shared-worker-fetch.js.py", options);
}
/**
* Create a Shared Worker within an iframe
*
* @param {object} t - a testharness.js subtest instance (used to reset global
* state)
* @param {string} url - the URL from which the Shared Worker should be
* created
* @param {string} options.ownerDip - the Document Isolation Policy of the
iframe
*/
async function createWorker(t, url, options) {
const { ownerDip } = options || {};
const frameUrl = resolveUrl("/common/blank.html", { dip: ownerDip });
const iframe = await withIframe(t, frameUrl);
const sw = new iframe.contentWindow.SharedWorker(url);
sw.onerror = t.unreached_func('SharedWorker.onerror should not be called');
await new Promise((resolve) => {
sw.port.addEventListener('message', resolve, { once: true });
sw.port.start();
});
return sw;
}
/**
* Instruct a Shared Worker to fetch from a specified URL and report on the
* success of the operation.
*
* @param {SharedWorker} worker
* @param {string} url - the URL that the worker should fetch
*/
function fetchFromWorker(worker, url) {
return new Promise((resolve) => {
worker.port.postMessage(url);
worker.port.addEventListener(
'message', (event) => resolve(event.data), { once: true }
);
});
};
promise_test(async (t) => {
const worker = await createWorker(t, makeWorkerUrl());
const result = await fetchFromWorker(worker,
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'success');
}, 'default policy (derived from response)');
promise_test(async (t) => {
const worker = await createWorker(t, makeWorkerUrl({ dip: 'isolate-and-require-corp' }));
const result = await fetchFromWorker(worker,
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'failure');
}, '"isolate-and-require-corp" (derived from response)');
promise_test(async (t) => {
const blobUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
scheme: "blob",
});
const workers = await Promise.all([
createWorker(t, blobUrl),
createWorker(t, blobUrl),
createWorker(t, blobUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'success');
}, 'default policy (derived from owner set due to use of local scheme - blob URL)');
promise_test(async (t) => {
const blobUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
creatorDip: "isolate-and-require-corp",
scheme: "blob",
});
const workers = await Promise.all([
createWorker(t, blobUrl),
createWorker(t, blobUrl),
createWorker(t, blobUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'failure');
}, 'isolate-and-require-corp (derived from blob URL creator)');
promise_test(async (t) => {
const blobUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
scheme: "blob",
});
const workers = await Promise.all([
createWorker(t, blobUrl),
createWorker(t, blobUrl, { ownerDip: 'isolate-and-require-corp' }),
createWorker(t, blobUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'failure');
}, '"isolate-and-require-corp" (derived from owner set due to use of local scheme - blob URL)');
promise_test(async (t) => {
const dataUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
scheme: "data",
});
const workers = await Promise.all([
createWorker(t, dataUrl),
createWorker(t, dataUrl),
createWorker(t, dataUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'success');
}, 'default policy (derived from owner set due to use of local scheme - data URL)');
promise_test(async (t) => {
const dataUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
creatorDip: "isolate-and-require-corp",
scheme: "data",
});
const workers = await Promise.all([
createWorker(t, dataUrl),
createWorker(t, dataUrl),
createWorker(t, dataUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'success');
}, 'default policy (not derived from data URL creator)');
promise_test(async (t) => {
const dataUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
scheme: "data",
});
const workers = await Promise.all([
createWorker(t, dataUrl),
createWorker(t, dataUrl, { ownerdip: 'isolate-and-require-corp' }),
createWorker(t, dataUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'failure');
}, '"isolate-and-require-corp" (derived from owner set due to use of local scheme - data URL)');
promise_test(async (t) => {
const filesystemUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
scheme: "filesystem",
});
const workers = await Promise.all([
createWorker(t, filesystemUrl),
createWorker(t, filesystemUrl),
createWorker(t, filesystemUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'success');
}, 'default policy (derived from owner set due to use of local scheme - filesystem URL)');
promise_test(async (t) => {
const filesystemUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
creatorDip: "isolate-and-require-corp",
scheme: "filesystem",
});
const workers = await Promise.all([
createWorker(t, filesystemUrl),
createWorker(t, filesystemUrl),
createWorker(t, filesystemUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'failure');
}, 'isolate-and-require-corp (derived from filesystem URL creator)');
promise_test(async (t) => {
const filesystemUrl = await createLocalUrl(t, {
url: makeWorkerUrl(),
scheme: "filesystem",
});
const workers = await Promise.all([
createWorker(t, filesystemUrl),
createWorker(t, filesystemUrl, { ownerDip: 'isolate-and-require-corp' }),
createWorker(t, filesystemUrl),
]);
const result = await fetchFromWorker(workers[0],
get_host_info().HTTPS_REMOTE_ORIGIN+"/html/document-isolation-policy/resources/nothing-no-corp.js");
assert_equals(result, 'failure');
}, '"isolate-and-require-corp" (derived from owner set due to use of local scheme - filesystem URL)');
</script>
</body>
</html>