Skip to content

Commit 21cd6f0

Browse files
Change default classic script fetch options credentials mode
This CL changes the default classic script fetch options credentials mode from "omit" to "same-origin", as per the recent spec change [1], and adds descendant worker credentials tests as a follow-up to said spec change and [2]. [1]: whatwg/html#3656 [2]: #13426 [email protected], [email protected], [email protected] Bug: 849101 Change-Id: I958f552f0ee91beb8aab98269f79a1eb219fb40a Reviewed-on: https://chromium-review.googlesource.com/c/1301964 Commit-Queue: Dominic Farolino <[email protected]> Reviewed-by: Kouhei Ueno <[email protected]> Reviewed-by: Hiroki Nakagawa <[email protected]> Cr-Commit-Position: refs/heads/master@{#604862}
1 parent 69a2952 commit 21cd6f0

7 files changed

+251
-26
lines changed

workers/modules/dedicated-worker-options-credentials.html

Lines changed: 243 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,84 +2,302 @@
22
<title>DedicatedWorker: WorkerOptions 'credentials'</title>
33
<script src="/resources/testharness.js"></script>
44
<script src="/resources/testharnessreport.js"></script>
5+
<script src="/common/get-host-info.sub.js"></script>
56
<script>
7+
host_info = get_host_info();
68

