summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/fetch/cross-origin-resource-policy
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/fetch/cross-origin-resource-policy')
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch-in-iframe.html67
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch.any.js76
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch.https.any.js56
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/iframe-loads.html46
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/image-loads.html54
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/green.pngbin0 -> 87 bytes
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/hello.py6
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/iframe.py5
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/iframeFetch.html19
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/image.py22
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/redirect.py6
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/script.py6
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/scheme-restriction.any.js7
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/scheme-restriction.https.window.js13
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/script-loads.html52
-rw-r--r--testing/web-platform/tests/fetch/cross-origin-resource-policy/syntax.any.js19
16 files changed, 454 insertions, 0 deletions
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch-in-iframe.html b/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch-in-iframe.html
new file mode 100644
index 0000000000..cc6a3a81bc
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch-in-iframe.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+</head>
+<body>
+ <script>
+const host = get_host_info();
+const remoteBaseURL = host.HTTP_REMOTE_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
+const notSameSiteBaseURL = host.HTTP_NOTSAMESITE_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
+const localBaseURL = host.HTTP_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
+
+function with_iframe(url)
+{
+ return new Promise(function(resolve) {
+ var frame = document.createElement('iframe');
+ frame.src = url;
+ frame.onload = function() { resolve(frame); };
+ document.body.appendChild(frame);
+ });
+}
+
+function loadIFrameAndFetch(iframeURL, fetchURL, expectedFetchResult, title)
+{
+ promise_test(async () => {
+ const frame = await with_iframe(iframeURL);
+ let receiveMessage;
+ const promise = new Promise((resolve, reject) => {
+ receiveMessage = (event) => {
+ if (event.data !== expectedFetchResult) {
+ reject("Received unexpected message " + event.data);
+ return;
+ }
+ resolve();
+ }
+ window.addEventListener("message", receiveMessage, false);
+ });
+ frame.contentWindow.postMessage(fetchURL, "*");
+ return promise.finally(() => {
+ frame.remove();
+ window.removeEventListener("message", receiveMessage, false);
+ });
+ }, title);
+}
+
+// This above data URL should be equivalent to resources/iframeFetch.html
+var dataIFrameURL = "data:text/html;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sPgo8aGVhZD4KICAgIDxzY3JpcHQ+CiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc01lc3NhZ2UoZXZlbnQpCiAgICAgICAgewogICAgICAgICAgICBmZXRjaChldmVudC5kYXRhLCB7IG1vZGU6ICJuby1jb3JzIiB9KS50aGVuKCgpID0+IHsKICAgICAgICAgICAgICAgIHBhcmVudC5wb3N0TWVzc2FnZSgib2siLCAiKiIpOwogICAgICAgICAgICB9LCAoKSA9PiB7CiAgICAgICAgICAgICAgICBwYXJlbnQucG9zdE1lc3NhZ2UoImtvIiwgIioiKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgcHJvY2Vzc01lc3NhZ2UsIGZhbHNlKTsKICAgIDwvc2NyaXB0Pgo8L2hlYWQ+Cjxib2R5PgogICAgPGgzPlRoZSBpZnJhbWUgbWFraW5nIGEgc2FtZSBvcmlnaW4gZmV0Y2ggY2FsbC48L2gzPgo8L2JvZHk+CjwvaHRtbD4K";
+
+loadIFrameAndFetch(dataIFrameURL, localBaseURL + "resources/hello.py?corp=same-origin", "ko",
+ "Cross-origin fetch in a data: iframe load fails if the server blocks cross-origin loads with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+loadIFrameAndFetch(dataIFrameURL, localBaseURL + "resources/hello.py?corp=same-site", "ko",
+ "Cross-origin fetch in a data: iframe load fails if the server blocks cross-origin loads with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+loadIFrameAndFetch(remoteBaseURL + "resources/iframeFetch.html", localBaseURL + "resources/hello.py?corp=same-origin", "ko",
+ "Cross-origin fetch in a cross origin iframe load fails if the server blocks cross-origin loads with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+loadIFrameAndFetch(notSameSiteBaseURL + "resources/iframeFetch.html", localBaseURL + "resources/hello.py?corp=same-site", "ko",
+ "Cross-origin fetch in a cross origin iframe load fails if the server blocks cross-origin loads with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+loadIFrameAndFetch(remoteBaseURL + "resources/iframeFetch.html", remoteBaseURL + "resources/hello.py?corp=same-origin", "ok",
+ "Same-origin fetch in a cross origin iframe load succeeds if the server blocks cross-origin loads with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch.any.js b/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch.any.js
new file mode 100644
index 0000000000..64a7bfeb86
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch.any.js
@@ -0,0 +1,76 @@
+// META: timeout=long
+// META: global=window,dedicatedworker,sharedworker
+// META: script=/common/get-host-info.sub.js
+
+const host = get_host_info();
+const path = "/fetch/cross-origin-resource-policy/";
+const localBaseURL = host.HTTP_ORIGIN + path;
+const sameSiteBaseURL = "http://" + host.ORIGINAL_HOST + ":" + host.HTTP_PORT2 + path;
+const notSameSiteBaseURL = host.HTTP_NOTSAMESITE_ORIGIN + path;
+const httpsBaseURL = host.HTTPS_ORIGIN + path;
+
+promise_test(async () => {
+ const response = await fetch("./resources/hello.py?corp=same-origin");
+ assert_equals(await response.text(), "hello");
+}, "Same-origin fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+promise_test(async () => {
+ const response = await fetch("./resources/hello.py?corp=same-site");
+ assert_equals(await response.text(), "hello");
+}, "Same-origin fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+promise_test(async (test) => {
+ const response = await fetch(notSameSiteBaseURL + "resources/hello.py?corp=same-origin");
+ assert_equals(await response.text(), "hello");
+}, "Cross-origin cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+promise_test(async (test) => {
+ const response = await fetch(notSameSiteBaseURL + "resources/hello.py?corp=same-site");
+ assert_equals(await response.text(), "hello");
+}, "Cross-origin cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+promise_test((test) => {
+ const remoteURL = notSameSiteBaseURL + "resources/hello.py?corp=same-origin";
+ return promise_rejects_js(test, TypeError, fetch(remoteURL, { mode : "no-cors" }));
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+promise_test((test) => {
+ const remoteURL = notSameSiteBaseURL + "resources/hello.py?corp=same-site";
+ return promise_rejects_js(test, TypeError, fetch(remoteURL, { mode: "no-cors" }));
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+promise_test((test) => {
+ const remoteURL = httpsBaseURL + "resources/hello.py?corp=same-site";
+ return promise_rejects_js(test, TypeError, fetch(remoteURL, { mode: "no-cors" }));
+}, "Cross-scheme (HTTP to HTTPS) no-cors fetch to a same-site URL with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+promise_test((test) => {
+ const remoteURL = httpsBaseURL + "resources/hello.py?corp=same-origin";
+ return promise_rejects_js(test, TypeError, fetch(remoteURL, { mode : "no-cors" }));
+}, "Cross-origin no-cors fetch to a same-site URL with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+promise_test(async (test) => {
+ const remoteSameSiteURL = sameSiteBaseURL + "resources/hello.py?corp=same-site";
+
+ await fetch(remoteSameSiteURL, { mode: "no-cors" });
+
+ return promise_rejects_js(test, TypeError, fetch(sameSiteBaseURL + "resources/hello.py?corp=same-origin", { mode: "no-cors" }));
+}, "Valid cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+promise_test((test) => {
+ const finalURL = notSameSiteBaseURL + "resources/hello.py?corp=same-origin";
+ return promise_rejects_js(test, TypeError, fetch("resources/redirect.py?redirectTo=" + encodeURIComponent(finalURL), { mode: "no-cors" }));
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header after a redirection.");
+
+promise_test((test) => {
+ const finalURL = localBaseURL + "resources/hello.py?corp=same-origin";
+ return fetch(notSameSiteBaseURL + "resources/redirect.py?redirectTo=" + encodeURIComponent(finalURL), { mode: "no-cors" });
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header after a cross-origin redirection.");
+
+promise_test(async (test) => {
+ const finalURL = localBaseURL + "resources/hello.py?corp=same-origin";
+
+ await fetch(finalURL, { mode: "no-cors" });
+
+ return promise_rejects_js(test, TypeError, fetch(notSameSiteBaseURL + "resources/redirect.py?corp=same-origin&redirectTo=" + encodeURIComponent(finalURL), { mode: "no-cors" }));
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' redirect response header.");
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch.https.any.js b/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch.https.any.js
new file mode 100644
index 0000000000..c9b5b7502f
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/fetch.https.any.js
@@ -0,0 +1,56 @@
+// META: timeout=long
+// META: global=window,worker
+// META: script=/common/get-host-info.sub.js
+
+const host = get_host_info();
+const path = "/fetch/cross-origin-resource-policy/";
+const localBaseURL = host.HTTPS_ORIGIN + path;
+const notSameSiteBaseURL = host.HTTPS_NOTSAMESITE_ORIGIN + path;
+
+promise_test(async () => {
+ const response = await fetch("./resources/hello.py?corp=same-origin");
+ assert_equals(await response.text(), "hello");
+}, "Same-origin fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+promise_test(async () => {
+ const response = await fetch("./resources/hello.py?corp=same-site");
+ assert_equals(await response.text(), "hello");
+}, "Same-origin fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+promise_test(async (test) => {
+ const response = await fetch(notSameSiteBaseURL + "resources/hello.py?corp=same-origin");
+ assert_equals(await response.text(), "hello");
+}, "Cross-origin cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+promise_test(async (test) => {
+ const response = await fetch(notSameSiteBaseURL + "resources/hello.py?corp=same-site");
+ assert_equals(await response.text(), "hello");
+}, "Cross-origin cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+promise_test((test) => {
+ const remoteURL = notSameSiteBaseURL + "resources/hello.py?corp=same-origin";
+ return promise_rejects_js(test, TypeError, fetch(remoteURL, { mode : "no-cors" }));
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+promise_test((test) => {
+ const remoteURL = notSameSiteBaseURL + "resources/hello.py?corp=same-site";
+ return promise_rejects_js(test, TypeError, fetch(remoteURL, { mode: "no-cors" }));
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+promise_test((test) => {
+ const finalURL = notSameSiteBaseURL + "resources/hello.py?corp=same-origin";
+ return promise_rejects_js(test, TypeError, fetch("resources/redirect.py?redirectTo=" + encodeURIComponent(finalURL), { mode: "no-cors" }));
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header after a redirection.");
+
+promise_test((test) => {
+ const finalURL = localBaseURL + "resources/hello.py?corp=same-origin";
+ return fetch(notSameSiteBaseURL + "resources/redirect.py?redirectTo=" + encodeURIComponent(finalURL), { mode: "no-cors" });
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header after a cross-origin redirection.");
+
+promise_test(async (test) => {
+ const finalURL = localBaseURL + "resources/hello.py?corp=same-origin";
+
+ await fetch(finalURL, { mode: "no-cors" });
+
+ return promise_rejects_js(test, TypeError, fetch(notSameSiteBaseURL + "resources/redirect.py?corp=same-origin&redirectTo=" + encodeURIComponent(finalURL), { mode: "no-cors" }));
+}, "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' redirect response header.");
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/iframe-loads.html b/testing/web-platform/tests/fetch/cross-origin-resource-policy/iframe-loads.html
new file mode 100644
index 0000000000..63902c302b
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/iframe-loads.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+</head>
+<body>
+ <script>
+const host = get_host_info();
+const remoteBaseURL = host.HTTP_REMOTE_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
+const localBaseURL = host.HTTP_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
+
+function with_iframe(url) {
+ return new Promise(function(resolve) {
+ var frame = document.createElement('iframe');
+ frame.src = url;
+ frame.onload = function() { resolve(frame); };
+ document.body.appendChild(frame);
+ });
+}
+
+promise_test(async() => {
+ const url = remoteBaseURL + "resources/iframe.py?corp=same-origin";
+
+ await new Promise((resolve, reject) => {
+ return fetch(url, { mode: "no-cors" }).then(reject, resolve);
+ });
+
+ const iframe = await with_iframe(url);
+ return new Promise((resolve, reject) => {
+ window.addEventListener("message", (event) => {
+ if (event.data !== "pong") {
+ reject(event.data);
+ return;
+ }
+ resolve();
+ }, false);
+ iframe.contentWindow.postMessage("ping", "*");
+ }).finally(() => {
+ iframe.remove();
+ });
+}, "Load an iframe that has Cross-Origin-Resource-Policy header");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/image-loads.html b/testing/web-platform/tests/fetch/cross-origin-resource-policy/image-loads.html
new file mode 100644
index 0000000000..060b7551ea
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/image-loads.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+</head>
+<body>
+ <div id="testDiv"></div>
+ <script>
+const host = get_host_info();
+const notSameSiteBaseURL = host.HTTP_NOTSAMESITE_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
+const ok = true;
+const ko = false;
+const noCors = false;
+
+function loadImage(url, shoudLoad, corsMode, title)
+{
+ const testDiv = document.getElementById("testDiv");
+ promise_test(() => {
+ const img = new Image();
+ if (corsMode)
+ img.crossOrigin = corsMode;
+ img.src = url;
+ return new Promise((resolve, reject) => {
+ img.onload = shoudLoad ? resolve : reject;
+ img.onerror = shoudLoad ? reject : resolve;
+ testDiv.appendChild(img);
+ }).finally(() => {
+ testDiv.innerHTML = "";
+ });
+ }, title);
+}
+
+loadImage("./resources/image.py?corp=same-origin", ok, noCors,
+ "Same-origin image load with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+loadImage("./resources/image.py?corp=same-site", ok, noCors,
+ "Same-origin image load with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+loadImage(notSameSiteBaseURL + "resources/image.py?corp=same-origin&acao=*", ok, "anonymous",
+ "Cross-origin cors image load with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+loadImage(notSameSiteBaseURL + "resources/image.py?corp=same-site&acao=*", ok, "anonymous",
+ "Cross-origin cors image load with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+loadImage(notSameSiteBaseURL + "resources/image.py?corp=same-origin&acao=*", ko, noCors,
+ "Cross-origin no-cors image load with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+loadImage(notSameSiteBaseURL + "resources/image.py?corp=same-site&acao=*", ko, noCors,
+ "Cross-origin no-cors image load with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/green.png b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/green.png
new file mode 100644
index 0000000000..28a1faab37
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/green.png
Binary files differ
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/hello.py b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/hello.py
new file mode 100644
index 0000000000..2b1cb84bad
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/hello.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ headers = [(b"Cross-Origin-Resource-Policy", request.GET[b'corp'])]
+ if b'origin' in request.headers:
+ headers.append((b'Access-Control-Allow-Origin', request.headers[b'origin']))
+
+ return 200, headers, b"hello"
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/iframe.py b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/iframe.py
new file mode 100644
index 0000000000..815ecf5927
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/iframe.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [(b"Content-Type", b"text/html"),
+ (b"Cross-Origin-Resource-Policy", request.GET[b'corp'])]
+ return 200, headers, b"<body><h3>The iframe</h3><script>window.onmessage = () => { parent.postMessage('pong', '*'); }</script></body>"
+
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/iframeFetch.html b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/iframeFetch.html
new file mode 100644
index 0000000000..257185805d
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/iframeFetch.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script>
+ function processMessage(event)
+ {
+ fetch(event.data, { mode: "no-cors" }).then(() => {
+ parent.postMessage("ok", "*");
+ }, () => {
+ parent.postMessage("ko", "*");
+ });
+ }
+ window.addEventListener("message", processMessage, false);
+ </script>
+</head>
+<body>
+ <h3>The iframe making a same origin fetch call.</h3>
+</body>
+</html>
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/image.py b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/image.py
new file mode 100644
index 0000000000..2a779cf11b
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/image.py
@@ -0,0 +1,22 @@
+import os.path
+
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ type = request.GET.first(b"type", None)
+
+ body = open(os.path.join(os.path.dirname(isomorphic_decode(__file__)), u"green.png"), u"rb").read()
+
+ response.add_required_headers = False
+ response.writer.write_status(200)
+
+ if b'corp' in request.GET:
+ response.writer.write_header(b"cross-origin-resource-policy", request.GET[b'corp'])
+ if b'acao' in request.GET:
+ response.writer.write_header(b"access-control-allow-origin", request.GET[b'acao'])
+ response.writer.write_header(b"content-length", len(body))
+ if(type != None):
+ response.writer.write_header(b"content-type", type)
+ response.writer.end_headers()
+
+ response.writer.write(body)
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/redirect.py b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/redirect.py
new file mode 100644
index 0000000000..0dad4dd923
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/redirect.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ headers = [(b"Location", request.GET[b'redirectTo'])]
+ if b'corp' in request.GET:
+ headers.append((b'Cross-Origin-Resource-Policy', request.GET[b'corp']))
+
+ return 302, headers, b""
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/script.py b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/script.py
new file mode 100644
index 0000000000..58f8d34154
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/resources/script.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ headers = [(b"Cross-Origin-Resource-Policy", request.GET[b'corp'])]
+ if b'origin' in request.headers:
+ headers.append((b'Access-Control-Allow-Origin', request.headers[b'origin']))
+
+ return 200, headers, b""
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/scheme-restriction.any.js b/testing/web-platform/tests/fetch/cross-origin-resource-policy/scheme-restriction.any.js
new file mode 100644
index 0000000000..8f6338176a
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/scheme-restriction.any.js
@@ -0,0 +1,7 @@
+// META: script=/common/get-host-info.sub.js
+
+promise_test(t => {
+ return promise_rejects_js(t,
+ TypeError,
+ fetch(get_host_info().HTTPS_REMOTE_ORIGIN + "/fetch/cross-origin-resource-policy/resources/hello.py?corp=same-site", { mode: "no-cors" }));
+}, "Cross-Origin-Resource-Policy: same-site blocks retrieving HTTPS from HTTP");
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/scheme-restriction.https.window.js b/testing/web-platform/tests/fetch/cross-origin-resource-policy/scheme-restriction.https.window.js
new file mode 100644
index 0000000000..4c74571874
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/scheme-restriction.https.window.js
@@ -0,0 +1,13 @@
+// META: script=/common/get-host-info.sub.js
+
+promise_test(t => {
+ const img = new Image();
+ img.src = get_host_info().HTTP_REMOTE_ORIGIN + "/fetch/cross-origin-resource-policy/resources/image.py?corp=same-site";
+ return new Promise((resolve, reject) => {
+ img.onload = resolve;
+ img.onerror = reject;
+ document.body.appendChild(img);
+ }).finally(() => {
+ img.remove();
+ });
+}, "Cross-Origin-Resource-Policy does not block Mixed Content <img>");
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/script-loads.html b/testing/web-platform/tests/fetch/cross-origin-resource-policy/script-loads.html
new file mode 100644
index 0000000000..a9690fc70b
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/script-loads.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+</head>
+<body>
+ <div id="testDiv"></div>
+ <script>
+const host = get_host_info();
+const notSameSiteBaseURL = host.HTTP_NOTSAMESITE_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
+const ok = true;
+const ko = false;
+const noCors = false;
+
+function loadScript(url, shoudLoad, corsMode, title)
+{
+ const testDiv = document.getElementById("testDiv");
+ promise_test(() => {
+ const script = document.createElement("script");
+ if (corsMode)
+ script.crossOrigin = corsMode;
+ script.src = url;
+ return new Promise((resolve, reject) => {
+ script.onload = shoudLoad ? resolve : reject;
+ script.onerror = shoudLoad ? reject : resolve;
+ testDiv.appendChild(script);
+ });
+ }, title);
+}
+
+loadScript("./resources/script.py?corp=same-origin", ok, noCors,
+ "Same-origin script load with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+loadScript("./resources/script.py?corp=same-site", ok, noCors,
+ "Same-origin script load with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+loadScript(notSameSiteBaseURL + "resources/script.py?corp=same-origin&acao=*", ok, "anonymous",
+ "Cross-origin cors script load with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+loadScript(notSameSiteBaseURL + "resources/script.py?corp=same-site&acao=*", ok, "anonymous",
+ "Cross-origin cors script load with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+
+loadScript(notSameSiteBaseURL + "resources/script.py?corp=same-origin&acao=*", ko, noCors,
+ "Cross-origin no-cors script load with a 'Cross-Origin-Resource-Policy: same-origin' response header.");
+
+loadScript(notSameSiteBaseURL + "resources/script.py?corp=same-site&acao=*", ko, noCors,
+ "Cross-origin no-cors script load with a 'Cross-Origin-Resource-Policy: same-site' response header.");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/fetch/cross-origin-resource-policy/syntax.any.js b/testing/web-platform/tests/fetch/cross-origin-resource-policy/syntax.any.js
new file mode 100644
index 0000000000..dc874977a6
--- /dev/null
+++ b/testing/web-platform/tests/fetch/cross-origin-resource-policy/syntax.any.js
@@ -0,0 +1,19 @@
+// META: script=/common/get-host-info.sub.js
+
+const crossOriginURL = get_host_info().HTTP_REMOTE_ORIGIN + "/fetch/cross-origin-resource-policy/resources/hello.py?corp=";
+
+[
+ "same",
+ "same, same-origin",
+ "SAME-ORIGIN",
+ "Same-Origin",
+ "same-origin, <>",
+ "same-origin, same-origin",
+ "https://www.example.com", // See https://github.com/whatwg/fetch/issues/760
+].forEach(incorrectHeaderValue => {
+ // Note: an incorrect value results in a successful load, so this test is only meaningful in
+ // implementations with support for the header.
+ promise_test(t => {
+ return fetch(crossOriginURL + encodeURIComponent(incorrectHeaderValue), { mode: "no-cors" });
+ }, "Parsing Cross-Origin-Resource-Policy: " + incorrectHeaderValue);
+});