Commit b789471f authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

ES Modules: Use an appropriate referrer policy for module script loading

This CL fixes ReferrerPolicy handling in module script loading. Before this CL,
FetchClientSettingsObjectSnapshot's referrer policy is used, but this is wrong.
The spec requires to use ScriptFetchOptions' referrer policy.

  // The "set up the module script request" algorithm:
  "Set request's cryptographic nonce metadata to options's cryptographic nonce,
  ..., and its referrer policy to options's referrer policy."
  https://html.spec.whatwg.org/multipage/webappapis.html#set-up-the-module-script-request

Specifically, this CL introduces |referrer_policy_| field in ScriptFetchOptions
class as spec'ed and propagates it to the entire path of module script loading.

ScriptFetchOptions's referrer policy can be set to following values:

- <script>'s "referrerpolicy" attribute is used for <script type='module'>. This
  hasn't been implemented yet (see https://crbug.com/841673), so the current
  document's referrer policy is used to keep the backward compatibility.

  // The "prepare a script" algorithm:
  "20. Let referrer policy be the current state of the element's referrerpolicy
  content attribute."
  "22. Let options be a script fetch options whose cryptographic nonce is
  cryptographic nonce, ..., and referrer policy is referrer policy."
  https://html.spec.whatwg.org/multipage/scripting.html#prepare-a-script

- <link>'s "referrerpolicy" attribute is used for modulepreload.

  // The "Link type "modulepreload"" algorithm:
  "9. Let referrer policy be the current state of the element's referrerpolicy
  attribute."
  "10. Let options be a script fetch options whose cryptographic nonce is
  cryptographic nonce, ..., and referrer policy is referrer policy."
  https://html.spec.whatwg.org/multipage/links.html#link-type-modulepreload

- The default referrer policy is used for module workers and worklets. This is
  the reason why this CL changes test expectations of workers and worklets.

  // The "fetch a module worker script graph" algorithm:
  "2. Let options be a script fetch options whose cryptographic nonce is the
  empty string, ..., and referrer policy is the empty string."
  https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree

