Make fetch() use "same-origin" credentials by default
[WebKit-https.git] / LayoutTests / http / wpt / resource-timing / rt-cors.js
1 function assertAlways(entry) {
2     assert_equals(entry.workerStart, 0, "entry should not have a workerStart time");
3     assert_equals(entry.secureConnectionStart, 0, "entry should not have a secureConnectionStart time");
4
5     assert_not_equals(entry.startTime, 0, "entry should have a non-0 fetchStart time");
6     assert_not_equals(entry.fetchStart, 0, "entry should have a non-0 startTime time");
7     assert_not_equals(entry.responseEnd, 0, "entry should have a non-0 responseEnd time");
8
9     assert_greater_than_equal(entry.fetchStart, entry.startTime, "fetchStart after startTime");
10     assert_greater_than_equal(entry.responseEnd, entry.fetchStart, "responseEnd after fetchStart");
11 }
12
13 function assertRedirectTimingData(entry) {
14     assertAlways(entry);
15     assert_not_equals(entry.redirectStart, 0, "entry should have a redirectStart time");
16     assert_not_equals(entry.redirectEnd, 0, "entry should have a redirectEnd time");
17     assert_equals(entry.startTime, entry.redirectStart, "entry startTime should be the same as redirectStart for a redirect");
18     assert_greater_than_equal(entry.redirectEnd, entry.redirectStart, "redirectEnd after redirectStart");
19     assert_greater_than_equal(entry.fetchStart, entry.redirectEnd, "fetchStart after redirectEnd");
20 }
21
22 function assertRedirectWithDisallowedTimingData(entry) {
23     assertAlways(entry);
24     assert_equals(entry.redirectStart, 0, "entry should not have a redirectStart time");
25     assert_equals(entry.redirectEnd, 0, "entry should not have a redirectEnd time");
26     assert_equals(entry.startTime, entry.fetchStart, "entry startTime should have matched redirectStart but it was disallowed so it should match fetchStart");
27 }
28
29 function assertNonRedirectTimingData(entry) {
30     assertAlways(entry);
31     assert_equals(entry.redirectStart, 0, "entry should not have a redirectStart time");
32     assert_equals(entry.redirectEnd, 0, "entry should not have a redirectEnd time");
33     assert_equals(entry.startTime, entry.fetchStart, "entry startTime should be the same as fetchTime for non-redirect");
34 }
35
36 function assertAllowedTimingData(entry) {
37     assert_greater_than_equal(entry.domainLookupStart, entry.fetchStart, "domainLookupStart after fetchStart");
38     assert_greater_than_equal(entry.domainLookupEnd, entry.domainLookupStart, "domainLookupEnd after domainLookupStart");
39     assert_greater_than_equal(entry.connectStart, entry.domainLookupEnd, "connectStart after domainLookupEnd");
40     assert_greater_than_equal(entry.connectEnd, entry.connectStart, "connectEnd after connectStart");
41     assert_greater_than_equal(entry.requestStart, entry.connectEnd, "requestStart after connectEnd");
42     assert_greater_than_equal(entry.responseStart, entry.requestStart, "responseStart after requestStart");
43     assert_greater_than_equal(entry.responseEnd, entry.responseStart, "responseEnd after responseStart");
44 }
45
46 function assertDisallowedTimingData(entry) {
47     // These attributes must be zero:
48     // https://w3c.github.io/resource-timing/#cross-origin-resources
49     const keys = [
50         "redirectStart",
51         "redirectEnd",
52         "domainLookupStart",
53         "domainLookupEnd",
54         "connectStart",
55         "connectEnd",
56         "requestStart",
57         "responseStart",
58         "secureConnectionStart",
59     ];
60     for (let key of keys)
61         assert_equals(entry[key], 0, `entry ${key} must be zero for Cross Origin resource without passing Timing-Allow-Origin check`);
62 }
63
64 // No-redirect
65
66 promise_test(function(t) {
67     let promise = observeResources(1).then(([entry]) => {
68         assertNonRedirectTimingData(entry);
69         assertAllowedTimingData(entry);
70     });
71     let url = uniqueDataURL("same-origin-1", "same-origin");
72     fetch(url);
73     return promise;
74 }, "Same Origin request must have timing data");
75
76 promise_test(function(t) {
77     let promise = observeResources(1).then(([entry]) => {
78         assertNonRedirectTimingData(entry);
79         assertDisallowedTimingData(entry);
80     });
81     let url = uniqueDataURL("cross-origin-1", "cross-origin");
82     url = url + "&pipe=header(Access-Control-Allow-Origin,*)";
83     fetch(url);
84     return promise;
85 }, "Cross Origin resource without Timing-Allow-Origin must have filtered timing data");
86
87 promise_test(function(t) {
88     let promise = observeResources(1).then(([entry]) => {
89         assertNonRedirectTimingData(entry);
90         assertDisallowedTimingData(entry);
91     });
92     let url = uniqueDataURL("null", "cross-origin");
93     url = addTimingAllowOriginHeader(url, "null");
94     fetch(url);
95     return promise;
96 }, "Cross Origin resource with Timing-Allow-Origin null value must have filtered timing data");
97
98 promise_test(function(t) {
99     let promise = observeResources(1).then(([entry]) => {
100         assertNonRedirectTimingData(entry);
101         assertAllowedTimingData(entry);
102     });
103     let url = uniqueDataURL("wildcard", "cross-origin");
104     url = addTimingAllowOriginHeader(url, "*");
105     fetch(url);
106     return promise;
107 }, "Cross Origin resource with Timing-Allow-Origin wildcard must have timing data");
108
109 promise_test(function(t) {
110     let promise = observeResources(1).then(([entry]) => {
111         assertNonRedirectTimingData(entry);
112         assertAllowedTimingData(entry);
113     });
114     let url = uniqueDataURL("only-entry", "cross-origin");
115     url = addTimingAllowOriginHeader(url, location.origin);
116     fetch(url);
117     return promise;
118 }, "Cross Origin resource with origin in Timing-Allow-Origin list must have timing data (only entry)");
119
120 promise_test(function(t) {
121     let promise = observeResources(1).then(([entry]) => {
122         assertNonRedirectTimingData(entry);
123         assertAllowedTimingData(entry);
124     });
125     let url = uniqueDataURL("middle-entry", "cross-origin");
126     url = addCommaSeparatedTimingAllowOriginHeaders(url, ["example.com", location.origin, "example.com"]);
127     fetch(url);
128     return promise;
129 }, "Cross Origin resource with origin in Timing-Allow-Origin list must have timing data (middle entry, comma separated)");
130
131 promise_test(function(t) {
132     let promise = observeResources(1).then(([entry]) => {
133         assertNonRedirectTimingData(entry);
134         assertAllowedTimingData(entry);
135     });
136     let url = uniqueDataURL("middle-entry", "cross-origin");
137     url = addMultipleTimingAllowOriginHeaders(url, ["example.com", location.origin, "example.com"]);
138     fetch(url);
139     return promise;
140 }, "Cross Origin resource with origin in Timing-Allow-Origin list must have timing data (middle entry, multiple headers)");
141
142 promise_test(function(t) {
143     let promise = observeResources(1).then(([entry]) => {
144         assertNonRedirectTimingData(entry);
145         assertDisallowedTimingData(entry); });
146     let url = uniqueDataURL("other-origins", "cross-origin");
147     url = addCommaSeparatedTimingAllowOriginHeaders(url, [location.origin + ".test", "x" + location.origin]);
148     fetch(url);
149     return promise;
150 }, "Cross Origin resource with origin not in Timing-Allow-Origin list must have filtered timing data (other origins, comma separated)");
151
152 promise_test(function(t) {
153     let promise = observeResources(1).then(([entry]) => {
154         assertNonRedirectTimingData(entry);
155         assertDisallowedTimingData(entry);
156     });
157     let url = uniqueDataURL("other-origins", "cross-origin");
158     url = addMultipleTimingAllowOriginHeaders(url, [location.origin + ".test", "x" + location.origin]);
159     fetch(url);
160     return promise;
161 }, "Cross Origin resource with origin not in Timing-Allow-Origin list must have filtered timing data (other origins, multiple headers)");
162
163 promise_test(function(t) {
164     let promise = observeResources(1).then(([entry]) => {
165         assertNonRedirectTimingData(entry);
166         assertDisallowedTimingData(entry);
167     });
168     let url = uniqueDataURL("case-sensitive", "cross-origin");
169     url = addTimingAllowOriginHeader(url, location.origin.toUpperCase());
170     fetch(url);
171     return promise;
172 }, "Cross Origin resource with origin not in Timing-Allow-Origin list must have filtered timing data (case-sensitive)");
173
174 // Redirects
175
176 promise_test(function(t) {
177     let promise = observeResources(1).then(([entry]) => {
178         assertRedirectTimingData(entry);
179         assertAllowedTimingData(entry);
180     });
181     let url = uniqueDataURL("redirect-same-origin-1", "same-origin");
182     fetch(urlWithRedirectTo(url));
183     return promise;
184 }, "Redirect to Same Origin request must have timing data");
185
186 promise_test(function(t) {
187     let promise = observeResources(1).then(([entry]) => {
188         assertRedirectWithDisallowedTimingData(entry);
189         assertDisallowedTimingData(entry);
190     });
191     let url = uniqueDataURL("redirect-cross-origin-1", "cross-origin");
192     url = url + "&pipe=header(Access-Control-Allow-Origin,*)";
193     fetch(urlWithRedirectTo(url));
194     return promise;
195 }, "Redirect to Cross Origin resource without Timing-Allow-Origin must have filtered timing data");
196
197 promise_test(function(t) {
198     let promise = observeResources(1).then(([entry]) => {
199         assertRedirectWithDisallowedTimingData(entry);
200         assertDisallowedTimingData(entry);
201     });
202     let url = uniqueDataURL("redirect-null", "cross-origin");
203     url = addTimingAllowOriginHeader(url, "null");
204     fetch(urlWithRedirectTo(url));
205     return promise;
206 }, "Redirect to Cross Origin resource with Timing-Allow-Origin null value must have filtered timing data");
207
208 promise_test(function(t) {
209     let promise = observeResources(1).then(([entry]) => {
210         assertRedirectTimingData(entry);
211         assertAllowedTimingData(entry);
212     });
213     let url = uniqueDataURL("redirect-wildcard", "cross-origin");
214     url = addTimingAllowOriginHeader(url, "*");
215     fetch(urlWithRedirectTo(url));
216     return promise;
217 }, "Redirect to Cross Origin resource with Timing-Allow-Origin wildcard must have timing data");
218
219 promise_test(function(t) {
220     let promise = observeResources(1).then(([entry]) => {
221         assertRedirectTimingData(entry);
222         assertAllowedTimingData(entry);
223     });
224     let url = uniqueDataURL("redirect-only-entry", "cross-origin");
225     url = addTimingAllowOriginHeader(url, location.origin);
226     fetch(urlWithRedirectTo(url));
227     return promise;
228 }, "Redirect to Cross Origin resource with origin in Timing-Allow-Origin list must have timing data (only entry)");
229
230 promise_test(function(t) {
231     let promise = observeResources(1).then(([entry]) => {
232         assertRedirectTimingData(entry);
233         assertAllowedTimingData(entry);
234     });
235     let url = uniqueDataURL("redirect-middle-entry", "cross-origin");
236     url = addCommaSeparatedTimingAllowOriginHeaders(url, ["example.com", location.origin, "example.com"]);
237     fetch(urlWithRedirectTo(url));
238     return promise;
239 }, "Redirect to Cross Origin resource with origin in Timing-Allow-Origin list must have timing data (middle entry, comma separated)");
240
241 promise_test(function(t) {
242     let promise = observeResources(1).then(([entry]) => {
243         assertRedirectTimingData(entry);
244         assertAllowedTimingData(entry);
245     });
246     let url = uniqueDataURL("redirect-middle-entry", "cross-origin");
247     url = addMultipleTimingAllowOriginHeaders(url, ["example.com", location.origin, "example.com"]);
248     fetch(urlWithRedirectTo(url));
249     return promise;
250 }, "Redirect to Cross Origin resource with origin in Timing-Allow-Origin list must have timing data (middle entry, multiple headers)");
251
252 promise_test(function(t) {
253     let promise = observeResources(1).then(([entry]) => {
254         assertRedirectWithDisallowedTimingData(entry);
255         assertDisallowedTimingData(entry);
256     });
257     let url = uniqueDataURL("redirect-other-origins", "cross-origin");
258     url = addCommaSeparatedTimingAllowOriginHeaders(url, [location.origin + ".test", "x" + location.origin]);
259     fetch(urlWithRedirectTo(url));
260     return promise;
261 }, "Redirect to Cross Origin resource with origin not in Timing-Allow-Origin list must have filtered timing data (other origins, comma separated)");
262
263 promise_test(function(t) {
264     let promise = observeResources(1).then(([entry]) => {
265         assertRedirectWithDisallowedTimingData(entry);
266         assertDisallowedTimingData(entry);
267     });
268     let url = uniqueDataURL("redirect-other-origins", "cross-origin");
269     url = addMultipleTimingAllowOriginHeaders(url, [location.origin + ".test", "x" + location.origin]);
270     fetch(urlWithRedirectTo(url));
271     return promise;
272 }, "Redirect to Cross Origin resource with origin not in Timing-Allow-Origin list must have filtered timing data (other origins, multiple headers)");
273
274 promise_test(function(t) {
275     let promise = observeResources(1).then(([entry]) => {
276         assertRedirectWithDisallowedTimingData(entry);
277         assertDisallowedTimingData(entry);
278     });
279     let url = uniqueDataURL("redirect-case-sensitive", "cross-origin");
280     url = addTimingAllowOriginHeader(url, location.origin.toUpperCase());
281     fetch(urlWithRedirectTo(url));
282     return promise;
283 }, "Redirect to Cross Origin resource with origin not in Timing-Allow-Origin list must have filtered timing data (case-sensitive)");
284
285
286 // Multiple redirects
287
288 promise_test(function(t) {
289     let promise = observeResources(1).then(([entry]) => {
290         assertRedirectTimingData(entry);
291         assertAllowedTimingData(entry);
292     });
293     let url = uniqueDataURL("multiple-redirect-same-origin", "same-origin");
294     let urlRedirect1 = urlWithRedirectTo(url);
295     let urlRedirect2 = urlWithRedirectTo(urlRedirect1);
296     let urlRedirect3 = urlWithRedirectTo(urlRedirect2);
297     fetch(urlRedirect3);
298     return promise;
299 }, "Multiple level redirect to Same Origin resource must have timing data");
300
301 promise_test(function(t) {
302     let promise = observeResources(1).then(([entry]) => {
303         assertRedirectWithDisallowedTimingData(entry);
304         assertDisallowedTimingData(entry);
305     });
306     let url = uniqueDataURL("multiple-redirect-cross-origin", "cross-origin");
307     url += "&pipe=header(Access-Control-Allow-Origin,*)";
308     let urlRedirect1 = urlWithRedirectTo(url);
309     let urlRedirect2 = urlWithRedirectTo(urlRedirect1);
310     let urlRedirect3 = urlWithRedirectTo(urlRedirect2);
311     fetch(urlRedirect3);
312     return promise;
313 }, "Multiple level redirect to Cross Origin resource without Timing-Allow-Origin must have must have filtered timing data");
314
315 promise_test(function(t) {
316     let promise = observeResources(1).then(([entry]) => {
317         assertRedirectTimingData(entry);
318         assertAllowedTimingData(entry);
319     });
320     let url = uniqueDataURL("multiple-redirect-cross-origin-timing-allowed", "cross-origin");
321     url = addTimingAllowOriginHeader(url, location.origin);
322     let urlRedirect1 = urlWithRedirectTo(url);
323     let urlRedirect2 = urlWithRedirectTo(urlRedirect1);
324     let urlRedirect3 = urlWithRedirectTo(urlRedirect2);
325     fetch(urlRedirect3);
326     return promise;
327 }, "Multiple level redirect to Cross Origin resource with Timing-Allow-Origin must have must have timing data");
328
329 // FIXME: Same Origin -> Cross Origin (no Timing-Allow-Origin) -> Same Origin
330 // FIXME: Same Origin -> Cross Origin (with Timing-Allow-Origin) -> Same Origin