| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE html> | |
| 2 <script src="../resources/testharness.js"></script> | |
| 3 <script src="../resources/testharnessreport.js"></script> | |
| 4 <script src="../resources/get-host-info.js"></script> | |
| 5 <script src="resources/test-helpers.js"></script> | |
| 6 <script src="resources/foreign-fetch-helpers.js"></script> | |
| 7 <body> | |
| 8 <script> | |
| 9 var host_info = get_host_info(); | |
| 10 var origin = new URL(self.location).origin; | |
| 11 var wrong_origin = 'https://example.com/'; | |
| 12 var test_header = 'X-ServiceWorker-ServerHeader'; | |
| 13 | |
| 14 function url_to_fetch(scope) { | |
| 15 return host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + scope; | |
| 16 } | |
| 17 | |
| 18 function worker_for_response(response) { | |
| 19 return 'foreign-fetch-cors-worker.js?' + | |
| 20 encodeURIComponent(JSON.stringify(response)); | |
| 21 } | |
| 22 | |
| 23 function scope_for_params(params) { | |
| 24 return 'simple.txt?' + encodeURIComponent(JSON.stringify(params)); | |
| 25 } | |
| 26 | |
| 27 // Method used for tests that expect to result in an opaque response. | |
| 28 function verify_opaque_fetch(url, t) { | |
| 29 return promise_rejects(t, new TypeError(), fetch(url)) | |
| 30 .then(() => fetch(url, {mode: 'no-cors'})) | |
| 31 .then(response => assert_equals(response.type, 'opaque')) | |
| 32 .then(() => new Promise(resolve => { | |
| 33 var request = new XMLHttpRequest(); | |
| 34 request.open('GET', url); | |
| 35 request.onreadystatechange = () => { | |
| 36 if (request.readyState == 4) resolve(request); | |
| 37 }; | |
| 38 request.send(); | |
| 39 })) | |
| 40 .then(xhr => { | |
| 41 assert_equals(xhr.status, 0); | |
| 42 assert_equals(xhr.responseText, ''); | |
| 43 }); | |
| 44 } | |
| 45 | |
| 46 // Verify that fetching an url results in a network error. | |
| 47 function verify_network_error(url, t) { | |
| 48 return promise_rejects(t, new TypeError(), fetch(url)) | |
| 49 .then(() => promise_rejects(t, new TypeError(), | |
| 50 fetch(url, {mode: 'no-cors'}))) | |
| 51 .then(() => new Promise(resolve => { | |
| 52 var request = new XMLHttpRequest(); | |
| 53 request.open('GET', url); | |
| 54 request.onreadystatechange = () => { | |
| 55 if (request.readyState == 4) resolve(request); | |
| 56 }; | |
| 57 request.send(); | |
| 58 })) | |
| 59 .then(xhr => { | |
| 60 assert_equals(xhr.status, 0); | |
| 61 assert_equals(xhr.responseText, ''); | |
| 62 }); | |
| 63 } | |
| 64 | |
| 65 // Verifies that fetching the URL returns a cors response, with a specific value | |
| 66 // for a test_header on the response. Also verifies that round-tripping this | |
| 67 // response through the cache doesn't cause issues. | |
| 68 function verify_cors_fetch_with_header_value(url, header_value) { | |
| 69 var response; | |
| 70 var cache; | |
| 71 return fetch(url) | |
| 72 .then(r => { | |
| 73 response = r.clone(); | |
| 74 assert_equals(r.type, 'cors'); | |
| 75 assert_equals(r.headers.get(test_header), header_value, 'From fetch'); | |
| 76 return r.text(); | |
| 77 }) | |
| 78 .then(response_text => { | |
| 79 assert_true(response_text.startsWith('report(')); | |
| 80 return self.caches.open(url); | |
| 81 }) | |
| 82 .then(c => { | |
| 83 cache = c; | |
| 84 return cache.put(url, response); | |
| 85 }) | |
| 86 .then(() => cache.match(url)) | |
| 87 .then(r => { | |
| 88 assert_equals(r.type, 'cors'); | |
| 89 assert_equals(r.headers.get(test_header), header_value, 'From cache'); | |
| 90 return r.text(); | |
| 91 }) | |
| 92 .then(response_text => { | |
| 93 assert_true(response_text.startsWith('report(')); | |
| 94 return self.caches.delete(url); | |
| 95 }) | |
| 96 .then(() => new Promise(resolve => { | |
| 97 var request = new XMLHttpRequest(); | |
| 98 request.open('GET', url); | |
| 99 request.onreadystatechange = () => { | |
| 100 if (request.readyState == 4) resolve(request); | |
| 101 }; | |
| 102 request.send(); | |
| 103 })) | |
| 104 .then(xhr => { | |
| 105 assert_true(xhr.responseText.startsWith('report(')); | |
| 106 assert_equals(xhr.getResponseHeader(test_header), header_value); | |
| 107 var headers = xhr.getAllResponseHeaders().toLowerCase(); | |
| 108 if (header_value) { | |
| 109 assert_true(headers.includes(test_header.toLowerCase() + ': ' + | |
| 110 header_value.toLowerCase())); | |
| 111 } else { | |
| 112 assert_false(headers.includes(test_header.toLowerCase())); | |
| 113 } | |
| 114 }); | |
| 115 } | |
| 116 | |
| 117 verify_cors_fetch_with_header = | |
| 118 url => verify_cors_fetch_with_header_value(url, 'SetInTheServer'); | |
| 119 verify_cors_fetch_without_header = | |
| 120 url => verify_cors_fetch_with_header_value(url, null); | |
| 121 | |
| 122 var tests = [ | |
| 123 { | |
| 124 description: 'Same origin fetch without CORS headers, not exposed', | |
| 125 params: { | |
| 126 cross_origin: false, | |
| 127 with_aceheaders: false, | |
| 128 with_acaorigin: false | |
| 129 }, | |
| 130 response: {}, | |
| 131 expectation: verify_opaque_fetch | |
| 132 }, | |
| 133 { | |
| 134 description: 'Same origin fetch without CORS headers, only origin exposed', | |
| 135 params: { | |
| 136 cross_origin: false, | |
| 137 with_aceheaders: false, | |
| 138 with_acaorigin: false | |
| 139 }, | |
| 140 response: {origin: origin}, | |
| 141 expectation: verify_cors_fetch_without_header | |
| 142 }, | |
| 143 { | |
| 144 description: | |
| 145 'Same origin fetch without CORS headers, headers and origin exposed', | |
| 146 params: { | |
| 147 cross_origin: false, | |
| 148 with_aceheaders: false, | |
| 149 with_acaorigin: false | |
| 150 }, | |
| 151 response: {origin: origin, headers: [test_header]}, | |
| 152 expectation: verify_cors_fetch_with_header | |
| 153 }, | |
| 154 { | |
| 155 description: | |
| 156 'Same origin fetch without CORS headers, exposed to wrong origin', | |
| 157 params: { | |
| 158 cross_origin: false, | |
| 159 with_aceheaders: false, | |
| 160 with_acaorigin: false | |
| 161 }, | |
| 162 response: {origin: wrong_origin, headers: [test_header]}, | |
| 163 expectation: verify_network_error | |
| 164 }, | |
| 165 { | |
| 166 description: 'Same origin fetch with CORS headers, not exposed', | |
| 167 params: { | |
| 168 cross_origin: false, | |
| 169 with_aceheaders: true, | |
| 170 with_acaorigin: true | |
| 171 }, | |
| 172 response: {}, | |
| 173 expectation: verify_opaque_fetch | |
| 174 }, | |
| 175 { | |
| 176 description: 'Same origin fetch with CORS headers, only origin exposed', | |
| 177 params: { | |
| 178 cross_origin: false, | |
| 179 with_aceheaders: true, | |
| 180 with_acaorigin: true | |
| 181 }, | |
| 182 response: {origin: origin}, | |
| 183 expectation: verify_cors_fetch_without_header | |
| 184 }, | |
| 185 { | |
| 186 description: | |
| 187 'Same origin fetch with CORS headers, headers and origin exposed', | |
| 188 params: { | |
| 189 cross_origin: false, | |
| 190 with_aceheaders: true, | |
| 191 with_acaorigin: true | |
| 192 }, | |
| 193 response: {origin: origin, headers: [test_header]}, | |
| 194 expectation: verify_cors_fetch_with_header | |
| 195 }, | |
| 196 { | |
| 197 description: 'Same origin fetch with CORS headers, exposed to wrong origin', | |
| 198 params: { | |
| 199 cross_origin: false, | |
| 200 with_aceheaders: true, | |
| 201 with_acaorigin: true | |
| 202 }, | |
| 203 response: {origin: wrong_origin, headers: [test_header]}, | |
| 204 expectation: verify_network_error | |
| 205 }, | |
| 206 { | |
| 207 description: 'Cross origin fetch without CORS headers, not exposed', | |
| 208 params: { | |
| 209 cross_origin: true, | |
| 210 with_aceheaders: false, | |
| 211 with_acaorigin: false | |
| 212 }, | |
| 213 response: {}, | |
| 214 expectation: verify_opaque_fetch | |
| 215 }, | |
| 216 { | |
| 217 description: 'Cross origin fetch with ACEHeaders header, not exposed', | |
| 218 params: { | |
| 219 cross_origin: true, | |
| 220 with_aceheaders: true, | |
| 221 with_acaorigin: true | |
| 222 }, | |
| 223 response: {}, | |
| 224 expectation: verify_opaque_fetch | |
| 225 }, | |
| 226 { | |
| 227 description: | |
| 228 'Cross origin fetch with ACEHeaders header, only origin exposed', | |
| 229 params: { | |
| 230 cross_origin: true, | |
| 231 with_aceheaders: true, | |
| 232 with_acaorigin: true | |
| 233 }, | |
| 234 response: {origin: origin}, | |
| 235 expectation: verify_cors_fetch_without_header | |
| 236 }, | |
| 237 { | |
| 238 description: | |
| 239 'Cross origin fetch with ACEHeaders header, headers and origin exposed', | |
| 240 params: { | |
| 241 cross_origin: true, | |
| 242 with_aceheaders: true, | |
| 243 with_acaorigin: true | |
| 244 }, | |
| 245 response: {origin: origin, headers: [test_header]}, | |
| 246 expectation: verify_cors_fetch_with_header | |
| 247 }, | |
| 248 { | |
| 249 description: | |
| 250 'Cross origin fetch with ACEHeaders header, exposed to wrong origin', | |
| 251 params: { | |
| 252 cross_origin: true, | |
| 253 with_aceheaders: true, | |
| 254 with_acaorigin: true | |
| 255 }, | |
| 256 response: {origin: wrong_origin, headers: [test_header]}, | |
| 257 expectation: verify_network_error | |
| 258 }, | |
| 259 { | |
| 260 description: 'Cross origin fetch without ACEHeaders header, not exposed', | |
| 261 params: { | |
| 262 cross_origin: true, | |
| 263 with_aceheaders: false, | |
| 264 with_acaorigin: true | |
| 265 }, | |
| 266 response: {}, | |
| 267 expectation: verify_opaque_fetch | |
| 268 }, | |
| 269 { | |
| 270 description: | |
| 271 'Cross origin fetch without ACEHeaders header, only origin exposed', | |
| 272 params: { | |
| 273 cross_origin: true, | |
| 274 with_aceheaders: false, | |
| 275 with_acaorigin: true | |
| 276 }, | |
| 277 response: {origin: origin}, | |
| 278 expectation: verify_cors_fetch_without_header | |
| 279 }, | |
| 280 { | |
| 281 description: 'Cross origin fetch without ACEHeaders header, ' + | |
| 282 'headers and origin exposed', | |
| 283 params: { | |
| 284 cross_origin: true, | |
| 285 with_aceheaders: false, | |
| 286 with_acaorigin: true | |
| 287 }, | |
| 288 response: {origin: origin, headers: [test_header]}, | |
| 289 expectation: verify_cors_fetch_without_header | |
| 290 } | |
| 291 ]; | |
| 292 | |
| 293 for (var i = 0; i < tests.length; ++i) (data => { | |
| 294 promise_test(t => { | |
| 295 var scope = scope_for_params(data.params); | |
| 296 var worker = worker_for_response(data.response); | |
| 297 return install_cross_origin_worker(t, worker, scope) | |
| 298 .then(() => data.expectation(url_to_fetch(scope), t)); | |
| 299 }, data.description); | |
| 300 })(tests[i]); | |
| 301 </script> | |
| 302 </body> | |
| OLD | NEW |