shared-worker-import-referrer.html (10936B)
1 <!DOCTYPE html> 2 <title>SharedWorker: Referrer</title> 3 <meta name="timeout" content="long" /> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script> 7 8 // This Set is for checking a shared worker in each test is newly created. 9 const existingWorkers = new Set(); 10 11 async function openWindow(url) { 12 const win = window.open(url, '_blank'); 13 add_result_callback(() => win.close()); 14 const msg_event = await new Promise(resolve => window.onmessage = resolve); 15 assert_equals(msg_event.data, 'LOADED'); 16 return win; 17 } 18 19 // Removes URL parameters from the given URL string and returns it. 20 function removeParams(url_string) { 21 if (!url_string) 22 return url_string; 23 let url = new URL(url_string); 24 for (var key of url.searchParams.keys()) 25 url.searchParams.delete(key); 26 return url.href; 27 } 28 29 // Generates a referrer given a fetchType, referrer policy, and a request URL 30 // (used to determine whether request is remote-origin or not). This function 31 // is used to generate expected referrers. 32 function generateExpectedReferrer(referrerURL, referrerPolicy, requestURL) { 33 let generatedReferrer = ""; 34 if (referrerPolicy === 'no-referrer') 35 generatedReferrer = ""; 36 else if (referrerPolicy === 'origin') 37 generatedReferrer = new URL('resources/' + referrerURL, location.href).origin + '/'; 38 else if (referrerPolicy === 'same-origin') 39 generatedReferrer = requestURL.includes('remote') ? "" : new URL('resources/' + referrerURL, location.href).href; 40 else 41 generatedReferrer = new URL('resources/' + referrerURL, location.href).href; 42 43 return generatedReferrer; 44 } 45 46 // Runs a referrer policy test with the given settings. This opens a new window 47 // that starts a shared worker. 48 // 49 // |settings| has options as follows: 50 // 51 // settings = { 52 // scriptURL: 'resources/referrer-checker.sub.js', 53 // windowReferrerPolicy: 'no-referrer', 54 // workerReferrerPolicy: 'same-origin', 55 // fetchType: 'top-level' or 'descendant-static' or 'descendant-dynamic' 56 // }; 57 // 58 // - |scriptURL| is used for starting a new worker. 59 // - |windowReferrerPolicy| is to set the ReferrerPolicy HTTP header of the 60 // window. This policy should be applied to top-level worker module script 61 // loading and static imports. 62 // - |workerReferrerPolicy| is to set the ReferrerPolicy HTTP header of the 63 // worker. This policy should be applied to dynamic imports. 64 // - |fetchType| indicates a script whose referrer will be tested. 65 function import_referrer_test(settings, description) { 66 promise_test(async () => { 67 let windowURL = 'resources/new-shared-worker-window.html'; 68 if (settings.windowReferrerPolicy) { 69 windowURL += 70 `?pipe=header(Referrer-Policy, ${settings.windowReferrerPolicy})`; 71 } 72 73 let scriptURL = settings.scriptURL; 74 if (settings.workerReferrerPolicy) { 75 // 'sub' is necessary even if the |scriptURL| contains the '.sub' 76 // extension because the extension doesn't work with the 'pipe' parameter. 77 // See an issue on the WPT's repository: 78 // https://github.com/web-platform-tests/wpt/issues/9345 79 scriptURL += 80 `?pipe=sub|header(Referrer-Policy, ${settings.workerReferrerPolicy})`; 81 } 82 83 const win = await openWindow(windowURL); 84 // Construct a unique name for SharedWorker. 85 const name = `${settings.scriptURL}_` + 86 `${settings.windowReferrerPolicy ? settings.windowReferrerPolicy 87 : settings.workerReferrerPolicy}` + 88 `_${settings.fetchType}`; 89 const workerProperties = { scriptURL, name }; 90 // Check if this shared worker is newly created. 91 assert_false(existingWorkers.has(workerProperties)); 92 existingWorkers.add(workerProperties); 93 94 win.postMessage(workerProperties, '*'); 95 const msgEvent = await new Promise(resolve => window.onmessage = resolve); 96 97 // Generate the expected referrer, given: 98 // - The fetchType of the test 99 // - Referrer URL to be used 100 // - Relevant referrer policy 101 // - Request URL 102 let expectedReferrer; 103 if (settings.fetchType === 'top-level') { 104 // Top-level worker requests have their outgoing referrers set given their 105 // containing window's URL and referrer policy. 106 expectedReferrer = generateExpectedReferrer('new-shared-worker-window.html', settings.windowReferrerPolicy, settings.scriptURL); 107 } else if (settings.fetchType === 'descendant-static') { 108 // Static descendant script requests from a worker have their outgoing 109 // referrer set given their containing script's URL and containing 110 // window's referrer policy. 111 112 // In the below cases, the referrer URL and the request URLs are the same 113 // because the initial request (for the top-level worker script) should 114 // act as the referrer for future descendant requests. 115 expectedReferrer = generateExpectedReferrer(settings.scriptURL, settings.windowReferrerPolicy, settings.scriptURL); 116 } else if (settings.fetchType === 'descendant-dynamic') { 117 // Dynamic descendant script requests from a worker have their outgoing 118 // referrer set given their containing script's URL and referrer policy. 119 expectedReferrer = generateExpectedReferrer(settings.scriptURL, settings.workerReferrerPolicy, settings.scriptURL); 120 } 121 122 // Delete query parameters from the actual referrer to make it easy to match 123 // it with the expected referrer. 124 const actualReferrer = removeParams(msgEvent.data); 125 126 assert_equals(actualReferrer, expectedReferrer); 127 }, description); 128 } 129 130 // Tests for top-level worker module script loading. 131 // 132 // Top-level worker module scripts should inherit the containing window's 133 // referrer policy when using the containing window's URL as the referrer. 134 // 135 // [Current document] 136 // --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|. 137 // --(new SharedWorker)--> [SharedWorker] should respect [windowReferrerPolicy| 138 // when using [Window]'s URL as the referrer. 139 140 import_referrer_test( 141 { scriptURL: 'postmessage-referrer-checker.py', 142 windowReferrerPolicy: 'no-referrer', 143 fetchType: 'top-level' }, 144 'Same-origin top-level module script loading with "no-referrer" referrer ' + 145 'policy'); 146 147 import_referrer_test( 148 { scriptURL: 'postmessage-referrer-checker.py', 149 windowReferrerPolicy: 'origin', 150 fetchType: 'top-level' }, 151 'Same-origin top-level module script loading with "origin" referrer ' + 152 'policy'); 153 154 import_referrer_test( 155 { scriptURL: 'postmessage-referrer-checker.py', 156 windowReferrerPolicy: 'same-origin', 157 fetchType: 'top-level' }, 158 'Same-origin top-level module script loading with "same-origin" referrer ' + 159 'policy'); 160 161 // Tests for static imports. 162 // 163 // Static imports should inherit the containing window's referrer policy when 164 // using the containing module script's URL as the referrer. 165 // Note: This is subject to change in the future; see 166 // https://github.com/w3c/webappsec-referrer-policy/issues/111. 167 // 168 // [Current document] 169 // --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|. 170 // --(new SharedWorker)--> [SharedWorker] 171 // --(static import)--> [Script] should respect |windowReferrerPolicy| when 172 // using [SharedWorker]'s URL as the referrer. 173 174 import_referrer_test( 175 { scriptURL: 'static-import-same-origin-referrer-checker-worker.js', 176 windowReferrerPolicy: 'no-referrer', 177 fetchType: 'descendant-static' }, 178 'Same-origin static import with "no-referrer" referrer policy.'); 179 180 import_referrer_test( 181 { scriptURL: 'static-import-same-origin-referrer-checker-worker.js', 182 windowReferrerPolicy: 'origin', 183 fetchType: 'descendant-static' }, 184 'Same-origin static import with "origin" referrer policy.'); 185 186 import_referrer_test( 187 { scriptURL: 'static-import-same-origin-referrer-checker-worker.js', 188 windowReferrerPolicy: 'same-origin', 189 fetchType: 'descendant-static' }, 190 'Same-origin static import with "same-origin" referrer policy.'); 191 192 import_referrer_test( 193 { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', 194 windowReferrerPolicy: 'no-referrer', 195 fetchType: 'descendant-static' }, 196 'Cross-origin static import with "no-referrer" referrer policy.'); 197 198 import_referrer_test( 199 { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', 200 windowReferrerPolicy: 'origin', 201 fetchType: 'descendant-static' }, 202 'Cross-origin static import with "origin" referrer policy.'); 203 204 import_referrer_test( 205 { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', 206 windowReferrerPolicy: 'same-origin', 207 fetchType: 'descendant-static' }, 208 'Cross-origin static import with "same-origin" referrer policy.'); 209 210 // Tests for dynamic imports. 211 // 212 // Dynamic imports should inherit the containing script's referrer policy if 213 // set, and use the default referrer policy otherwise, when using the 214 // containing script's URL as the referrer. 215 // 216 // [Current document] 217 // --(open)--> [Window] 218 // --(new SharedWorker)--> [SharedWorker] whose referrer policy is 219 // |workerReferrerPolicy|. 220 // --(dynamic import)--> [Script] should respect |workerReferrerPolicy| when 221 // using [SharedWorker]'s URL as the referrer. 222 223 import_referrer_test( 224 { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', 225 workerReferrerPolicy: 'no-referrer', 226 fetchType: 'descendant-dynamic' }, 227 'Same-origin dynamic import with "no-referrer" referrer policy.'); 228 229 import_referrer_test( 230 { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', 231 workerReferrerPolicy: 'origin', 232 fetchType: 'descendant-dynamic' }, 233 'Same-origin dynamic import with "origin" referrer policy.'); 234 235 import_referrer_test( 236 { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', 237 workerReferrerPolicy: 'same-origin', 238 fetchType: 'descendant-dynamic' }, 239 'Same-origin dynamic import with "same-origin" referrer policy.'); 240 241 import_referrer_test( 242 { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', 243 workerReferrerPolicy: 'no-referrer', 244 fetchType: 'descendant-dynamic' }, 245 'Cross-origin dynamic import with "no-referrer" referrer policy.'); 246 247 import_referrer_test( 248 { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', 249 workerReferrerPolicy: 'origin', 250 fetchType: 'descendant-dynamic' }, 251 'Cross-origin dynamic import with "origin" referrer policy.'); 252 253 import_referrer_test( 254 { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', 255 workerReferrerPolicy: 'same-origin', 256 fetchType: 'descendant-dynamic' }, 257 'Cross-origin dynamic import with "same-origin" referrer policy.'); 258 259 </script>