Change-Id: Ic0f9e6667cd1b84f74d86fcc948451c1d2f8191f
Bug: 842553, 855963
Reviewed-on: https://chromium-review.googlesource.com/1111743
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarHiroshige Hayashizaki <hiroshige@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569967}
parent b39bd892
...@@ -36,7 +36,7 @@ function removeParams(url_string) { ...@@ -36,7 +36,7 @@ function removeParams(url_string) {
// scriptURL: 'resources/referrer-checker.sub.js', // scriptURL: 'resources/referrer-checker.sub.js',
// windowReferrerPolicy: 'no-referrer', // windowReferrerPolicy: 'no-referrer',
// workerReferrerPolicy: 'same-origin', // workerReferrerPolicy: 'same-origin',
// expectedReferrer: 'https://example.com/referrer-checker.py' // moduleGraphLevel: 'top-level' (or 'descendant')
// }; // };
// //
// - |scriptURL| is used for starting a new worker. // - |scriptURL| is used for starting a new worker.
...@@ -45,8 +45,7 @@ function removeParams(url_string) { ...@@ -45,8 +45,7 @@ function removeParams(url_string) {
// loading and static imports. // loading and static imports.
// - |workerReferrerPolicy| is set to the ReferrerPolicy HTTP header of the // - |workerReferrerPolicy| is set to the ReferrerPolicy HTTP header of the
// worker. This policy should be applied to dynamic imports. // worker. This policy should be applied to dynamic imports.
// - |expectedReferrer| is compared with the actual referrer. URL parameters are // - |moduleGraphLevel| indicates a script whose referrer will be tested.
// ignored.
function import_referrer_test(settings, description) { function import_referrer_test(settings, description) {
promise_test(async () => { promise_test(async () => {
let windowURL = 'resources/new-worker-window.html'; let windowURL = 'resources/new-worker-window.html';
...@@ -69,141 +68,144 @@ function import_referrer_test(settings, description) { ...@@ -69,141 +68,144 @@ function import_referrer_test(settings, description) {
win.postMessage(scriptURL, '*'); win.postMessage(scriptURL, '*');
const msgEvent = await new Promise(resolve => window.onmessage = resolve); const msgEvent = await new Promise(resolve => window.onmessage = resolve);
// Delete query parameters from the referrers to make it easy to match the let expectedReferrer;
// actual referrer with the expected referrer. if (settings.moduleGraphLevel == 'top-level')
const expectedReferrer = removeParams(settings.expectedReferrer); expectedReferrer = createURLString('resources/new-worker-window.html');
else
expectedReferrer = createURLString('resources/' + settings.scriptURL);
// Delete query parameters from the actual referrer to make it easy to match
// it with the expected referrer.
const actualReferrer = removeParams(msgEvent.data); const actualReferrer = removeParams(msgEvent.data);
assert_equals(actualReferrer, expectedReferrer); assert_equals(actualReferrer, expectedReferrer);
}, description); }, description);
} }
// Tests for top-level worker module script loading. // Tests for top-level worker module script loading.
// //
// Top-level worker module script loading should obey the window's // Top-level worker module script loading should obey the default referrer
// ReferrerPolicy, and send the window's URL as a referrer. // policy (not the window's referrer policy), and send the window's URL as a
// referrer.
// //
// [Current document] // [Current document]
// --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|. // --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|.
// --(new Worker)--> [Worker] should be loaded with [Window]'s URL as a // --(new Worker)--> [Worker] should be loaded with [Window]'s URL as a
// referrer if it's allowed by |windowReferrerPolicy|. // referrer regardless of |windowReferrerPolicy|.
import_referrer_test( import_referrer_test(
{ scriptURL: 'referrer-checker.py', { scriptURL: 'referrer-checker.py',
windowReferrerPolicy: 'no-referrer', windowReferrerPolicy: 'no-referrer',
expectedReferrer: '' }, moduleGraphLevel: 'top-level' },
'Same-origin top-level module script loading with "no-referrer" referrer ' + 'Same-origin top-level module script loading with "no-referrer" referrer ' +
'policy'); 'policy');
import_referrer_test( import_referrer_test(
{ scriptURL: 'referrer-checker.py', { scriptURL: 'referrer-checker.py',
windowReferrerPolicy: 'origin', windowReferrerPolicy: 'origin',
expectedReferrer: window.location.origin + '/' }, moduleGraphLevel: 'top-level' },
'Same-origin top-level module script loading with "origin" referrer ' + 'Same-origin top-level module script loading with "origin" referrer ' +
'policy'); 'policy');
import_referrer_test( import_referrer_test(
{ scriptURL: 'referrer-checker.py', { scriptURL: 'referrer-checker.py',
windowReferrerPolicy: 'same-origin', windowReferrerPolicy: 'same-origin',
expectedReferrer: createURLString('resources/new-worker-window.html') }, moduleGraphLevel: 'top-level' },
'Same-origin top-level module script loading with "same-origin" referrer ' + 'Same-origin top-level module script loading with "same-origin" referrer ' +
'policy'); 'policy');
// Tests for static imports. // Tests for static imports.
// //
// Static imports should obey the window's ReferrerPolicy, and send the worker's // Static imports should obey the default referrer policy, and send the worker's
// URL as a referrer. // URL as a referrer.
// //
// [Current document] // [Current document]
// --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|. // --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|.
// --(new Worker)--> [Worker] // --(new Worker)--> [Worker]
// --(static import)--> [Script] should be loaded with [Worker]'s URL as a // --(static import)--> [Script] should be loaded with [Worker]'s URL as a
// referrer if it's allowed by |windowReferrerPolicy|. // referrer regardless of |windowReferrerPolicy|.
import_referrer_test( import_referrer_test(
{ scriptURL: 'static-import-same-origin-referrer-checker-worker.js', { scriptURL: 'static-import-same-origin-referrer-checker-worker.js',
windowReferrerPolicy: 'no-referrer', windowReferrerPolicy: 'no-referrer',
expectedReferrer: '' }, moduleGraphLevel: 'descendant' },
'Same-origin static import with "no-referrer" referrer policy.'); 'Same-origin static import with "no-referrer" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'static-import-same-origin-referrer-checker-worker.js', { scriptURL: 'static-import-same-origin-referrer-checker-worker.js',
windowReferrerPolicy: 'origin', windowReferrerPolicy: 'origin',
expectedReferrer: window.location.origin + '/' }, moduleGraphLevel: 'descendant' },
'Same-origin static import with "origin" referrer policy.'); 'Same-origin static import with "origin" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'static-import-same-origin-referrer-checker-worker.js', { scriptURL: 'static-import-same-origin-referrer-checker-worker.js',
windowReferrerPolicy: 'same-origin', windowReferrerPolicy: 'same-origin',
expectedReferrer: createURLString( moduleGraphLevel: 'descendant' },
'resources/static-import-same-origin-referrer-checker-worker.js') },
'Same-origin static import with "same-origin" referrer policy.'); 'Same-origin static import with "same-origin" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js',
windowReferrerPolicy: 'no-referrer', windowReferrerPolicy: 'no-referrer',
expectedReferrer: '' }, moduleGraphLevel: 'descendant' },
'Cross-origin static import with "no-referrer" referrer policy.'); 'Cross-origin static import with "no-referrer" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js',
windowReferrerPolicy: 'origin', windowReferrerPolicy: 'origin',
expectedReferrer: window.location.origin + '/' }, moduleGraphLevel: 'descendant' },
'Cross-origin static import with "origin" referrer policy.'); 'Cross-origin static import with "origin" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js',
windowReferrerPolicy: 'same-origin', windowReferrerPolicy: 'same-origin',
expectedReferrer: '' }, moduleGraphLevel: 'descendant' },
'Cross-origin static import with "same-origin" referrer policy.'); 'Cross-origin static import with "same-origin" referrer policy.');
// Tests for dynamic imports. // Tests for dynamic imports.
// //
// Dynamic imports should obey the worker's ReferrerPolicy, and send the // Dynamic imports should obey the default referrer policy (not the worker's
// worker's URL as a referrer. Note that the worker doesn't inherit the window's // referrer policy), and send the worker's URL as a referrer.
// referrer policy and it's set by the ReferrerPolicy HTTP header on the
// response of the top-level worker module script.
// //
// [Current document] // [Current document]
// --(open)--> [Window] // --(open)--> [Window]
// --(new Worker)--> [Worker] whose referrer policy is |workerReferrerPolicy|. // --(new Worker)--> [Worker] whose referrer policy is |workerReferrerPolicy|.
// --(dynamic import)--> [Script] should be loaded with [Worker]'s URL as a // --(dynamic import)--> [Script] should be loaded with [Worker]'s URL as a
// referrer if it's allowed by |workerReferrerPolicy|. // referrer regardless of |workerReferrerPolicy|.
import_referrer_test( import_referrer_test(
{ scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js',
workerReferrerPolicy: 'no-referrer', workerReferrerPolicy: 'no-referrer',
expectedReferrer: '' }, moduleGraphLevel: 'descendant' },
'Same-origin dynamic import with "no-referrer" referrer policy.'); 'Same-origin dynamic import with "no-referrer" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js',
workerReferrerPolicy: 'origin', workerReferrerPolicy: 'origin',
expectedReferrer: window.location.origin + '/' }, moduleGraphLevel: 'descendant' },
'Same-origin dynamic import with "origin" referrer policy.'); 'Same-origin dynamic import with "origin" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js',
workerReferrerPolicy: 'same-origin', workerReferrerPolicy: 'same-origin',
expectedReferrer: createURLString( moduleGraphLevel: 'descendant' },
'resources/dynamic-import-same-origin-referrer-checker-worker.js') },
'Same-origin dynamic import with "same-origin" referrer policy.'); 'Same-origin dynamic import with "same-origin" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js',
workerReferrerPolicy: 'no-referrer', workerReferrerPolicy: 'no-referrer',
expectedReferrer: '' }, moduleGraphLevel: 'descendant' },
'Cross-origin dynamic import with "no-referrer" referrer policy.'); 'Cross-origin dynamic import with "no-referrer" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js',
workerReferrerPolicy: 'origin', workerReferrerPolicy: 'origin',
expectedReferrer: window.location.origin + '/' }, moduleGraphLevel: 'descendant' },
'Cross-origin dynamic import with "origin" referrer policy.'); 'Cross-origin dynamic import with "origin" referrer policy.');
import_referrer_test( import_referrer_test(
{ scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js',
workerReferrerPolicy: 'same-origin', workerReferrerPolicy: 'same-origin',
expectedReferrer: '' }, moduleGraphLevel: 'descendant' },
'Cross-origin dynamic import with "same-origin" referrer policy.'); 'Cross-origin dynamic import with "same-origin" referrer policy.');
</script> </script>
This is a testharness.js-based test.
PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
Harness: the test ran to completion.
...@@ -2,25 +2,14 @@ ...@@ -2,25 +2,14 @@
# |expected_referrer|. # |expected_referrer|.
def main(request, response): def main(request, response):
referrer = request.headers.get("referer", "") referrer = request.headers.get("referer", "")
referrer_policy = request.GET.first("referrer_policy")
expected_referrer = request.GET.first("expected_referrer", "") expected_referrer = request.GET.first("expected_referrer", "")
response_headers = [("Content-Type", "text/javascript"), response_headers = [("Content-Type", "text/javascript"),
("Access-Control-Allow-Origin", "*")] ("Access-Control-Allow-Origin", "*")]
if referrer_policy == "no-referrer" or referrer_policy == "origin": # The expected referrer doesn't contain query params for simplification, so
if referrer == expected_referrer: # we check the referrer by startswith() here.
return (200, response_headers, "") if (expected_referrer != "" and
return (404, response_headers) referrer.startswith(expected_referrer + "?")):
return (200, response_headers, "")
if referrer_policy == "same-origin":
if referrer == expected_referrer:
return (200, response_headers, "")
# The expected referrer doesn't contain query params for simplification,
# so we check the referrer by startswith() here.
if (expected_referrer != "" and
referrer.startswith(expected_referrer + "?")):
return (200, response_headers, "")
return (404, response_headers)
return (404, response_headers) return (404, response_headers)
...@@ -29,7 +29,9 @@ function runReferrerTest(settings) { ...@@ -29,7 +29,9 @@ function runReferrerTest(settings) {
}).then(msg_event => assert_equals(msg_event.data, 'RESOLVED')); }).then(msg_event => assert_equals(msg_event.data, 'RESOLVED'));
} }
// Runs a series of tests related to the referrer policy on a worklet. // Runs a series of tests related to the referrer policy on a worklet. Referrer
// on worklet module loading should always be handled with the default referrer
// policy.
// //
// Usage: // Usage:
// runReferrerTests("paint"); // runReferrerTests("paint");
...@@ -44,7 +46,7 @@ function runReferrerTests(workletType) { ...@@ -44,7 +46,7 @@ function runReferrerTests(workletType) {
referrerPolicy: 'no-referrer', referrerPolicy: 'no-referrer',
scriptOrigins: { topLevel: 'same' } }); scriptOrigins: { topLevel: 'same' } });
}, 'Importing a same-origin script from a page that has "no-referrer" ' + }, 'Importing a same-origin script from a page that has "no-referrer" ' +
'referrer policy should not send referrer.'); 'referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -52,7 +54,7 @@ function runReferrerTests(workletType) { ...@@ -52,7 +54,7 @@ function runReferrerTests(workletType) {
referrerPolicy: 'no-referrer', referrerPolicy: 'no-referrer',
scriptOrigins: { topLevel: 'remote' } }); scriptOrigins: { topLevel: 'remote' } });
}, 'Importing a remote-origin script from a page that has "no-referrer" ' + }, 'Importing a remote-origin script from a page that has "no-referrer" ' +
'referrer policy should not send referrer.'); 'referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -60,7 +62,7 @@ function runReferrerTests(workletType) { ...@@ -60,7 +62,7 @@ function runReferrerTests(workletType) {
referrerPolicy: 'origin', referrerPolicy: 'origin',
scriptOrigins: { topLevel: 'same' } }); scriptOrigins: { topLevel: 'same' } });
}, 'Importing a same-origin script from a page that has "origin" ' + }, 'Importing a same-origin script from a page that has "origin" ' +
'referrer policy should send only an origin as referrer.'); 'referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -68,7 +70,7 @@ function runReferrerTests(workletType) { ...@@ -68,7 +70,7 @@ function runReferrerTests(workletType) {
referrerPolicy: 'origin', referrerPolicy: 'origin',
scriptOrigins: { topLevel: 'remote' } }); scriptOrigins: { topLevel: 'remote' } });
}, 'Importing a remote-origin script from a page that has "origin" ' + }, 'Importing a remote-origin script from a page that has "origin" ' +
'referrer policy should send only an origin as referrer.'); 'referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -76,7 +78,7 @@ function runReferrerTests(workletType) { ...@@ -76,7 +78,7 @@ function runReferrerTests(workletType) {
referrerPolicy: 'same-origin', referrerPolicy: 'same-origin',
scriptOrigins: { topLevel: 'same' } }); scriptOrigins: { topLevel: 'same' } });
}, 'Importing a same-origin script from a page that has "same-origin" ' + }, 'Importing a same-origin script from a page that has "same-origin" ' +
'referrer policy should send referrer.'); 'referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -84,7 +86,7 @@ function runReferrerTests(workletType) { ...@@ -84,7 +86,7 @@ function runReferrerTests(workletType) {
referrerPolicy: 'same-origin', referrerPolicy: 'same-origin',
scriptOrigins: { topLevel: 'remote' } }); scriptOrigins: { topLevel: 'remote' } });
}, 'Importing a remote-origin script from a page that has "same-origin" ' + }, 'Importing a remote-origin script from a page that has "same-origin" ' +
'referrer policy should not send referrer.'); 'referrer policy.');
// Tests for descendant script fetch ----------------------------------------- // Tests for descendant script fetch -----------------------------------------
...@@ -95,7 +97,7 @@ function runReferrerTests(workletType) { ...@@ -95,7 +97,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'same', scriptOrigins: { topLevel: 'same',
descendant: 'same' } }); descendant: 'same' } });
}, 'Importing a same-origin script from a same-origin worklet script that ' + }, 'Importing a same-origin script from a same-origin worklet script that ' +
'has "no-referrer" referrer policy should not send referrer.'); 'has "no-referrer" referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -104,7 +106,7 @@ function runReferrerTests(workletType) { ...@@ -104,7 +106,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'same', scriptOrigins: { topLevel: 'same',
descendant: 'remote' } }); descendant: 'remote' } });
}, 'Importing a remote-origin script from a same-origin worklet script ' + }, 'Importing a remote-origin script from a same-origin worklet script ' +
'that has "no-referrer" referrer policy should not send referrer.'); 'that has "no-referrer" referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -113,7 +115,7 @@ function runReferrerTests(workletType) { ...@@ -113,7 +115,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'remote', scriptOrigins: { topLevel: 'remote',
descendant: 'remote' } }); descendant: 'remote' } });
}, 'Importing a remote-origin script from a remote-origin worklet script ' + }, 'Importing a remote-origin script from a remote-origin worklet script ' +
'that has "no-referrer" referrer policy should not send referrer.'); 'that has "no-referrer" referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -122,7 +124,7 @@ function runReferrerTests(workletType) { ...@@ -122,7 +124,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'same', scriptOrigins: { topLevel: 'same',
descendant: 'same' } }); descendant: 'same' } });
}, 'Importing a same-origin script from a same-origin worklet script that ' + }, 'Importing a same-origin script from a same-origin worklet script that ' +
'has "origin" referrer policy should send referrer.'); 'has "origin" referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -131,7 +133,7 @@ function runReferrerTests(workletType) { ...@@ -131,7 +133,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'same', scriptOrigins: { topLevel: 'same',
descendant: 'remote' } }); descendant: 'remote' } });
}, 'Importing a remote-origin script from a same-origin worklet script ' + }, 'Importing a remote-origin script from a same-origin worklet script ' +
'that has "origin" referrer policy should send referrer.'); 'that has "origin" referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -140,7 +142,7 @@ function runReferrerTests(workletType) { ...@@ -140,7 +142,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'remote', scriptOrigins: { topLevel: 'remote',
descendant: 'remote' } }); descendant: 'remote' } });
}, 'Importing a remote-origin script from a remote-origin worklet script ' + }, 'Importing a remote-origin script from a remote-origin worklet script ' +
'that has "origin" referrer policy should send referrer.'); 'that has "origin" referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -149,7 +151,7 @@ function runReferrerTests(workletType) { ...@@ -149,7 +151,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'same', scriptOrigins: { topLevel: 'same',
descendant: 'same' } }); descendant: 'same' } });
}, 'Importing a same-origin script from a same-origin worklet script that ' + }, 'Importing a same-origin script from a same-origin worklet script that ' +
'has "same-origin" referrer policy should send referrer.'); 'has "same-origin" referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -158,7 +160,7 @@ function runReferrerTests(workletType) { ...@@ -158,7 +160,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'same', scriptOrigins: { topLevel: 'same',
descendant: 'remote' } }); descendant: 'remote' } });
}, 'Importing a remote-origin script from a same-origin worklet script ' + }, 'Importing a remote-origin script from a same-origin worklet script ' +
'that has "same-origin" referrer policy should not send referrer.'); 'that has "same-origin" referrer policy.');
promise_test(() => { promise_test(() => {
return runReferrerTest({ workletType: workletType, return runReferrerTest({ workletType: workletType,
...@@ -167,5 +169,5 @@ function runReferrerTests(workletType) { ...@@ -167,5 +169,5 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'remote', scriptOrigins: { topLevel: 'remote',
descendant: 'remote' } }); descendant: 'remote' } });
}, 'Importing a remote-origin script from a remote-origin worklet script ' + }, 'Importing a remote-origin script from a remote-origin worklet script ' +
'that has "same-origin" referrer policy should not send referrer.'); 'that has "same-origin" referrer policy.');
} }
...@@ -48,47 +48,30 @@ function isDestinationCrossOrigin(fetchType, scriptOrigins) { ...@@ -48,47 +48,30 @@ function isDestinationCrossOrigin(fetchType, scriptOrigins) {
assert_unreached('fetchType has an invalid value.'); assert_unreached('fetchType has an invalid value.');
} }
function createExpectedReferrer(
importerURL, fetchType, referrerPolicy, scriptOrigins) {
if (referrerPolicy === 'no-referrer')
return "";
if (referrerPolicy === 'same-origin') {
if (isDestinationCrossOrigin(fetchType, scriptOrigins))
return "";
// Delete query params to make it easier to match with an actual referrer in
// the referrer-checker.py.
const expectedReferrer = new URL(importerURL);
for (var key of expectedReferrer.searchParams.keys())
expectedReferrer.searchParams.delete(key);
return expectedReferrer;
}
if (referrerPolicy === 'origin')
return (new URL(importerURL)).origin + '/';
assert_unreached('referrerPolicy has an invalid value.');
}
window.onmessage = e => { window.onmessage = e => {
const workletType = e.data.workletType; const workletType = e.data.workletType;
const fetchType = e.data.fetchType; const fetchType = e.data.fetchType;
const referrerPolicy = e.data.referrerPolicy;
const scriptOrigins = e.data.scriptOrigins; const scriptOrigins = e.data.scriptOrigins;
let scriptURL; let scriptURL;
let expectedReferrer; let expectedReferrer;
if (fetchType === 'top-level') { if (fetchType === 'top-level') {
scriptURL = createScriptURLForTopLevel(scriptOrigins.topLevel); scriptURL = createScriptURLForTopLevel(scriptOrigins.topLevel);
expectedReferrer = createExpectedReferrer( // The referrer of the top-level script should be this file.
location.href, fetchType, referrerPolicy, scriptOrigins); // Delete query params to make it easier to match with an actual referrer in
// the referrer-checker.py.
expectedReferrer = new URL(location.href);
for (var key of expectedReferrer.searchParams.keys())
expectedReferrer.searchParams.delete(key);
} else if (fetchType === 'descendant') { } else if (fetchType === 'descendant') {
scriptURL = createScriptURLForDecendant(scriptOrigins); scriptURL = createScriptURLForDecendant(scriptOrigins);
expectedReferrer = createExpectedReferrer( // The referrer of the imported script should be the importer script.
scriptURL, fetchType, referrerPolicy, scriptOrigins); expectedReferrer = scriptURL;
} else { } else {
assert_unreached('fetchType should be \'top-level\' or \'descendant\''); assert_unreached('fetchType should be \'top-level\' or \'descendant\'');
} }
const params = new URLSearchParams; const params = new URLSearchParams;
params.append('referrer_policy', referrerPolicy);
params.append('expected_referrer', expectedReferrer); params.append('expected_referrer', expectedReferrer);
get_worklet(workletType).addModule(scriptURL + '?' + params) get_worklet(workletType).addModule(scriptURL + '?' + params)
......
...@@ -16,6 +16,7 @@ enum HostDefinedOptionsIndex : size_t { ...@@ -16,6 +16,7 @@ enum HostDefinedOptionsIndex : size_t {
kCredentialsMode, kCredentialsMode,
kNonce, kNonce,
kParserState, kParserState,
kReferrerPolicy,
kLength kLength
}; };
...@@ -48,7 +49,13 @@ ReferrerScriptInfo ReferrerScriptInfo::FromV8HostDefinedOptions( ...@@ -48,7 +49,13 @@ ReferrerScriptInfo ReferrerScriptInfo::FromV8HostDefinedOptions(
ParserDisposition parser_state = static_cast<ParserDisposition>( ParserDisposition parser_state = static_cast<ParserDisposition>(
parser_state_value->IntegerValue(context).ToChecked()); parser_state_value->IntegerValue(context).ToChecked());
return ReferrerScriptInfo(base_url, credentials_mode, nonce, parser_state); v8::Local<v8::Primitive> referrer_policy_value =
host_defined_options->Get(kReferrerPolicy);
ReferrerPolicy referrer_policy = static_cast<ReferrerPolicy>(
referrer_policy_value->IntegerValue(context).ToChecked());
return ReferrerScriptInfo(base_url, credentials_mode, nonce, parser_state,
referrer_policy);
} }
v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions( v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions(
...@@ -77,6 +84,11 @@ v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions( ...@@ -77,6 +84,11 @@ v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions(
host_defined_options->Set(HostDefinedOptionsIndex::kParserState, host_defined_options->Set(HostDefinedOptionsIndex::kParserState,
parser_state_value); parser_state_value);
v8::Local<v8::Primitive> referrer_policy_value = v8::Integer::NewFromUnsigned(
isolate, static_cast<uint32_t>(referrer_policy_));
host_defined_options->Set(HostDefinedOptionsIndex::kReferrerPolicy,
referrer_policy_value);
return host_defined_options; return host_defined_options;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h" #include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h" #include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h"
#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
#include "third_party/blink/renderer/platform/wtf/text/text_position.h" #include "third_party/blink/renderer/platform/wtf/text/text_position.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
...@@ -26,16 +27,19 @@ class CORE_EXPORT ReferrerScriptInfo { ...@@ -26,16 +27,19 @@ class CORE_EXPORT ReferrerScriptInfo {
ReferrerScriptInfo(const KURL& base_url, ReferrerScriptInfo(const KURL& base_url,
network::mojom::FetchCredentialsMode credentials_mode, network::mojom::FetchCredentialsMode credentials_mode,
const String& nonce, const String& nonce,
ParserDisposition parser_state) ParserDisposition parser_state,
ReferrerPolicy referrer_policy)
: base_url_(base_url), : base_url_(base_url),
credentials_mode_(credentials_mode), credentials_mode_(credentials_mode),
nonce_(nonce), nonce_(nonce),
parser_state_(parser_state) {} parser_state_(parser_state),
referrer_policy_(referrer_policy) {}
ReferrerScriptInfo(const KURL& base_url, const ScriptFetchOptions& options) ReferrerScriptInfo(const KURL& base_url, const ScriptFetchOptions& options)
: ReferrerScriptInfo(base_url, : ReferrerScriptInfo(base_url,
options.CredentialsMode(), options.CredentialsMode(),
options.Nonce(), options.Nonce(),
options.ParserState()) {} options.ParserState(),
options.GetReferrerPolicy()) {}
static ReferrerScriptInfo FromV8HostDefinedOptions( static ReferrerScriptInfo FromV8HostDefinedOptions(
v8::Local<v8::Context>, v8::Local<v8::Context>,
...@@ -48,6 +52,7 @@ class CORE_EXPORT ReferrerScriptInfo { ...@@ -48,6 +52,7 @@ class CORE_EXPORT ReferrerScriptInfo {
} }
const String& Nonce() const { return nonce_; } const String& Nonce() const { return nonce_; }
ParserDisposition ParserState() const { return parser_state_; } ParserDisposition ParserState() const { return parser_state_; }
ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; }
bool IsDefaultValue() const { bool IsDefaultValue() const {
return base_url_.IsNull() && return base_url_.IsNull() &&
...@@ -77,6 +82,11 @@ class CORE_EXPORT ReferrerScriptInfo { ...@@ -77,6 +82,11 @@ class CORE_EXPORT ReferrerScriptInfo {
// The default value is "not-parser-inserted" per: // The default value is "not-parser-inserted" per:
// https://html.spec.whatwg.org/multipage/webappapis.html#default-classic-script-fetch-options // https://html.spec.whatwg.org/multipage/webappapis.html#default-classic-script-fetch-options
const ParserDisposition parser_state_ = kNotParserInserted; const ParserDisposition parser_state_ = kNotParserInserted;
// Spec: "referencing script's referrer policy"
// The default value is "the empty string" per:
// https://html.spec.whatwg.org/multipage/webappapis.html#default-classic-script-fetch-options
const ReferrerPolicy referrer_policy_ = kReferrerPolicyDefault;
}; };
} // namespace blink } // namespace blink
......
...@@ -15,7 +15,7 @@ TEST(ReferrerScriptInfo, IsDefaultValue) { ...@@ -15,7 +15,7 @@ TEST(ReferrerScriptInfo, IsDefaultValue) {
EXPECT_FALSE( EXPECT_FALSE(
ReferrerScriptInfo(KURL("http://example.com"), ReferrerScriptInfo(KURL("http://example.com"),
network::mojom::FetchCredentialsMode::kInclude, "", network::mojom::FetchCredentialsMode::kInclude, "",
kNotParserInserted) kNotParserInserted, kReferrerPolicyDefault)
.IsDefaultValue()); .IsDefaultValue());
} }
...@@ -28,7 +28,7 @@ TEST(ReferrerScriptInfo, ToFromV8) { ...@@ -28,7 +28,7 @@ TEST(ReferrerScriptInfo, ToFromV8) {
.IsEmpty()); .IsEmpty());
ReferrerScriptInfo info(url, network::mojom::FetchCredentialsMode::kInclude, ReferrerScriptInfo info(url, network::mojom::FetchCredentialsMode::kInclude,
"foobar", kNotParserInserted); "foobar", kNotParserInserted, kReferrerPolicyOrigin);
v8::Local<v8::PrimitiveArray> v8_info = v8::Local<v8::PrimitiveArray> v8_info =
info.ToV8HostDefinedOptions(scope.GetIsolate()); info.ToV8HostDefinedOptions(scope.GetIsolate());
...@@ -39,6 +39,7 @@ TEST(ReferrerScriptInfo, ToFromV8) { ...@@ -39,6 +39,7 @@ TEST(ReferrerScriptInfo, ToFromV8) {
decoded.CredentialsMode()); decoded.CredentialsMode());
EXPECT_EQ("foobar", decoded.Nonce()); EXPECT_EQ("foobar", decoded.Nonce());
EXPECT_EQ(kNotParserInserted, decoded.ParserState()); EXPECT_EQ(kNotParserInserted, decoded.ParserState());
EXPECT_EQ(kReferrerPolicyOrigin, decoded.GetReferrerPolicy());
} }
} // namespace blink } // namespace blink
...@@ -531,18 +531,23 @@ static void ModulePreloadIfNeeded(const LinkLoadParameters& params, ...@@ -531,18 +531,23 @@ static void ModulePreloadIfNeeded(const LinkLoadParameters& params,
SubresourceIntegrityHelper::DoReport(document, report_info); SubresourceIntegrityHelper::DoReport(document, report_info);
} }
// Step 9. "Let options be a script fetch options whose cryptographic nonce is // Step 9. "Let referrer policy be the current state of the element's
// cryptographic nonce, integrity metadata is integrity metadata, parser // referrerpolicy attribute." [spec text]
// metadata is "not-parser-inserted", and credentials mode is credentials // |referrer_policy| parameter is the value of the referrerpolicy attribute.
// mode." [spec text]
// Step 10. "Let options be a script fetch options whose cryptographic nonce
// is cryptographic nonce, integrity metadata is integrity metadata, parser
// metadata is "not-parser-inserted", credentials mode is credentials mode,
// and referrer policy is referrer policy." [spec text]
ModuleScriptFetchRequest request( ModuleScriptFetchRequest request(
params.href, destination, params.href, destination,
ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity, ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity,
kNotParserInserted, credentials_mode), kNotParserInserted, credentials_mode,
params.referrer_policy),
Referrer(Referrer::NoReferrer(), params.referrer_policy), Referrer(Referrer::NoReferrer(), params.referrer_policy),
TextPosition::MinimumPosition()); TextPosition::MinimumPosition());
// Step 10. "Fetch a single module script given url, settings object, // Step 11. "Fetch a single module script given url, settings object,
// destination, options, settings object, "client", and with the top-level // destination, options, settings object, "client", and with the top-level
// module fetch flag set. Wait until algorithm asynchronously completes with // module fetch flag set. Wait until algorithm asynchronously completes with
// result." [spec text] // result." [spec text]
......
...@@ -185,7 +185,7 @@ void ModuleTreeLinker::FetchRoot(const KURL& original_url, ...@@ -185,7 +185,7 @@ void ModuleTreeLinker::FetchRoot(const KURL& original_url,
ModuleScriptFetchRequest request( ModuleScriptFetchRequest request(
url, destination_, options, url, destination_, options,
SecurityPolicy::GenerateReferrer( SecurityPolicy::GenerateReferrer(
fetch_client_settings_object_.GetReferrerPolicy(), url, options.GetReferrerPolicy(), url,
fetch_client_settings_object_.GetOutgoingReferrer()), fetch_client_settings_object_.GetOutgoingReferrer()),
TextPosition::MinimumPosition()); TextPosition::MinimumPosition());
...@@ -366,7 +366,8 @@ void ModuleTreeLinker::FetchDescendants(ModuleScript* module_script) { ...@@ -366,7 +366,8 @@ void ModuleTreeLinker::FetchDescendants(ModuleScript* module_script) {
ScriptFetchOptions options(module_script->FetchOptions().Nonce(), ScriptFetchOptions options(module_script->FetchOptions().Nonce(),
IntegrityMetadataSet(), String(), IntegrityMetadataSet(), String(),
module_script->FetchOptions().ParserState(), module_script->FetchOptions().ParserState(),
module_script->FetchOptions().CredentialsMode()); module_script->FetchOptions().CredentialsMode(),
module_script->FetchOptions().GetReferrerPolicy());
// [FD] Step 7. For each url in urls, ... // [FD] Step 7. For each url in urls, ...
// //
...@@ -374,12 +375,13 @@ void ModuleTreeLinker::FetchDescendants(ModuleScript* module_script) { ...@@ -374,12 +375,13 @@ void ModuleTreeLinker::FetchDescendants(ModuleScript* module_script) {
// procedure should be performed in parallel to each other. // procedure should be performed in parallel to each other.
for (size_t i = 0; i < urls.size(); ++i) { for (size_t i = 0; i < urls.size(); ++i) {
// [FD] Step 7. ... perform the internal module script graph fetching // [FD] Step 7. ... perform the internal module script graph fetching
// procedure given ... with the top-level module fetch flag unset. ... // procedure given url, fetch client settings object, destination, options,
// module script's settings object, visited set, module script's base URL,
// and with the top-level module fetch flag unset. ...
ModuleScriptFetchRequest request( ModuleScriptFetchRequest request(
urls[i], destination_, options, urls[i], destination_, options,
SecurityPolicy::GenerateReferrer( SecurityPolicy::GenerateReferrer(options.GetReferrerPolicy(), urls[i],
fetch_client_settings_object_.GetReferrerPolicy(), urls[i], module_script->BaseURL().GetString()),
module_script->BaseURL().GetString()),
positions[i]); positions[i]);
InitiateInternalModuleScriptGraphFetching( InitiateInternalModuleScriptGraphFetching(
request, ModuleGraphLevel::kDependentModuleFetch); request, ModuleGraphLevel::kDependentModuleFetch);
......
...@@ -207,7 +207,8 @@ void DynamicModuleResolver::ResolveDynamically( ...@@ -207,7 +207,8 @@ void DynamicModuleResolver::ResolveDynamically(
// string.</spec> // string.</spec>
ScriptFetchOptions options(referrer_info.Nonce(), IntegrityMetadataSet(), ScriptFetchOptions options(referrer_info.Nonce(), IntegrityMetadataSet(),
String(), referrer_info.ParserState(), String(), referrer_info.ParserState(),
referrer_info.CredentialsMode()); referrer_info.CredentialsMode(),
referrer_info.GetReferrerPolicy());
// Step 2.4. "Fetch a module script graph given url, settings object, // Step 2.4. "Fetch a module script graph given url, settings object,
// "script", and options. Wait until the algorithm asynchronously completes // "script", and options. Wait until the algorithm asynchronously completes
......
...@@ -199,6 +199,9 @@ void WorkerOrWorkletGlobalScope::BindContentSecurityPolicyToExecutionContext() { ...@@ -199,6 +199,9 @@ void WorkerOrWorkletGlobalScope::BindContentSecurityPolicyToExecutionContext() {
GetContentSecurityPolicy()->BindToExecutionContext(GetExecutionContext()); GetContentSecurityPolicy()->BindToExecutionContext(GetExecutionContext());
} }
// Implementation of the "fetch a module worker script graph" algorithm in the
// HTML spec:
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree
void WorkerOrWorkletGlobalScope::FetchModuleScript( void WorkerOrWorkletGlobalScope::FetchModuleScript(
const KURL& module_url_record, const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, const FetchClientSettingsObjectSnapshot& fetch_client_settings_object,
...@@ -210,11 +213,13 @@ void WorkerOrWorkletGlobalScope::FetchModuleScript( ...@@ -210,11 +213,13 @@ void WorkerOrWorkletGlobalScope::FetchModuleScript(
String nonce; String nonce;
// integrity metadata is the empty string, // integrity metadata is the empty string,
String integrity_attribute; String integrity_attribute;
// parser metadata is "not-parser-inserted", // parser metadata is "not-parser-inserted,
ParserDisposition parser_state = kNotParserInserted; ParserDisposition parser_state = kNotParserInserted;
// and credentials mode is credentials mode." // credentials mode is credentials mode, and referrer policy is the empty
// string."
ScriptFetchOptions options(nonce, IntegrityMetadataSet(), integrity_attribute, ScriptFetchOptions options(nonce, IntegrityMetadataSet(), integrity_attribute,
parser_state, credentials_mode); parser_state, credentials_mode,
kReferrerPolicyDefault);
Modulator* modulator = Modulator::From(ScriptController()->GetScriptState()); Modulator* modulator = Modulator::From(ScriptController()->GetScriptState());
// Step 3. "Perform the internal module script graph fetching procedure ..." // Step 3. "Perform the internal module script graph fetching procedure ..."
......
...@@ -109,9 +109,6 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData, ...@@ -109,9 +109,6 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
const Vector<CSPHeaderAndType>& headers); const Vector<CSPHeaderAndType>& headers);
virtual void BindContentSecurityPolicyToExecutionContext(); virtual void BindContentSecurityPolicyToExecutionContext();
// Implementation of the "fetch a module worker script graph" algorithm in the
// HTML spec:
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree
void FetchModuleScript( void FetchModuleScript(
const KURL& module_url_record, const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, const FetchClientSettingsObjectSnapshot& fetch_client_settings_object,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h" #include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h" #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
...@@ -29,18 +30,21 @@ class PLATFORM_EXPORT ScriptFetchOptions final { ...@@ -29,18 +30,21 @@ class PLATFORM_EXPORT ScriptFetchOptions final {
// is "omit"." [spec text] // is "omit"." [spec text]
ScriptFetchOptions() ScriptFetchOptions()
: parser_state_(ParserDisposition::kNotParserInserted), : parser_state_(ParserDisposition::kNotParserInserted),
credentials_mode_(network::mojom::FetchCredentialsMode::kOmit) {} credentials_mode_(network::mojom::FetchCredentialsMode::kOmit),
referrer_policy_(kReferrerPolicyDefault) {}
ScriptFetchOptions(const String& nonce, ScriptFetchOptions(const String& nonce,
const IntegrityMetadataSet& integrity_metadata, const IntegrityMetadataSet& integrity_metadata,
const String& integrity_attribute, const String& integrity_attribute,
ParserDisposition parser_state, ParserDisposition parser_state,
network::mojom::FetchCredentialsMode credentials_mode) network::mojom::FetchCredentialsMode credentials_mode,
ReferrerPolicy referrer_policy)
: nonce_(nonce), : nonce_(nonce),
integrity_metadata_(integrity_metadata), integrity_metadata_(integrity_metadata),
integrity_attribute_(integrity_attribute), integrity_attribute_(integrity_attribute),
parser_state_(parser_state), parser_state_(parser_state),
credentials_mode_(credentials_mode) {} credentials_mode_(credentials_mode),
referrer_policy_(referrer_policy) {}
~ScriptFetchOptions() = default; ~ScriptFetchOptions() = default;
const String& Nonce() const { return nonce_; } const String& Nonce() const { return nonce_; }
...@@ -54,6 +58,7 @@ class PLATFORM_EXPORT ScriptFetchOptions final { ...@@ -54,6 +58,7 @@ class PLATFORM_EXPORT ScriptFetchOptions final {
network::mojom::FetchCredentialsMode CredentialsMode() const { network::mojom::FetchCredentialsMode CredentialsMode() const {
return credentials_mode_; return credentials_mode_;
} }
ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; }
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script
// Steps 1 and 3. // Steps 1 and 3.
...@@ -75,6 +80,9 @@ class PLATFORM_EXPORT ScriptFetchOptions final { ...@@ -75,6 +80,9 @@ class PLATFORM_EXPORT ScriptFetchOptions final {
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-fetch-options-credentials // https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-fetch-options-credentials
const network::mojom::FetchCredentialsMode credentials_mode_; const network::mojom::FetchCredentialsMode credentials_mode_;
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-fetch-options-referrer-policy
const ReferrerPolicy referrer_policy_;
}; };
} // namespace blink } // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment