tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

isolate-and-require-corp-load-from-cache-storage.tentative.https.html (6487B)


      1 <!doctype html>
      2 <html>
      3 <title> Retrieve resources from CacheStorage with Cross-Origin-Embedder-Policy: require-corp</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script src="/common/get-host-info.sub.js"></script>
      7 <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
      8 <script>
      9 
     10 /*
     11  This document has the header Document-Isolation-Policy: isolate-and-require-corp.
     12 
     13  This test is retrieving same-origin and cross-origin resources from the
     14  CacheStorage. The resources are generated from the ServiceWorker or from the
     15  network with the header Cross-Origin-Resource-Policy being one of:
     16    - 'same-origin'
     17    - 'cross-origin'
     18    - <undefined>
     19 */
     20 
     21 promise_test(async (t) => {
     22  const SCOPE = new URL(location.href).pathname;
     23  const SCRIPT =
     24    'resources/sw-store-to-cache-storage.js?' +
     25    `pipe=header(service-worker-allowed,${SCOPE})`;
     26 
     27  const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE);
     28  add_completion_callback(() => reg.unregister());
     29  await new Promise(resolve => {
     30    navigator.serviceWorker.addEventListener('controllerchange', resolve);
     31  });
     32 }, 'setting up');
     33 
     34 function remote(path) {
     35  const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
     36  return new URL(path, REMOTE_ORIGIN);
     37 }
     38 
     39 function local(path) {
     40  return new URL(path, location.origin);
     41 }
     42 
     43 // Send a message to the currently active ServiceWorker and wait for its
     44 // response.
     45 function executeCommandInServiceWorker(command) {
     46  return new Promise(resolve => {
     47    navigator.serviceWorker.addEventListener('message', e => resolve(e.data));
     48    navigator.serviceWorker.controller.postMessage(command);
     49  });
     50 }
     51 
     52 // Try loading an image from a |response|. Return a Promise resolving or
     53 // rejecting depending on the image loading result.
     54 const loadFailure = {name: "Image.onerror"};
     55 function readImageFromResponse(response) {
     56  return new Promise((resolve, reject) => {
     57    const img = document.createElement("img");
     58    img.onload = resolve.bind(this, "");
     59    img.onerror = reject.bind(this, loadFailure);
     60    response.blob().then(blob => {
     61      img.src = URL.createObjectURL(blob);
     62      document.body.appendChild(img);
     63    })
     64  })
     65 }
     66 
     67 const image_path = "/images/blue.png?pipe=";
     68 
     69 const corp_header = {
     70  "":"",
     71  "corp-undefined": "",
     72  "corp-same-origin": "|header(Cross-Origin-Resource-Policy,same-origin)",
     73  "corp-cross-origin": "|header(Cross-Origin-Resource-Policy,cross-origin)",
     74 }
     75 
     76 const cors_header = {
     77  "":"",
     78  "cors-disabled": "",
     79  "cors-enabled": "|header(Access-Control-Allow-Origin,*)",
     80 }
     81 
     82 function test(
     83  // Test parameters:
     84  request_source, request_origin, request_mode, response_cors, response_corp,
     85  // Test expectations:
     86  response_stored, response_type) {
     87  promise_test(async (t) => {
     88    // 0. Start from an empty CacheStorage.
     89    await caches.delete("v1");
     90 
     91    // 1. Store a cross-origin no-cors response generated from the SW into the
     92    //    CacheStorage.
     93    const path = image_path +
     94      corp_header[response_corp] +
     95      cors_header[response_cors];
     96    const url = (request_origin === "same-origin" ? local : remote)(path);
     97    const command = {
     98      url: url.href,
     99      mode: request_mode,
    100      source: request_source,
    101    };
    102 
    103    assert_equals(await executeCommandInServiceWorker(command), response_stored);
    104    if (response_stored === "not-stored") {
    105      return;
    106    }
    107 
    108    // 2. Retrieve it from the CacheStorage.
    109    const cache = await caches.open('v1');
    110 
    111    if (response_type === 'error') {
    112      await promise_rejects_js(t, TypeError, cache.match(url));
    113      return;
    114    }
    115 
    116    const response = await cache.match(url);
    117 
    118    assert_equals(response.type, response_type);
    119 
    120    if (request_source === "service-worker") {
    121      assert_equals("foo", await response.text());
    122      return;
    123    }
    124 
    125    // Opaque response can't be read from the document.
    126    if (response_type === "opaque") {
    127      await promise_rejects_exactly(t, loadFailure, readImageFromResponse(response));
    128      return;
    129    }
    130 
    131    await readImageFromResponse(response);
    132  }, `Fetch ${request_origin} ${request_mode} ${response_cors} ${response_corp} from ${request_source} and CacheStorage.`)
    133 }
    134 
    135 // Responses generated from the ServiceWorker.
    136 {
    137  test("service-worker", "cross-origin", "cors", "", "", "stored", "default");
    138  test("service-worker", "cross-origin", "no-cors", "", "", "stored", "default");
    139  test("service-worker", "same-origin", "cors", "", "", "stored", "default");
    140  test("service-worker", "same-origin", "no-cors", "", "", "stored", "default");
    141 }
    142 
    143 // Responses generated from a same-origin server.
    144 {
    145  const t = test.bind(this, "network", "same-origin");
    146  t("cors", "cors-disabled", "corp-cross-origin", "stored", "basic");
    147  t("cors", "cors-disabled", "corp-same-origin", "stored", "basic");
    148  t("cors", "cors-disabled", "corp-undefined", "stored", "basic");
    149  t("cors", "cors-enabled", "corp-cross-origin", "stored", "basic");
    150  t("cors", "cors-enabled", "corp-same-origin", "stored", "basic");
    151  t("cors", "cors-enabled", "corp-undefined", "stored", "basic");
    152  t("no-cors", "cors-disabled", "corp-cross-origin", "stored", "basic");
    153  t("no-cors", "cors-disabled", "corp-same-origin", "stored", "basic");
    154  t("no-cors", "cors-disabled", "corp-undefined", "stored", "basic");
    155  t("no-cors", "cors-enabled", "corp-cross-origin", "stored", "basic");
    156  t("no-cors", "cors-enabled", "corp-same-origin", "stored", "basic");
    157  t("no-cors", "cors-enabled", "corp-undefined", "stored", "basic");
    158 }
    159 
    160 // Responses generated from a cross-origin server.
    161 {
    162  const t = test.bind(this, "network", "cross-origin");
    163  t("cors", "cors-disabled", "corp-cross-origin", "not-stored");
    164  t("cors", "cors-disabled", "corp-same-origin", "not-stored");
    165  t("cors", "cors-disabled", "corp-undefined", "not-stored");
    166  t("cors", "cors-enabled", "corp-cross-origin", "stored", "cors");
    167  t("cors", "cors-enabled", "corp-same-origin", "stored", "cors");
    168  t("cors", "cors-enabled", "corp-undefined", "stored", "cors");
    169  t("no-cors", "cors-disabled", "corp-cross-origin", "stored", "opaque");
    170  t("no-cors", "cors-disabled", "corp-same-origin", "not-stored");
    171  t("no-cors", "cors-disabled", "corp-undefined", "stored", "error");
    172  t("no-cors", "cors-enabled", "corp-cross-origin", "stored", "opaque");
    173  t("no-cors", "cors-enabled", "corp-same-origin", "not-stored");
    174  t("no-cors", "cors-enabled", "corp-undefined", "stored", "error");
    175 }
    176 
    177 </script>
    178 </html>