| <!doctype html> |
| <html> |
| <title> Check enforcement of COEP in a ServiceWorker using CacheStorage. </title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/common/get-host-info.sub.js"></script> |
| <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> |
| <script> |
| // See also: ./dedicated-worker-cache-storage.https.html |
| |
| function remote(path) { |
| const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN; |
| return new URL(path, REMOTE_ORIGIN); |
| } |
| |
| const iframe_path = "./resources/iframe.html?pipe="; |
| const service_worker_path = "./resources/universal-worker.js?pipe="; |
| const ressource_path = "/images/blue.png?pipe="; |
| |
| const coep_header= { |
| "coep-none" : "", |
| "coep-require-corp" : "|header(Cross-Origin-Embedder-Policy,require-corp)", |
| } |
| |
| const corp_header = { |
| "corp-undefined" : "", |
| "corp-cross-origin" : "|header(Cross-Origin-Resource-Policy,cross-origin)", |
| } |
| |
| // Send a message to the |worker| and wait for its response. |
| function executeCommandInServiceWorker(worker, command) { |
| const channel = new MessageChannel(); |
| const response = new Promise(resolve => channel.port1.onmessage = resolve); |
| worker.postMessage(command, [ channel.port2 ]); |
| return response; |
| } |
| |
| // Check enforcement of COEP in a ServiceWorker using CacheStorage. |
| // |
| // 1) Fetch a response from a document with COEP:none. Store it in the |
| // CacheStorage. The response is cross-origin without any CORS header. |
| // 2) From a ServiceWorker, retrieve the response from the CacheStorage. |
| // |
| // Test parameters: |
| // - |worker_coep| the COEP header of the ServiceWorker's script response. |
| // - |response_corp| the CORP header of the response. |
| // |
| // Test expectations: |
| // |loaded| is true whenever the worker is able to fetch the response from |
| // the CacheStorage. According to the specification: |
| // https://mikewest.github.io/corpp/#initialize-embedder-policy-for-global |
| // it must be false when: |
| // - |worker_coep| is 'coep-require-corp' and |
| // - |response-corp| is 'corp-undefined'. |
| function check( |
| // Test parameters: |
| worker_coep, |
| response_corp, |
| |
| // Test expectations: |
| loaded) { |
| |
| promise_test(async (t) => { |
| // 1) Fetch a response from a document with COEP:none. Store it in the |
| // CacheStorage. The response is cross-origin without any CORS header. |
| const resource_path = ressource_path + corp_header[response_corp]; |
| const resource_url = remote(resource_path); |
| const fetch_request = new Request(resource_url, {mode: 'no-cors'}); |
| const cache = await caches.open('v1'); |
| const fetch_response = await fetch(fetch_request); |
| await cache.put(fetch_request, fetch_response); |
| |
| // 2) Start a ServiceWorker. |
| const SCOPE= new URL(location.href).pathname; |
| const service_worker_allowed = `|header(service-worker-allowed,${SCOPE})`; |
| const SCRIPT = |
| service_worker_path + |
| coep_header[worker_coep] + |
| service_worker_allowed; |
| |
| const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE); |
| add_completion_callback(() => reg.unregister()); |
| |
| // Start talking to the ServiceWorker, no matter its state. |
| const worker = reg.installing || reg.waiting || reg.active; |
| |
| // 3) From the service worker, try to retrieve the response from the |
| // CacheStorage. |
| const response = executeCommandInServiceWorker(worker, ` |
| (async function() { |
| const cache = await caches.open('v1'); |
| const request = new Request('${resource_url}', { |
| mode: 'no-cors' |
| }); |
| try { |
| const response = await cache.match(request); |
| message.ports[0].postMessage('success'); |
| } catch(error) { |
| message.ports[0].postMessage('error'); |
| } |
| })() |
| `); |
| const {data} = await response; |
| assert_equals(data === "success", loaded); |
| }, `A ServiceWorker with ${worker_coep} use CacheStorage to get a ${response_corp} response.`) |
| } |
| |
| // ------------------------------------------------------ |
| // worker_coep , response_corp , loaded |
| // ------------------------------------------------------ |
| check("coep-none" , "corp-undefined" , true); |
| check("coep-none" , "corp-cross-origin" , true); |
| check("coep-require-corp" , "corp-undefined" , false); |
| check("coep-require-corp" , "corp-cross-origin" , true); |
| |
| </script> |
| </html> |