diff --git a/preload/dynamic-adding-preload-nonce.html b/preload/dynamic-adding-preload-nonce.html
index 19e09472eef3813..2a5bc1ae857adb9 100644
--- a/preload/dynamic-adding-preload-nonce.html
+++ b/preload/dynamic-adding-preload-nonce.html
@@ -1,39 +1,50 @@
+
diff --git a/preload/link-header-preload-nonce.html b/preload/link-header-preload-nonce.html
index 74ea87042b4546b..cd2d8fbb5a0225d 100644
--- a/preload/link-header-preload-nonce.html
+++ b/preload/link-header-preload-nonce.html
@@ -1,33 +1,53 @@
-Makes sure that Link headers preload resources with CSP nonce
-
-
-
+
+
+
+
-
diff --git a/preload/link-header-preload-nonce.html.headers b/preload/link-header-preload-nonce.html.headers
deleted file mode 100644
index a54b69378e9cc78..000000000000000
--- a/preload/link-header-preload-nonce.html.headers
+++ /dev/null
@@ -1,3 +0,0 @@
-Content-Security-Policy: script-src 'nonce-abc'
-Link: ;rel=preload;as=script
-Link: ;rel=preload;as=script;nonce=abc
diff --git a/preload/preload-csp.sub.html b/preload/preload-csp.sub.html
index a11214e9ec8e41a..7d367bf846d886f 100644
--- a/preload/preload-csp.sub.html
+++ b/preload/preload-csp.sub.html
@@ -1,55 +1,35 @@
-
+
Makes sure that preload requests respect CSP
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
diff --git a/preload/preload-default-csp.sub.html b/preload/preload-default-csp.sub.html
index c649a53f874d854..8d280c4a475125f 100644
--- a/preload/preload-default-csp.sub.html
+++ b/preload/preload-default-csp.sub.html
@@ -1,55 +1,35 @@
-
+
Makes sure that preload requests respect CSP
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/preload/preload-strict-dynamic.html b/preload/preload-strict-dynamic.html
deleted file mode 100644
index 76395656f9b359e..000000000000000
--- a/preload/preload-strict-dynamic.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-CSP strict-dynamic + preload
-
-
-
-
-
-
-
-
diff --git a/preload/preload-strict-dynamic.sub.html b/preload/preload-strict-dynamic.sub.html
new file mode 100644
index 000000000000000..bdd7a1746ba1df8
--- /dev/null
+++ b/preload/preload-strict-dynamic.sub.html
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+CSP strict-dynamic + preload
+
+
+
+
+
+
+
+
+
diff --git a/preload/resources/preload_helper.js b/preload/resources/preload_helper.js
index 1c7c1a2750e7bc8..5b7a6eb52ba0ef8 100644
--- a/preload/resources/preload_helper.js
+++ b/preload/resources/preload_helper.js
@@ -1,3 +1,18 @@
+function stashPutUrl(token) {
+ return `/preload/resources/stash-put.py?key=${token}`;
+}
+
+function encodedStashPutUrl(token) {
+ return encodeURIComponent(stashPutUrl(token));
+}
+
+async function hasArrivedAtServer(token) {
+ const res = await fetch(`/preload/resources/stash-take.py?key=${token}`);
+ assert_true(res.status === 200 || res.status === 404,
+ 'status must be either 200 or 404');
+ return res.status === 200;
+}
+
function verifyPreloadAndRTSupport()
{
var link = window.document.createElement("link");
diff --git a/preload/resources/stash-put.py b/preload/resources/stash-put.py
new file mode 100644
index 000000000000000..f4bc87940ec9b55
--- /dev/null
+++ b/preload/resources/stash-put.py
@@ -0,0 +1,20 @@
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ if request.method == u'OPTIONS':
+ # CORS preflight
+ response.headers.set(b'Access-Control-Allow-Origin', b'*')
+ response.headers.set(b'Access-Control-Allow-Methods', b'*')
+ response.headers.set(b'Access-Control-Allow-Headers', b'*')
+ return 'done'
+
+ url_dir = u'/'.join(request.url_parts.path.split(u'/')[:-1]) + u'/'
+ key = request.GET.first(b"key")
+ if b"value" in request.GET:
+ value = request.GET.first(b"value")
+ else:
+ value = b"value"
+ # value here must be a text string. It will be json.dump()'ed in stash-take.py.
+ request.server.stash.put(key, isomorphic_decode(value), url_dir)
+ response.headers.set(b'Access-Control-Allow-Origin', b'*')
+ return "done"
diff --git a/preload/resources/stash-take.py b/preload/resources/stash-take.py
new file mode 100644
index 000000000000000..9977197cae5591f
--- /dev/null
+++ b/preload/resources/stash-take.py
@@ -0,0 +1,14 @@
+from wptserve.handlers import json_handler
+
+
+@json_handler
+def main(request, response):
+ dir = u'/'.join(request.url_parts.path.split(u'/')[:-1]) + u'/'
+ key = request.GET.first(b"key")
+ response.headers.set(b'Access-Control-Allow-Origin', b'*')
+ value = request.server.stash.take(key, dir)
+ if value is None:
+ response.status = 404
+ return 'No entry is found'
+ response.status = 200
+ return value