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 | |
11 function worker_for_origins(origins) { | |
12 var worker = 'foreign-fetch-worker.js?'; | |
13 var params = {origins: origins, relscopes: ['/intercept']}; | |
14 return worker + encodeURIComponent(JSON.stringify(params)); | |
15 } | |
16 | |
17 function worker_for_scopes(relative_scopes) { | |
18 var worker = 'foreign-fetch-worker.js?'; | |
19 var params = {relscopes: relative_scopes}; | |
20 return worker + encodeURIComponent(JSON.stringify(params)); | |
21 } | |
22 | |
23 function intercepted_url(scope) { | |
24 return host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + | |
25 scope + '/intercept/foo?basic'; | |
26 } | |
27 | |
28 function non_intercepted_url(scope) { | |
29 return host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + | |
30 scope + '/foo?basic'; | |
31 } | |
32 | |
33 promise_test(t => { | |
34 var scope = 'foreign-fetch/scope/wildcard'; | |
35 return install_cross_origin_worker(t, worker_for_origins(['*']), scope) | |
36 .then(() => promise_rejects(t, new TypeError(), | |
37 fetch(non_intercepted_url(scope)))) | |
38 .then(() => fetch(intercepted_url(scope))) | |
39 .then(response => response.text()) | |
40 .then(response_text => { | |
41 assert_equals(response_text, 'Foreign Fetch'); | |
42 }); | |
43 }, 'Service Worker intercepts fetches in scope with wildcard origin.'); | |
44 | |
45 promise_test(t => { | |
46 var scope = 'foreign-fetch/scope/match-origin'; | |
47 return install_cross_origin_worker( | |
48 t, worker_for_origins([location.origin]), scope) | |
49 .then(() => fetch(intercepted_url(scope))) | |
50 .then(response => response.text()) | |
51 .then(response_text => { | |
52 assert_equals(response_text, 'Foreign Fetch'); | |
53 }); | |
54 }, 'Service Worker intercepts fetches in scope with explicit origin.'); | |
55 | |
56 promise_test(t => { | |
57 var scope = 'foreign-fetch/scope/nomatch-origin'; | |
58 return install_cross_origin_worker( | |
59 t, worker_for_origins(['https://example.com']), scope) | |
60 .then(() => promise_rejects(t, new TypeError(), | |
61 fetch(non_intercepted_url(scope)))); | |
62 }, 'Service Worker doesn\'t intercept fetches with non matching origin.'); | |
63 | |
64 promise_test(t => { | |
65 var scope = 'foreign-fetch/scope/origin-list'; | |
66 return install_cross_origin_worker( | |
67 t, worker_for_origins([location.origin, 'https://example.com']), scope) | |
68 .then(() => fetch(intercepted_url(scope))) | |
69 .then(response => response.text()) | |
70 .then(response_text => { | |
71 assert_equals(response_text, 'Foreign Fetch'); | |
72 }); | |
73 }, 'Service Worker intercepts fetches in scope with explicit origin list.'); | |
74 | |
75 promise_test(t => { | |
76 var scope = 'resources/foreign-fetch/same-origin'; | |
77 return service_worker_unregister_and_register( | |
78 t, 'resources/' + worker_for_origins(['*']), scope) | |
79 .then(r => { | |
80 add_completion_callback(() => r.unregister()); | |
81 return wait_for_state(t, r.installing, 'activated'); | |
82 }) | |
83 .then(() => fetch(scope + '/intercept/foo?basic')) | |
84 .then(response => { | |
85 assert_equals(response.status, 404); | |
86 }); | |
87 }, 'Service Worker does not intercept same origin fetches.'); | |
88 | |
89 promise_test(t => { | |
90 var scope = 'reply-to-message.html?onmessage'; | |
91 var remote_url = | |
92 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + scope; | |
93 return install_cross_origin_worker(t, worker_for_scopes(['']), scope) | |
94 .then(() => with_iframe(remote_url)) | |
95 .then(frame => new Promise(resolve => { | |
96 var channel = new MessageChannel(); | |
97 frame.contentWindow.postMessage('ping', '*', [channel.port1]); | |
98 channel.port2.onmessage = reply => resolve(reply.data); | |
99 })) | |
100 .then(reply => { | |
101 assert_equals(reply, 'ping'); | |
102 }); | |
103 }, 'Service Worker does not intercept navigations.'); | |
104 | |
105 promise_test(t => { | |
106 var scope = 'fetch-access-control.php?fallback&ACAOrigin=*'; | |
107 var remote_url = | |
108 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + scope; | |
109 return install_cross_origin_worker(t, worker_for_scopes(['']), scope) | |
110 .then(() => fetch(remote_url)) | |
111 .then(response => response.text()) | |
112 .then(response_text => assert_true(response_text.startsWith('report('))); | |
113 }, 'Service Worker that fallback to network should fallback to network.'); | |
114 | |
115 promise_test(t => { | |
116 var scope = 'fetch-access-control.php?fetch&ACAOrigin=*'; | |
117 var remote_url = | |
118 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + scope; | |
119 return install_cross_origin_worker(t, worker_for_scopes(['']), scope) | |
120 .then(() => fetch(remote_url)) | |
121 .then(response => response.text()) | |
122 .then(response_text => assert_true(response_text.startsWith('report('))); | |
123 }, 'Service Worker that fetch from the network should fallback to network.'); | |
124 | |
125 promise_test(t => { | |
126 var scope = 'simple.txt?fallback'; | |
127 var remote_url = | |
128 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + scope; | |
129 return install_cross_origin_worker(t, worker_for_scopes(['']), scope) | |
130 .then(() => fetch(remote_url, {mode: 'no-cors'})) | |
131 .then(response => assert_equals(response.type, 'opaque')) | |
132 .then(() => promise_rejects(t, new TypeError(), fetch(remote_url))); | |
133 }, 'Falling back to network should still respect CORS.'); | |
134 | |
135 promise_test(t => { | |
136 var ff_scope = 'foreign-fetch/scope/controlled?basic'; | |
137 var remote_url = | |
138 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + ff_scope; | |
139 var scope = 'resources/simple.html?fetch'; | |
140 var worker = 'resources/empty-worker.js'; | |
141 return install_cross_origin_worker(t, worker_for_scopes(['']), ff_scope) | |
142 .then(() => service_worker_unregister_and_register(t, worker, scope)) | |
143 .then(r => { | |
144 add_completion_callback(() => r.unregister()); | |
145 return wait_for_state(t, r.installing, 'activated'); | |
146 }) | |
147 .then(() => with_iframe(scope)) | |
148 .then(frame => frame.contentWindow.fetch(remote_url)) | |
149 .then(response => response.text()) | |
150 .then(response_text => { | |
151 assert_equals(response_text, 'Foreign Fetch'); | |
152 }); | |
153 }, 'Foreign fetch can intercept fetch requests from SW controlled pages.'); | |
154 | |
155 promise_test(t => { | |
156 var ff_scope = 'foreign-fetch/scope/controlled?script'; | |
157 var remote_url = | |
158 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + ff_scope; | |
159 var scope = 'resources/simple.html?script'; | |
160 var worker = 'resources/empty-worker.js'; | |
161 return install_cross_origin_worker(t, worker_for_scopes(['']), ff_scope) | |
162 .then(() => service_worker_unregister_and_register(t, worker, scope)) | |
163 .then(r => { | |
164 add_completion_callback(() => r.unregister()); | |
165 return wait_for_state(t, r.installing, 'activated'); | |
166 }) | |
167 .then(() => with_iframe(scope)) | |
168 .then(frame => new Promise(resolve => { | |
169 frame.contentWindow.DidLoad = resolve; | |
170 let script = frame.contentWindow.document.createElement('script'); | |
171 script.setAttribute('src', remote_url); | |
172 script.setAttribute('crossorigin', 'use-credentials'); | |
173 frame.contentWindow.document.head.appendChild(script); | |
174 })) | |
175 .then(response_text => { | |
176 assert_equals(response_text, 'Foreign Fetch'); | |
177 }); | |
178 }, 'Foreign fetch can intercept resource requests from SW controlled pages.'); | |
179 | |
180 promise_test(t => { | |
181 var scope = 'simple.txt?meta'; | |
182 var remote_url = | |
183 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + scope; | |
184 return install_cross_origin_worker(t, worker_for_scopes(['']), scope) | |
185 .then(() => fetch(remote_url, {mode: 'no-cors'})) | |
186 .then(response => response.json()) | |
187 .then(response_data => { | |
188 assert_equals(self.location.href, response_data.referrer); | |
189 assert_equals(self.location.origin, response_data.origin); | |
190 }) | |
191 .then(() => with_iframe('resources/blank.html')) | |
192 .then(frame => { | |
193 var meta = frame.contentDocument.createElement('meta'); | |
194 meta.setAttribute('name', 'referrer'); | |
195 meta.setAttribute('content', 'no-referrer'); | |
196 frame.contentDocument.head.appendChild(meta); | |
197 return frame.contentWindow.fetch(remote_url, {mode: 'no-cors'}); | |
198 }) | |
199 .then(response => response.json()) | |
200 .then(response_data => { | |
201 assert_equals('', response_data.referrer); | |
202 assert_equals('null', response_data.origin); | |
203 }); | |
204 }, 'Referrer and origin are set correctly in ForeignFetchEvent.'); | |
205 | |
206 function fetch_from_iframe(origin, url) { | |
207 return with_iframe(origin + | |
208 '/serviceworker/resources/foreign-fetch-helper-iframe.html') | |
209 .then(frame => new Promise((resolve) => { | |
210 var channel = new MessageChannel(); | |
211 frame.contentWindow.postMessage({url: url, | |
212 port: channel.port1}, | |
213 '*', [channel.port1]); | |
214 channel.port2.onmessage = reply => resolve(reply.data); | |
215 })); | |
216 } | |
217 | |
218 promise_test(t => { | |
219 var scope = 'simple.txt?basic_insecure'; | |
220 var remote_url = | |
221 host_info.AUTHENTICATED_ORIGIN + '/serviceworker/resources/' + scope; | |
222 return install_cross_origin_worker(t, worker_for_scopes(['']), scope, | |
223 host_info.AUTHENTICATED_ORIGIN) | |
224 .then(() => fetch_from_iframe(host_info.HTTPS_REMOTE_ORIGIN, remote_url)) | |
225 .then(response => assert_equals(response, 'Success: Foreign Fetch')) | |
226 .then(() => fetch_from_iframe(host_info.UNAUTHENTICATED_ORIGIN, | |
227 remote_url)) | |
228 .then(response => assert_equals(response, | |
229 'Error: TypeError: Failed to fetch')); | |
230 }, 'Service Worker does not intercept fetches from an insecure context.'); | |
231 | |
232 promise_test(t => { | |
233 var scope = 'fetch-access-control.php?basic&ACAOrigin=*&ACAMethods=SPECIAL'; | |
234 var remote_url = | |
235 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + scope; | |
236 return install_cross_origin_worker(t, worker_for_scopes(['']), scope) | |
237 .then(() => fetch(remote_url, {method: 'SPECIAL'})) | |
238 .then(response => response.text()) | |
239 .then(response_text => assert_true(response_text.startsWith('report('))) | |
240 // Do the whole thing twice to test CORS preflight cache behavior. | |
241 .then(() => fetch(remote_url, {method: 'SPECIAL'})) | |
242 .then(response => response.text()) | |
243 .then(response_text => assert_true(response_text.startsWith('report('))); | |
244 }, 'Service Worker does not intercept fetches with CORS preflight'); | |
245 | |
246 promise_test(t => { | |
247 var scope = 'simple.txt?null'; | |
248 var remote_url = | |
249 host_info.HTTPS_REMOTE_ORIGIN + '/serviceworker/resources/' + scope; | |
250 return install_cross_origin_worker(t, worker_for_scopes(['']), scope) | |
251 .then(() => promise_rejects(t, new TypeError(), fetch(remote_url))); | |
252 }, 'Foreign fetch rejects if resolved with a null response.'); | |
253 </script> | |
254 </body> | |
OLD | NEW |