-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[html] Test COEP derivation in shared workers
Co-authored-by: Simon Pieters <[email protected]>
- Loading branch information
1 parent
a13852d
commit 6eb96ee
Showing
2 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
24 changes: 24 additions & 0 deletions
24
html/cross-origin-embedder-policy/resources/shared-worker-fetch.js.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
body = b''' | ||
'use strict'; | ||
onconnect = (event) => { | ||
const port = event.ports[0]; | ||
port.onmessage = (event) => { | ||
fetch(event.data, { mode: 'no-cors' }) | ||
.then( | ||
() => port.postMessage('success'), | ||
() => port.postMessage('failure') | ||
); | ||
}; | ||
port.postMessage('ready'); | ||
};''' | ||
|
||
def main(request, response): | ||
headers = [(b'Content-Type', b'text/javascript')] | ||
|
||
for value in request.GET.get_list(b'value'): | ||
headers.append((b'Cross-Origin-Embedder-Policy', value)) | ||
|
||
return (200, headers, body) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<!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> | ||
<body> | ||
<p>Verify the Cross-Origin Embedder Policy for Shared Workers by performing a | ||
cross-domain "fetch" request for a resource that does not specify a COEP. Only | ||
Shared Workers with the default COEP should be able to successfully perform | ||
this operation.</p> | ||
<script> | ||
'use strict'; | ||
const testUrl = get_host_info().HTTPS_REMOTE_ORIGIN + | ||
'/html/cross-origin-embedder-policy/resources/empty-coep.py'; | ||
const workerHttpUrl = get_host_info().HTTPS_ORIGIN + | ||
'/html/cross-origin-embedder-policy/resources/shared-worker-fetch.js.py'; | ||
let workerBlobUrl; | ||
let workerDataUrl; | ||
|
||
promise_setup(() => { | ||
return fetch(workerHttpUrl) | ||
.then((response) => response.text()) | ||
.then((text) => { | ||
workerDataUrl = 'data:text/javascript;base64,' + btoa(text); | ||
workerBlobUrl = URL.createObjectURL( | ||
new Blob([text], { 'Content-Type': 'text/javascript' }) | ||
); | ||
}); | ||
}); | ||
|
||
/** | ||
* Create a Shared Worker within an iframe | ||
* | ||
* @param {object} t - a testharness.js subtest instance (used to reset global | ||
* state) | ||
* @param {string} ownerCoep - the Cross-Origin Embedder Policy of the iframe | ||
* @param {string} workerUrl - the URL from which the Shared Worker should be | ||
* created | ||
*/ | ||
function create(t, ownerCoep, workerUrl) { | ||
const iframe = document.createElement('iframe'); | ||
iframe.src = 'resources/empty-coep.py' + | ||
(ownerCoep ? '?value=' + ownerCoep : ''); | ||
|
||
return new Promise((resolve, reject) => { | ||
document.body.appendChild(iframe); | ||
t.add_cleanup(() => iframe.remove()); | ||
iframe.onload = () => resolve(iframe); | ||
}) | ||
.then((iframe) => { | ||
const sw = new iframe.contentWindow.SharedWorker(workerUrl); | ||
|
||
return new Promise((resolve) => { | ||
sw.port.addEventListener('message', () => resolve(sw), { once: true }); | ||
sw.port.start(); | ||
}); | ||
}); | ||
} | ||
|
||
/** | ||
* 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((t) => { | ||
return create(t, null, workerHttpUrl) | ||
.then((worker) => fetchFromWorker(worker, testUrl)) | ||
.then((result) => assert_equals(result, 'success')); | ||
}, 'default policy (derived from response)'); | ||
|
||
promise_test((t) => { | ||
return create(t, null, workerHttpUrl + '?value=require-corp') | ||
.then((worker) => fetchFromWorker(worker, testUrl)) | ||
.then((result) => assert_equals(result, 'failure')); | ||
}, '"require-corp" (derived from response)'); | ||
|
||
promise_test((t) => { | ||
return Promise.all([ | ||
create(t, null, workerBlobUrl), | ||
create(t, null, workerBlobUrl), | ||
create(t, null, workerBlobUrl) | ||
]) | ||
.then((workers) => fetchFromWorker(workers[0], testUrl)) | ||
.then((result) => assert_equals(result, 'success')); | ||
}, 'default policy (derived from owner set due to use of local scheme - blob URL)'); | ||
|
||
promise_test((t) => { | ||
return Promise.all([ | ||
create(t, null, workerBlobUrl), | ||
create(t, 'require-corp', workerBlobUrl), | ||
create(t, null, workerBlobUrl) | ||
]) | ||
.then((workers) => fetchFromWorker(workers[0], testUrl)) | ||
.then((result) => assert_equals(result, 'failure')); | ||
}, '"require-corp" (derived from owner set due to use of local scheme - blob URL)'); | ||
|
||
promise_test((t) => { | ||
return Promise.all([ | ||
create(t, null, workerDataUrl), | ||
create(t, null, workerDataUrl), | ||
create(t, null, workerDataUrl) | ||
]) | ||
.then((workers) => fetchFromWorker(workers[0], testUrl)) | ||
.then((result) => assert_equals(result, 'success')); | ||
}, 'default policy (derived from owner set due to use of local scheme - data URL)'); | ||
|
||
promise_test((t) => { | ||
return Promise.all([ | ||
create(t, null, workerDataUrl), | ||
create(t, 'require-corp', workerDataUrl), | ||
create(t, null, workerDataUrl) | ||
]) | ||
.then((workers) => fetchFromWorker(workers[0], testUrl)) | ||
.then((result) => assert_equals(result, 'failure')); | ||
}, '"require-corp" (derived from owner set due to use of local scheme - data URL)'); | ||
</script> | ||
</body> | ||
</html> |