79
// Determines the expected cookie value to be reported by a dedicated worker
810
// based on the given option. The worker reports an empty string as the actual
911
// cookie value if the cookie wasn't sent to the server. Otherwise, it's the
1012
// value set by the headers file:
1113
// "dedicated-worker-options-credentials.html.headers"
12-
function DetermineExpectedCookieValue(options) {
13-
// Classic script loading should always send credentials regardless of the
14-
// 'credentials' option because the spec says the option takes effect only
15-
// for module script loading.
16-
if (options.type == 'classic')
17-
return 'COOKIE_VALUE';
18-
assert_equals(options.type, 'module');
19-
20-
if (!options.credentials ||
21-
options.credentials == 'same-origin' ||
22-
options.credentials == 'include') {
23-
return 'COOKIE_VALUE';
14+
function DetermineExpectedCookieValue(options, config) {
15+
// Valid WorkerOptions and test config checking.
16+
if (config.origin !== 'same' && config.origin !== 'remote')
17+
assert_unreached('Invalid config.origin was specified: ' + config.origin);
18+
if (options.credentials && options.credentials !== 'omit' &&
19+
options.credentials !== 'same-origin' &&
20+
options.credentials !== 'include') {
21+
assert_unreached('Invalid credentials option was specified: ' +
22+
options.credentials);
2423
}
25-
if (options.credentials == 'omit')
24+
if (options.type !== 'classic' && options.type !== 'module')
25+
assert_unreached('Invalid type option was specified: ' + options.type);
26+
27+
if (options.type === 'classic')
28+
return (config.origin === 'same') ? '1' : '';
29+
30+
if (options.credentials === 'omit')
2631
return '';
27-
assert_unreached('Invalid credentials option was specified: ' +
28-
options.credentials);
32+
else if (options.credentials === 'include')
33+
return '1';
34+
else
35+
return (config.origin === 'same') ? '1' : '';
2936
}
3037

3138
// Runs a credentials test with the given WorkerOptions.
32-
function credentials_test(options, description) {
39+
//
40+
// |options| is a WorkerOptions dict.
41+
// |config| has options as follows:
42+
//
43+
// config = {
44+
// fetchType: 'top-level' or 'descendant-static' or 'descendant-dynamic'
45+
// origin: 'remote' or 'same'
46+
// };
47+
//
48+
// - |config.fetchType| indicates the type of script to load for the test.
49+
// - |config.origin| indicates same-origin-ness of the script to load.
50+
function credentials_test(options, config, description) {
3351
promise_test(async () => {
34-
const worker = new Worker('resources/credentials.py', options);
52+
let workerURL, origin = config.origin;
53+
if (config.fetchType === 'top-level') {
54+
workerURL = 'resources/credentials.py';
55+
} else if (config.fetchType === 'descendant-static') {
56+
workerURL =
57+
`resources/static-import-${origin}-origin-credentials-checker-worker.${origin === 'same' ? '' : 'sub.'}js`;
58+
} else if (config.fetchType === 'descendant-dynamic') {
59+
workerURL =
60+
`resources/dynamic-import-${origin}-origin-credentials-checker-worker.${origin === 'same' ? '' : 'sub.'}js`;
61+
} else {
62+
assert_unreached('Invalid config.fetchType: ' + config.fetchType);
63+
}
64+
65+
const worker = new Worker(workerURL, options);
3566

3667
// Wait until the worker sends the actual cookie value.
3768
const msg_event = await new Promise(resolve => worker.onmessage = resolve);
3869

39-
const expectedCookieValue = DetermineExpectedCookieValue(options);
70+
const expectedCookieValue = DetermineExpectedCookieValue(options, config);
4071
assert_equals(msg_event.data, expectedCookieValue);
4172
}, description);
4273
}
4374

44-
// Tests for module scripts.
75+
function init() {
76+
// Same-origin cookie is set up in the .headers file in this directory.
77+
promise_test(async () => {
78+
return fetch(
79+
`${host_info.HTTP_REMOTE_ORIGIN}/cookies/resources/set-cookie.py?name=COOKIE_NAME&path=/workers/modules/`,
80+
{
81+
mode: 'no-cors',
82+
credentials: 'include'
83+
});
84+
}, 'Test initialization: setting up cross-origin cookie');
85+
}
86+
87+
init();
88+
89+
// Tests for module workers.
90+
91+
credentials_test(
92+
{ type: 'module' },
93+
{ fetchType: 'top-level', origin: 'same' },
94+
'new Worker() with type=module and default credentials option should ' +
95+
'behave as credentials=same-origin and send the credentials');
96+
97+
credentials_test(
98+
{ credentials: 'omit', type: 'module' },
99+
{ fetchType: 'top-level', origin: 'same' },
100+
'new Worker() with type=module and credentials=omit should not send the ' +
101+
'credentials');
102+
103+
credentials_test(
104+
{ credentials: 'same-origin', type: 'module' },
105+
{ fetchType: 'top-level', origin: 'same' },
106+
'new Worker() with type=module and credentials=same-origin should send ' +
107+
'the credentials');
108+
109+
credentials_test(
110+
{ credentials: 'include', type: 'module' },
111+
{ fetchType: 'top-level', origin: 'same' },
112+
'new Worker() with type=module and credentials=include should send the ' +
113+
'credentials');
114+
115+
// Tests for module worker static imports.
116+
117+
credentials_test(
118+
{ type: 'module' },
119+
{ fetchType: 'descendant-static', origin: 'same' },
120+
'new Worker() with type=module and default credentials option should ' +
121+
'behave as credentials=same-origin and send the credentials for ' +
122+
'same-origin static imports');
123+
124+
credentials_test(
125+
{ credentials: 'omit', type: 'module' },
126+
{ fetchType: 'descendant-static', origin: 'same' },
127+
'new Worker() with type=module and credentials=omit should not send the ' +
128+
'credentials for same-origin static imports');
129+
130+
credentials_test(
131+
{ credentials: 'same-origin', type: 'module' },
132+
{ fetchType: 'descendant-static', origin: 'same' },
133+
'new Worker() with type=module and credentials=same-origin should send ' +
134+
'the credentials for same-origin static imports');
135+
136+
credentials_test(
137+
{ credentials: 'include', type: 'module' },
138+
{ fetchType: 'descendant-static', origin: 'same' },
139+
'new Worker() with type=module and credentials=include should send the ' +
140+
'credentials for same-origin static imports');
141+
142+
credentials_test(
143+
{ type: 'module' },
144+
{ fetchType: 'descendant-static', origin: 'remote' },
145+
'new Worker() with type=module and default credentials option should ' +
146+
'behave as credentials=same-origin and not send the credentials for ' +
147+
'cross-origin static imports');
148+
149+
credentials_test(
150+
{ credentials: 'omit', type: 'module' },
151+
{ fetchType: 'descendant-static', origin: 'remote' },
152+
'new Worker() with type-module credentials=omit should not send the ' +
153+
'credentials for cross-origin static imports');
154+
155+
credentials_test(
156+
{ credentials: 'same-origin', type: 'module' },
157+
{ fetchType: 'descendant-static', origin: 'remote' },
158+
'new Worker() with type=module and credentials=same-origin should not ' +
159+
'send the credentials for cross-origin static imports');
160+
161+
credentials_test(
162+
{ credentials: 'include', type: 'module' },
163+
{ fetchType: 'descendant-static', origin: 'remote' },
164+
'new Worker() with type=module and credentials=include should send the ' +
165+
'credentials for cross-origin static imports');
166+
167+
// Tests for module worker dynamic imports.
168+
169+
credentials_test(
170+
{ type: 'module' },
171+
{ fetchType: 'descendant-dynamic', origin: 'same' },
172+
'new Worker() with type=module and default credentials option should ' +
173+
'behave as credentials=same-origin and send the credentials for ' +
174+
'same-origin dynamic imports');
175+
176+
credentials_test(
177+
{ credentials: 'omit', type: 'module' },
178+
{ fetchType: 'descendant-dynamic', origin: 'same' },
179+
'new Worker() with type=module and credentials=omit should not send the ' +
180+
'credentials for same-origin dynamic imports');
181+
182+
credentials_test(
183+
{ credentials: 'same-origin', type: 'module' },
184+
{ fetchType: 'descendant-dynamic', origin: 'same' },
185+
'new Worker() with type=module and credentials=same-origin should send ' +
186+
'the credentials for same-origin dynamic imports');
187+
188+
credentials_test(
189+
{ credentials: 'include', type: 'module' },
190+
{ fetchType: 'descendant-dynamic', origin: 'same' },
191+
'new Worker() with type=module and credentials=include should send the ' +
192+
'credentials for same-origin dynamic imports');
45193

46194
credentials_test(
47195
{ type: 'module'},
48-
'new Worker() with the default credentials option should behave as ' +
49-
'credentials=same-origin and send the credentials');
196+
{ fetchType: 'descendant-dynamic', origin: 'remote' },
197+
'new Worker() with type=module and default credentials option should ' +
198+
'behave as credentials=same-origin and not send the credentials for ' +
199+
'cross-origin dynamic imports');
50200

51201
credentials_test(
52202
{ credentials: 'omit', type: 'module' },
53-
'new Worker() with credentials=omit should not send the credentials');
203+
{ fetchType: 'descendant-dynamic', origin: 'remote' },
204+
'new Worker() with type-module credentials=omit should not send the ' +
205+
'credentials for cross-origin dynamic imports');
54206

55207
credentials_test(
56208
{ credentials: 'same-origin', type: 'module' },
57-
'new Worker() with credentials=same-origin should send the credentials');
209+
{ fetchType: 'descendant-dynamic', origin: 'remote' },
210+
'new Worker() with type=module and credentials=same-origin should not ' +
211+
'send the credentials for cross-origin dynamic imports');
58212

