| <!doctype html> |
| <html> |
| <title> Retrieve resources from CacheStorage with Cross-Origin-Embedder-Policy: require-corp</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> |
| |
| /* |
| This document does NOT define the Cross-Origin-Embedder-Policy header. |
| Cross-Origin Embedder Policy Editor's draft: https://mikewest.github.io/corpp/ |
| |
| This test is retrieving same-origin and cross-origin resources from the |
| CacheStorage. The resources are generated from the ServiceWorker or from the |
| network with the header Cross-Origin-Resource-Policy being one of: |
| - 'same-origin' |
| - 'cross-origin' |
| - <undefined> |
| */ |
| |
| promise_test(async (t) => { |
| const SCOPE = new URL(location.href).pathname; |
| const SCRIPT = |
| 'resources/sw-store-to-cache-storage.js?' + |
| `pipe=header(service-worker-allowed,${SCOPE})`; |
| |
| const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE); |
| add_completion_callback(() => reg.unregister()); |
| await new Promise(resolve => { |
| navigator.serviceWorker.addEventListener('controllerchange', resolve); |
| }); |
| }, 'setting up'); |
| |
| function remote(path) { |
| const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN; |
| return new URL(path, REMOTE_ORIGIN); |
| } |
| |
| function local(path) { |
| return new URL(path, location.origin); |
| } |
| |
| // Send a message to the currently active ServiceWorker and wait for its |
| // response. |
| function executeCommandInServiceWorker(command) { |
| return new Promise(resolve => { |
| navigator.serviceWorker.addEventListener('message', e => resolve(e.data)); |
| navigator.serviceWorker.controller.postMessage(command); |
| }); |
| } |
| |
| // Try loading an image from a |response|. Return a Promise resolving or |
| // rejecting depending on the image loading result. |
| const loadFailure = {name: "Image.onerror"}; |
| function readImageFromResponse(response) { |
| return new Promise((resolve, reject) => { |
| const img = document.createElement("img"); |
| img.onload = resolve.bind(this, ""); |
| img.onerror = reject.bind(this, loadFailure); |
| response.blob().then(blob => { |
| img.src = URL.createObjectURL(blob); |
| document.body.appendChild(img); |
| }) |
| }) |
| } |
| |
| const image_path = "/images/blue.png?pipe="; |
| |
| const corp_header = { |
| "":"", |
| "corp-undefined": "", |
| "corp-same-origin": "|header(Cross-Origin-Resource-Policy,same-origin)", |
| "corp-cross-origin": "|header(Cross-Origin-Resource-Policy,cross-origin)", |
| } |
| |
| const cors_header = { |
| "":"", |
| "cors-disabled": "", |
| "cors-enabled": "|header(Access-Control-Allow-Origin,*)", |
| } |
| |
| function test( |
| // Test parameters: |
| request_source, request_origin, request_mode, response_cors, response_corp, |
| // Test expectations: |
| response_stored, response_type) { |
| promise_test(async (t) => { |
| // 0. Start from an empty CacheStorage. |
| await caches.delete("v1"); |
| |
| // 1. Make the ServiceWorker to request the ressource and store it into the |
| // CacheStorage. |
| const path = image_path + |
| corp_header[response_corp] + |
| cors_header[response_cors]; |
| const url = (request_origin === "same-origin" ? local : remote)(path); |
| const command = { |
| url: url.href, |
| mode: request_mode, |
| source: request_source, |
| }; |
| |
| assert_equals(await executeCommandInServiceWorker(command), response_stored); |
| if (response_stored === "not-stored") { |
| return; |
| } |
| |
| // 2. Make this document to retrieve it from the CacheStorage. |
| const cache = await caches.open('v1'); |
| const response = await cache.match(url); |
| |
| assert_equals(response.type, response_type); |
| |
| if (request_source === "service-worker") { |
| assert_equals("foo", await response.text()); |
| return; |
| } |
| |
| // Opaque response are not readable. |
| if (response_type === "opaque") { |
| await promise_rejects_exactly(t, loadFailure, readImageFromResponse(response)); |
| return; |
| } |
| |
| await readImageFromResponse(response); |
| }, `Fetch ${request_origin} ${request_mode} ${response_cors} ${response_corp} from ${request_source} and CacheStorage.`) |
| } |
| |
| // Responses generated from the ServiceWorker. |
| { |
| test("service-worker", "cross-origin", "cors", "", "", "stored", "default"); |
| test("service-worker", "cross-origin", "no-cors", "", "", "stored", "default"); |
| test("service-worker", "same-origin", "cors", "", "", "stored", "default"); |
| test("service-worker", "same-origin", "no-cors", "", "", "stored", "default"); |
| } |
| |
| // Responses generated from a same-origin server. |
| { |
| const t = test.bind(this, "network", "same-origin"); |
| t("cors", "cors-disabled", "corp-cross-origin", "stored", "basic"); |
| t("cors", "cors-disabled", "corp-same-origin", "stored", "basic"); |
| t("cors", "cors-disabled", "corp-undefined", "stored", "basic"); |
| t("cors", "cors-enabled", "corp-cross-origin", "stored", "basic"); |
| t("cors", "cors-enabled", "corp-same-origin", "stored", "basic"); |
| t("cors", "cors-enabled", "corp-undefined", "stored", "basic"); |
| t("no-cors", "cors-disabled", "corp-cross-origin", "stored", "basic"); |
| t("no-cors", "cors-disabled", "corp-same-origin", "stored", "basic"); |
| t("no-cors", "cors-disabled", "corp-undefined", "stored", "basic"); |
| t("no-cors", "cors-enabled", "corp-cross-origin", "stored", "basic"); |
| t("no-cors", "cors-enabled", "corp-same-origin", "stored", "basic"); |
| t("no-cors", "cors-enabled", "corp-undefined", "stored", "basic"); |
| } |
| |
| // Responses generated from a cross-origin server. |
| { |
| const t = test.bind(this, "network", "cross-origin"); |
| t("cors", "cors-disabled", "corp-cross-origin", "not-stored"); |
| t("cors", "cors-disabled", "corp-same-origin", "not-stored"); |
| t("cors", "cors-disabled", "corp-undefined", "not-stored"); |
| t("cors", "cors-enabled", "corp-cross-origin", "stored", "cors"); |
| t("cors", "cors-enabled", "corp-same-origin", "stored", "cors"); |
| t("cors", "cors-enabled", "corp-undefined", "stored", "cors"); |
| t("no-cors", "cors-disabled", "corp-cross-origin", "stored", "opaque"); |
| t("no-cors", "cors-disabled", "corp-same-origin", "not-stored"); |
| t("no-cors", "cors-disabled", "corp-undefined", "stored", "opaque"); |
| t("no-cors", "cors-enabled", "corp-cross-origin", "stored", "opaque"); |
| t("no-cors", "cors-enabled", "corp-same-origin", "not-stored"); |
| t("no-cors", "cors-enabled", "corp-undefined", "stored", "opaque"); |
| } |
| |
| </script> |
| </html> |