out-of-document-rule-set.https.html (9137B)
1 <!DOCTYPE html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 <script src="/common/dispatcher/dispatcher.js"></script> 5 <script src="/common/subset-tests-by-key.js"></script> 6 <script src="/common/utils.js"></script> 7 <script src="/common/get-host-info.sub.js"></script> 8 <script src="../resources/utils.js"></script> 9 <script src="resources/utils.sub.js"></script> 10 11 <meta name="variant" content="?include=BaseCase"> 12 <meta name="variant" content="?include=FollowRedirect"> 13 <meta name="variant" content="?include=RelativeUrlForSpeculationRulesSet"> 14 <meta name="variant" content="?include=RelativeUrlForCandidate"> 15 <meta name="variant" content="?include=UseNonUTF8EncodingForSpeculationRulesSet"> 16 <meta name="variant" content="?include=FailCORS"> 17 <meta name="variant" content="?include=FailToParseSpeculationRulesHeader"> 18 <meta name="variant" content="?include=InnerListInSpeculationRulesHeader"> 19 <meta name="variant" content="?include=EmptyRuleSet"> 20 <meta name="variant" content="?include=FailToParseRuleSet"> 21 <meta name="variant" content="?include=InvalidUrlForSpeculationRulesSet"> 22 <meta name="variant" content="?include=StatusCode199"> 23 <meta name="variant" content="?include=StatusCode404"> 24 <meta name="variant" content="?include=InvalidMimeType"> 25 <meta name="variant" content="?include=CSPExemption"> 26 27 <script> 28 setup(() => assertSpeculationRulesIsSupported()); 29 30 async function runSpeculationRulesFetchTest(t, options) { 31 options = { 32 // Whether a prefetch is expected to succeed. 33 shouldPrefetch: true, 34 // Status code to be returned in the response. 35 status: 200, 36 // Whether a redirect must be followed to reach the rule set. 37 redirect: false, 38 // Whether to use relative URLs for the candidates in the rule set. 39 useRelativeUrlForCandidate: false, 40 // Whether to use relative URL for the rule set in SpeculationRules header. 41 useRelativeUrlForSpeculationRulesSet: false, 42 // Whether to use UTF-8 encoding for the rule set. 43 useUtf8EncodingForSpeculationRulesSet: true, 44 // Whether to force the response to cause a CORS failure. 45 failCors: false, 46 // Whether to use a valid SpeculationRules header format. 47 useValidSpeculationRulesHeaderValue: true, 48 // Whether to use an inner list of URLS in SpeculationRules header. 49 useInnerListInSpeculationRulesHeaderValue: false, 50 // Whether to return an empty response. 51 useEmptySpeculationRulesSet: false, 52 // Wheter to return a rule set with valid JSON format 53 useValidJsonForSpeculationRulesSet: true, 54 // Wheter to use a valid URL for the rule set in SpeculationRules header. 55 useValidUrlForSpeculationRulesSet: true, 56 // Wheter to use the valid "application/speculationrules-json" MIME type for the rule set. 57 useValidMimeTypeForSpeculationRulesSet: true, 58 // Whether to use a strict CSP for the main page. 59 strictCSP: false, 60 ...options 61 }; 62 63 let page = 2; 64 let uuid = token(); 65 let executor_url = new URL(`executor.sub.html`, SR_PREFETCH_UTILS_URL).toString(); 66 if (options.useRelativeUrlForCandidate) { 67 executor_url = `executor.sub.html`; 68 } 69 let speculation_rule_set_url = `ruleset.py?url=${executor_url}&uuid=${uuid}&page=${page}&status=${options.status}&valid_mime=${options.useValidMimeTypeForSpeculationRulesSet}&valid_json=${options.useValidJsonForSpeculationRulesSet}&empty_json=${options.useEmptySpeculationRulesSet}&fail_cors=${options.failCors}&valid_encoding=${options.useUtf8EncodingForSpeculationRulesSet}&redirect=${options.redirect}`; 70 if (!options.useRelativeUrlForSpeculationRulesSet) { 71 let base_url = new URL(SR_PREFETCH_UTILS_URL); 72 base_url.hostname = get_host_info().NOTSAMESITE_HOST; 73 speculation_rule_set_url = new URL(speculation_rule_set_url, base_url).toString(); 74 } 75 if (!options.useValidUrlForSpeculationRulesSet) { 76 speculation_rule_set_url = "http://:80/"; 77 } 78 79 let speculation_rules_header = `header(Speculation-Rules,"${speculation_rule_set_url}")`; 80 if (!options.useValidSpeculationRulesHeaderValue) { 81 speculation_rules_header = `header(Speculation-Rules, x y z)`; 82 } 83 else if (options.useInnerListInSpeculationRulesHeaderValue) { 84 speculation_rules_header = `header(Speculation-Rules, \\("${speculation_rule_set_url}" "xyz.com/rule-set.json"\\))`; 85 } 86 if (options.strictCSP) { 87 speculation_rules_header = speculation_rules_header + `|header(Content-Security-Policy, script-src 'strict-dynamic' 'nonce-abc' 'unsafe-eval')`; 88 } 89 90 let agent = await spawnWindow(t, {pipe: speculation_rules_header}, uuid); 91 await new Promise(resolve => t.step_timeout(resolve, 2000)); 92 // Passing non-ascii character 'รท' as part of the next URL to check if we always decode the speculation rules set using utf-8 or not. This character is encoded differently in utf-8 and windows-1250 93 let nextUrl = agent.getExecutorURL({ page, str: decodeURIComponent('%C3%B7')}); 94 await agent.navigate(nextUrl); 95 96 await new Promise(resolve => t.step_timeout(resolve, 2000)); 97 98 let test_case_desc = JSON.stringify(options); 99 if (options.shouldPrefetch) 100 assert_prefetched(await agent.getRequestHeaders(), `Prefetch should work for request ${test_case_desc}.`); 101 else 102 assert_not_prefetched(await agent.getRequestHeaders(), `Prefetch should not work for request ${test_case_desc}.`); 103 } 104 105 subsetTestByKey('BaseCase', promise_test, async t => { 106 return runSpeculationRulesFetchTest(t, {}); 107 }, "Base case."); 108 109 subsetTestByKey('FollowRedirect', promise_test, async t => { 110 return runSpeculationRulesFetchTest(t, {redirect: true}); 111 }, "It should follow redirects and fetch the speculation rules set."); 112 113 subsetTestByKey('RelativeUrlForSpeculationRulesSet', promise_test, async t => { 114 return runSpeculationRulesFetchTest(t, {useRelativeUrlForSpeculationRulesSet: true}); 115 }, "It should fetch a speculation rules set using its relative URL."); 116 117 subsetTestByKey('RelativeUrlForCandidate', promise_test, async t => { 118 return runSpeculationRulesFetchTest(t, {useRelativeUrlForCandidate: true, shouldPrefetch: false}); 119 }, "It should resolve the relative candidate URLs in the speculation rules set based on the speculation rules set's URL"); 120 121 subsetTestByKey('UseNonUTF8EncodingForSpeculationRulesSet', promise_test, async t => { 122 return runSpeculationRulesFetchTest(t, {useUtf8EncodingForSpeculationRulesSet: false, shouldPrefetch: false}); 123 }, "The speculation rules set should always be encoded using UTF-8."); 124 125 subsetTestByKey('FailCORS', promise_test, async t => { 126 return runSpeculationRulesFetchTest(t, {failCors: true, shouldPrefetch: false}); 127 }, "It should reject the speculation rules set if CORS fails."); 128 129 subsetTestByKey('FailToParseSpeculationRulesHeader', promise_test, async t => { 130 return runSpeculationRulesFetchTest(t, {useValidSpeculationRulesHeaderValue: false, shouldPrefetch: false}); 131 }, "It should reject the speculation rules set if it fails to parse the SpeculationRules header."); 132 133 subsetTestByKey('InnerListInSpeculationRulesHeader', promise_test, async t => { 134 return runSpeculationRulesFetchTest(t, {useInnerListInSpeculationRulesHeaderValue: true, shouldPrefetch: false}); 135 }, "It should reject the speculation rules passed as inner list in the SpeculationRules header."); 136 137 subsetTestByKey('EmptyRuleSet', promise_test, async t => { 138 return runSpeculationRulesFetchTest(t, {useEmptySpeculationRulesSet: true, shouldPrefetch: false}); 139 }, "It should reject an empty speculation rules set."); 140 141 subsetTestByKey('FailToParseRuleSet', promise_test, async t => { 142 return runSpeculationRulesFetchTest(t, {useValidJsonForSpeculationRulesSet: false, shouldPrefetch: false}); 143 }, "It should reject the speculation rules set if it cannot parse it."); 144 145 subsetTestByKey('InvalidUrlForSpeculationRulesSet', promise_test, async t => { 146 return runSpeculationRulesFetchTest(t, {useValidUrlForSpeculationRulesSet: false, shouldPrefetch: false}); 147 }, "It should reject the speculation rules set with invalid URL."); 148 149 subsetTestByKey('StatusCode199', promise_test, async t => { 150 return runSpeculationRulesFetchTest(t, {status: 199, shouldPrefetch: false}); 151 }, "It should reject the speculation rules set with unsuccessful status code."); 152 153 subsetTestByKey('StatusCode404', promise_test, async t => { 154 return runSpeculationRulesFetchTest(t, {status: 404, shouldPrefetch: false}); 155 }, "It should reject the speculation rules set with unsuccessful status code."); 156 157 subsetTestByKey('InvalidMimeType', promise_test, async t => { 158 return runSpeculationRulesFetchTest(t, {useValidMimeTypeForSpeculationRulesSet: false, shouldPrefetch: false}); 159 }, "It should reject the speculation rules set with invalid MIME type."); 160 161 subsetTestByKey('CSPExemption', promise_test, async t => { 162 return runSpeculationRulesFetchTest(t, {shouldPrefetch: true, strictCSP: true}); 163 }, "It should accept the speculation rules when the main page has strict CSP."); 164 165 </script>