59213
credentials_test(
60214
{ credentials: 'include', type: 'module' },
61-
'new Worker() with credentials=include should send the credentials');
215+
{ fetchType: 'descendant-dynamic', origin: 'remote' },
216+
'new Worker() with type=module and credentials=include should send the ' +
217+
'credentials for cross-origin dynamic imports');
62218

63-
// Tests for classic scripts.
219+
// Tests for classic workers.
220+
// TODO(domfarolino): Maybe move classic worker tests up a directory?
64221

65222
credentials_test(
66223
{ type: 'classic' },
224+
{ fetchType: 'top-level', origin: 'same' },
67225
'new Worker() with type=classic should always send the credentials ' +
68226
'regardless of the credentials option (default).');
69227

70228
credentials_test(
71229
{ credentials: 'omit', type: 'classic' },
230+
{ fetchType: 'top-level', origin: 'same' },
72231
'new Worker() with type=classic should always send the credentials ' +
73232
'regardless of the credentials option (omit).');
74233

75234
credentials_test(
76235
{ credentials: 'same-origin', type: 'classic' },
236+
{ fetchType: 'top-level', origin: 'same' },
77237
'new Worker() with type=classic should always send the credentials ' +
78238
'regardless of the credentials option (same-origin).');
79239

80240
credentials_test(
81241
{ credentials: 'include', type: 'classic' },
242+
{ fetchType: 'top-level', origin: 'same' },
82243
'new Worker() with type=classic should always send the credentials ' +
83244
'regardless of the credentials option (include).');
84245

