loaf-source-location-redirect.html (3417B)
1 <!DOCTYPE HTML> 2 <meta charset=utf-8> 3 <title>Long Animation Frame Timing: source location should not expose cross-origin redirects</title> 4 <meta name="timeout" content="long"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="/common/utils.js"></script> 8 <script src="/common/get-host-info.sub.js"></script> 9 <script src="resources/utils.js"></script> 10 11 <body> 12 <h1>Long Animation Frame: source location with cross-origin redirects</h1> 13 <div id="log"></div> 14 <script> 15 16 const {REMOTE_ORIGIN} = get_host_info(); 17 18 function corsify(url, cors) { 19 if (!cors) 20 return url.href; 21 url.searchParams.set("pipe", "header(Access-Control-Allow-Origin, *)"); 22 return url.href; 23 } 24 25 const targetURL = (path, cors) => 26 corsify(new URL(path, REMOTE_ORIGIN), cors); 27 28 function crossOriginRedirectURL(path, cors) { 29 const url = new URL(`/common/redirect.py`, REMOTE_ORIGIN); 30 url.searchParams.set("location", targetURL(path, cors)); 31 return corsify(url, cors); 32 } 33 34 function test_source_location_with_redirect({path, type, name}) { 35 for (let scriptType of ["classic-opaque", "classic-cors", "module"]) { 36 const cors = scriptType !== "classic-opaque"; 37 promise_test(async t => { 38 const VERY_LONG_FRAME_DURATION = 360; 39 const preRedirectURL = crossOriginRedirectURL(path, cors); 40 const postRedirectURL = targetURL(path, cors); 41 let [entry, script] = await expect_long_frame_with_script((t, busy_wait) => { 42 const script = document.createElement("script"); 43 script.src = preRedirectURL; 44 if (scriptType === "module") 45 script.type = "module"; 46 else if (cors) 47 script.crossOrigin = "anonymous"; 48 document.body.appendChild(script); 49 t.add_cleanup(() => script.remove()); 50 }, script => script.duration >= VERY_LONG_FRAME_DURATION - 5, t); 51 52 const result = 53 script.sourceURL.startsWith(postRedirectURL) ? "post-redirect" : 54 script.sourceURL.startsWith(preRedirectURL) ? "pre-redirect" : 55 script.sourceURL === "" ? 56 "empty" : "other"; 57 58 assert_not_equals(result, "other", `Unexpected source location ${script.sourceURL}`); 59 if (!cors) 60 assert_equals(script.executionStart, script.startTime, "Opaque scripts should hide execution start time"); 61 62 if (cors) { 63 assert_not_equals(result, "empty", "CORS-ok scripts should expose sourceLocation"); 64 } else { 65 assert_equals(result, "pre-redirect", "No-CORS classic scripts should expose pre-redirect URL"); 66 assert_equals(script.sourceCharPosition, type === "script-block" || type === "resolve-promise" ? 0 : -1, "No-CORS classic scripts should not expose character index"); 67 } 68 }, `Test ${type} with ${scriptType}`); 69 } 70 } 71 72 test_source_location_with_redirect({ 73 path: "/long-animation-frame/resources/busy.js", 74 type: "script-block" 75 }); 76 77 test_source_location_with_redirect({ 78 path: "/long-animation-frame/resources/raf-generates-loaf.js", 79 name: "FrameRequestCallback", 80 type: "user-callback" 81 }); 82 test_source_location_with_redirect({ 83 path: "/long-animation-frame/resources/event-generates-loaf.js", 84 type: "event-listener", 85 name: "XMLHttpRequest.onload" 86 }); 87 88 test_source_location_with_redirect({ 89 path: "/long-animation-frame/resources/promise-generates-loaf.js", 90 type: "resolve-promise", 91 name: "Window.fetch.then" 92 }); 93 94 </script> 95 </body>