Bug 1621690 [wpt PR 22192] - [COEP] CacheStorage > reporting API > WPT tests, a=testonly
authorarthursonzogni <arthursonzogni@chromium.org>
Sat, 14 Mar 2020 10:38:42 +0000
changeset 518822 60d63a608908a41bd5afe59007e73484f6729894
parent 518821 0f2f823b599293166b82ceecd15b452de8b48382
child 518823 decf30eff2bb575f3e1f906695cbe9a96996290e
push id37217
push userccoroiu@mozilla.com
push dateSun, 15 Mar 2020 21:37:59 +0000
treeherdermozilla-central@f9fc9427476e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1621690, 22192, 1059727, 1031542, 887967, 2096687, 749603
milestone76.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1621690 [wpt PR 22192] - [COEP] CacheStorage > reporting API > WPT tests, a=testonly Automatic update from web-platform-tests [COEP] CacheStorage > reporting API > WPT tests When a response is blocked by CORP because of the COEP header, check the reporting API is worker. This patch adds 4x2=8 new WPT tests. For every 4 context: - Document - SharedWorker - DedicatedWorker - ServiceWorker For the 2 headers: - Cross-Origin-Embedder-Policy - Cross-Origin-Embedder-Policy-Report-Only Bug: 1059727, 1031542, 887967 Change-Id: I797e36d0cfc982862e85dbc9a49c661fee46bf85 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096687 Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org> Reviewed-by: Yutaka Hirano <yhirano@chromium.org> Cr-Commit-Position: refs/heads/master@{#749603} -- wpt-commits: a24e1f169812387a3f332a075fe8fee28cef4588 wpt-pr: 22192
testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting.https.html
testing/web-platform/tests/html/cross-origin-embedder-policy/resources/report.py
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting.https.html
@@ -0,0 +1,237 @@
+<!doctype html>
+<html>
+<head>
+  <title> Check COEP report are send for CacheStorage requests</title>
+  <meta name="timeout" content="long">
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="/common/get-host-info.sub.js"></script>
+  <script src="/common/utils.js"></script>
+  <script src="/service-workers/service-worker/resources/test-helpers.sub.js">
+  </script>
+</head>
+<script>
+
+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);
+}
+
+let encode = function(url) {
+  return encodeURI(url).replace(/\;/g,"%3B");
+}
+
+const resource_path = (new URL("./resources", location)).pathname;
+const report_token= token();
+const report_endpoint_url = local(resource_path + `/report.py?key=${report_token}`)
+const endpoint =
+{
+   "group":"endpoint",
+   "max_age":3600,
+   "endpoints":[{ "url":report_endpoint_url.toString() }]
+};
+let endpoint_string =
+  JSON.stringify(endpoint)
+   .replace(/,/g, "\\,")
+   .replace(/\(/g, "\\\(")
+   .replace(/\)/g, "\\\)=");
+const header_report_to = `|header(report-to,${endpoint_string})`;
+const header_coep =
+  '|header(Cross-Origin-Embedder-Policy,require-corp;report-to="endpoint")';
+const header_coep_report_only =
+  '|header(Cross-Origin-Embedder-Policy-Report-Only,require-corp;report-to="endpoint")';
+const SW_SCOPE = local(resource_path + "/");
+const header_service_worker_allowed =
+  `|header(service-worker-allowed,${SW_SCOPE})`;
+
+const iframe_path = resource_path + "/iframe.html?pipe=";
+const worker_path = resource_path + "/universal-worker.js?pipe=";
+const image_url = remote("/images/blue.png");
+
+// This script attempt to load a COEP:require-corp CORP:undefined response from
+// the CacheStorage.
+//
+// Executed from different context:
+// - A Document
+// - A ServiceWorker
+// - A DedicatedWorker
+// - A SharedWorker
+//
+// The context has either COEP or COEP-Report-Only defined.
+const eval_script = `
+  (async function() {
+    try {
+      const cache = await caches.open('v1');
+      const request = new Request('${image_url}', { mode: 'no-cors' });
+      const response = await cache.match(request);
+    } catch(e) {
+    }
+  })()
+`;
+
+promise_setup(async (t) => {
+  const cache = await caches.open('v1');
+  const fetch_request = new Request(image_url, {mode: 'no-cors'});
+  const fetch_response = await fetch(fetch_request);
+  await cache.put(fetch_request, fetch_response);
+}, "Setup: store a CORS:cross-origin COEP:none response into CacheStorage")
+
+async function makeIframe(test, iframe_url) {
+  const iframe = document.createElement("iframe");
+  test.add_cleanup(() => iframe.remove());
+  iframe.src = iframe_url;
+  const iframe_loaded = new Promise(resolve => iframe.onload = resolve);
+  document.body.appendChild(iframe);
+  await iframe_loaded;
+  return iframe;
+}
+
+function wait(ms) {
+  return new Promise(resolve => step_timeout(resolve, ms));
+}
+
+async function fetchReport() {
+  const fetch_report_path = resource_path + `/report.py?key=${report_token}`;
+  for(let i = 0; i<10; ++i) {
+    const response = await fetch(encode(fetch_report_path));
+    const reports = await response.json();
+    if (reports.length == 0) {
+      wait(100);
+      continue;
+    }
+    if (reports.length != 1)
+      throw "Too many reports received";
+
+    return reports[0];
+  }
+  throw "Report not send";
+}
+
+// Remove parts of the URL that are differ at runtime.
+function normalize(url) {
+  url = new URL(url);
+  return url.origin + url.pathname;
+}
+
+promise_test(async (t) => {
+  const iframe_url =
+    local(encode(iframe_path + header_coep + header_report_to));
+  const iframe = await makeIframe(t, iframe_url);
+  iframe.contentWindow.postMessage(eval_script);
+  const report = await fetchReport();
+  assert_equals(report["body"]["blocked-url"], image_url.toString());
+  assert_equals(report["body"]["type"], "corp");
+  assert_equals(report["type"], "coep");
+  assert_equals(normalize(report["url"]), normalize(iframe_url.toString()));
+}, "COEP support on document.")
+
+promise_test(async (t) => {
+  const iframe_url =
+    local(encode(iframe_path + header_coep_report_only + header_report_to));
+  const iframe = await makeIframe(t, iframe_url);
+  iframe.contentWindow.postMessage(eval_script);
+  const report = await fetchReport();
+  assert_equals(report["body"]["blocked-url"], image_url.toString());
+  assert_equals(report["body"]["type"], "corp");
+  assert_equals(report["type"], "coep");
+  assert_equals(normalize(report["url"]), normalize(iframe_url.toString()));
+}, "COEP-Report-Only support on document.")
+
+promise_test(async (t) => {
+  const worker_url = local(encode(worker_path));
+  const iframe_url =
+    local(encode(iframe_path + header_coep + header_report_to));
+  dedicated_worker_script = `
+    (async function() {
+      const w = new Worker('${worker_url}');
+      w.postMessage(\`${eval_script}\`);
+    })();
+  `;
+  const iframe = await makeIframe(t, iframe_url);
+  iframe.contentWindow.postMessage(dedicated_worker_script);
+  const report = await fetchReport();
+  assert_equals(report["body"]["blocked-url"], image_url.toString());
+  assert_equals(report["body"]["type"], "corp");
+  assert_equals(report["type"], "coep");
+  assert_equals(normalize(report["url"]), normalize(worker_url.toString()));
+}, "COEP support on DedicatedWorker.")
+
+promise_test(async (t) => {
+  const worker_url = local(encode(worker_path));
+  const iframe_url =
+    local(encode(iframe_path + header_coep_report_only + header_report_to));
+  dedicated_worker_script = `
+    (async function() {
+      const w = new Worker('${worker_url}');
+      w.postMessage(\`${eval_script}\`);
+    })();
+  `;
+  const iframe = await makeIframe(t, iframe_url);
+  iframe.contentWindow.postMessage(dedicated_worker_script);
+  const report = await fetchReport();
+  assert_equals(report["body"]["blocked-url"], image_url.toString());
+  assert_equals(report["body"]["type"], "corp");
+  assert_equals(report["type"], "coep");
+  assert_equals(normalize(report["url"]), normalize(worker_url.toString()));
+}, "COEP-Report-Only support on DedicatedWorker.")
+
+promise_test(async (t) => {
+  const worker_url =
+    local(encode(worker_path + header_coep + header_report_to));
+  const worker = new Worker(worker_url);
+  worker.postMessage(eval_script);
+  const report = await fetchReport();
+  assert_equals(report["body"]["blocked-url"], image_url.toString());
+  assert_equals(report["body"]["type"], "corp");
+  assert_equals(report["type"], "coep");
+  assert_equals(normalize(report["url"]), normalize(worker_url.toString()));
+}, "COEP support on SharedWorker.")
+
+promise_test(async (t) => {
+  const worker_url =
+    local(encode(worker_path + header_coep_report_only + header_report_to));
+  const worker = new Worker(worker_url);
+  worker.postMessage(eval_script);
+  const report = await fetchReport();
+  assert_equals(report["body"]["blocked-url"], image_url.toString());
+  assert_equals(report["body"]["type"], "corp");
+  assert_equals(report["type"], "coep");
+  assert_equals(normalize(report["url"]), normalize(worker_url.toString()));
+}, "COEP-Report-Only support on SharedWorker.")
+
+promise_test(async (t) => {
+  const worker_url =
+    local(encode(worker_path + header_coep + header_service_worker_allowed));
+  const reg =
+    await service_worker_unregister_and_register(t, worker_url, SW_SCOPE);
+  add_completion_callback(() => reg.unregister());
+  const worker = reg.installing || reg.waiting || reg.active;
+  worker.postMessage(eval_script);
+  const report = await fetchReport();
+  assert_equals(report["body"]["blocked-url"], image_url.toString());
+  assert_equals(report["body"]["type"], "corp");
+  assert_equals(report["type"], "coep");
+  assert_equals(normalize(report["url"]), normalize(worker_url.toString()));
+}, "COEP support on ServiceWorker.")
+
+promise_test(async (t) => {
+  const worker_url =
+    local(encode(worker_path + header_coep_report_only + header_service_worker_allowed))
+  const reg =
+    await service_worker_unregister_and_register(t, worker_url, SW_SCOPE);
+  add_completion_callback(() => reg.unregister());
+  const worker = reg.installing || reg.waiting || reg.active;
+  worker.postMessage(eval_script);
+  const report = await fetchReport();
+  assert_equals(report["body"]["blocked-url"], image_url.toString());
+  assert_equals(report["body"]["type"], "corp");
+  assert_equals(report["type"], "coep");
+  assert_equals(normalize(report["url"]), normalize(worker_url.toString()));
+}, "COEP-Report-Only support on ServiceWorker.")
+
+</script>
+</html>
--- a/testing/web-platform/tests/html/cross-origin-embedder-policy/resources/report.py
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/resources/report.py
@@ -3,31 +3,33 @@ import json
 
 def main(request, response):
     if request.method == 'OPTIONS':
         # CORS preflight
         response.headers.set('Access-Control-Allow-Origin', '*')
         response.headers.set('Access-Control-Allow-Methods', 'POST')
         response.headers.set('Access-Control-Allow-Headers', 'content-type')
         return ''
-
+    response.headers.set('Access-Control-Allow-Origin', '*')
     uuidMap = {
         'endpoint': '01234567-0123-0123-0123-0123456789AB',
         'report-only-endpoint': '01234567-0123-0123-0123-0123456789CD'
     }
+    key = 0;
+    if 'endpoint' in request.GET:
+        key = uuidMap[request.GET['endpoint']]
 
-    response.headers.set('Access-Control-Allow-Origin', '*')
-    endpoint = request.GET.first('endpoint')
-    if endpoint not in uuidMap:
+    if 'key' in request.GET:
+        key = request.GET['key']
+
+    if key == 0:
         response.status = 400
         return 'invalid endpoint'
 
     path = '/'.join(request.url_parts.path.split('/')[:-1]) + '/'
-    key = uuidMap[endpoint]
-
     if request.method == 'POST':
         reports = request.server.stash.take(key, path) or []
         for report in json.loads(request.body):
             reports.append(report)
         request.server.stash.put(key, reports, path)
         return 'done'
 
     if request.method == 'GET':