246+
// Tests for classic worker dynamic imports.
247+
248+
credentials_test(
249+
{ type: 'classic' },
250+
{ fetchType: 'descendant-dynamic', origin: 'same' },
251+
'new Worker() with type=classic should always send the credentials for ' +
252+
'same-origin dynamic imports regardless of the credentials option ' +
253+
'(default).');
254+
255+
credentials_test(
256+
{ credentials: 'omit', type: 'classic' },
257+
{ fetchType: 'descendant-dynamic', origin: 'same' },
258+
'new Worker() with type=classic should always send the credentials for ' +
259+
'same-origin dynamic imports regardless of the credentials option (omit).');
260+
261+
credentials_test(
262+
{ credentials: 'same-origin', type: 'classic' },
263+
{ fetchType: 'descendant-dynamic', origin: 'same' },
264+
'new Worker() with type=classic should always send the credentials for ' +
265+
'same-origin dynamic imports regardless of the credentials option ' +
266+
'(same-origin).');
267+
268+
credentials_test(
269+
{ credentials: 'include', type: 'classic' },
270+
{ fetchType: 'descendant-dynamic', origin: 'same' },
271+
'new Worker() with type=classic should always send the credentials for ' +
272+
'same-origin dynamic imports regardless of the credentials option ' +
273+
'(include).');
274+
275+
credentials_test(
276+
{ type: 'classic' },
277+
{ fetchType: 'descendant-dynamic', origin: 'remote' },
278+
'new Worker() with type=classic should never send the credentials for ' +
279+
'cross-origin dynamic imports regardless of the credentials option ' +
280+
'(default).');
281+
282+
credentials_test(
283+
{ credentials: 'omit', type: 'classic' },
284+
{ fetchType: 'descendant-dynamic', origin: 'remote' },
285+
'new Worker() with type=classic should never send the credentials for ' +
286+
'cross-origin dynamic imports regardless of the credentials option ' +
287+
'(omit).');
288+
289+
credentials_test(
290+
{ credentials: 'same-origin', type: 'classic' },
291+
{ fetchType: 'descendant-dynamic', origin: 'remote' },
292+
'new Worker() with type=classic should never send the credentials for ' +
293+
'cross-origin dynamic imports regardless of the credentials option ' +
294+
'(same-origin).');
295+
296+
credentials_test(
297+
{ credentials: 'include', type: 'classic' },
298+
{ fetchType: 'descendant-dynamic', origin: 'remote' },
299+
'new Worker() with type=classic should never send the credentials for ' +
300+
'cross-origin dynamic imports regardless of the credentials option ' +
301+
'(include).');
302+
85303
</script>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Set-Cookie: COOKIE_NAME=COOKIE_VALUE
1+
Set-Cookie: COOKIE_NAME=1
22
Access-Control-Allow-Credentials: true

workers/modules/resources/credentials.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ def main(request, response):
22
cookie = request.cookies.first("COOKIE_NAME", None)
33

44
response_headers = [("Content-Type", "text/javascript"),
5+
("Access-Control-Allow-Origin", request.headers.get("Origin")),
56
("Access-Control-Allow-Credentials", "true")]
67

78
cookie_value = '';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Import a remote origin script.
2+
import('http://{{domains[www1]}}:{{ports[http][0]}}/workers/modules/resources/credentials.py');
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import('./credentials.py');
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Import a remote origin script.
2+
import 'http://{{domains[www1]}}:{{ports[http][0]}}/workers/modules/resources/credentials.py';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './credentials.py';

0 commit comments

Comments
 (0)