1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1647128 - Fetch Metadata Headers contain invalid value for Sec-Fetch-Site for meta redirects</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
/*
* Description of the test:
* We load site A that redirects to site B using a meta refresh,
* finally site B redirects to site C via a 302 redirect.
* The first load of site A is made by an iframe: frame.srcdoc = "<meta ...".
* We check that all requests have the Sec-Fetch-* headers set appropriately.
*/
SimpleTest.waitForExplicitFinish();
const REQUEST_URL = "https://example.com/tests/dom/security/test/sec-fetch/file_redirect.sjs";
let testPassCounter = 0;
var script = SpecialPowers.loadChromeScript(() => {
/* eslint-env mozilla/chrome-script */
Services.obs.addObserver(function onExamResp(subject, topic, data) {
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
if (!channel.URI.spec.startsWith("https://example.com/tests/dom/security/test/sec-fetch/file_redirect.sjs")) {
return;
}
// The redirection flow is the following:
// http://mochi.test:8888 -> https://example.com?meta -> https://example.com?redirect302 -> https://example.com?pageC
// So the Sec-Fetch-* headers for each request should be:
const expectedHeaders = {
"?meta": {
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Dest": "iframe",
"Sec-Fetch-User": null,
},
"?redirect302": {
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Dest": "iframe",
"Sec-Fetch-User": null,
},
"?pageC": {
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Dest": "iframe",
"Sec-Fetch-User": null,
},
};
let matchedOne = false;
for (const [query, headers] of Object.entries(expectedHeaders)) {
if (!channel.URI.spec.endsWith(query)) {
continue;
}
matchedOne = true;
for (const [header, value] of Object.entries(headers)) {
try {
is(channel.getRequestHeader(header), value, `testing ${header} for the ${query} query`);
} catch (e) {
is(header, "Sec-Fetch-User", "testing Sec-Fetch-User");
}
}
}
ok(matchedOne, "testing expectedHeaders");
sendAsyncMessage("test-pass");
}, "http-on-stop-request");
});
script.addMessageListener("test-pass", async () => {
testPassCounter++;
if (testPassCounter < 3) {
return;
}
// If we received "test-pass" 3 times we know that all loads had Sec-Fetch-* headers set appropriately.
SimpleTest.finish();
});
let frame = document.createElement("iframe");
frame.srcdoc = `<meta http-equiv="refresh" content="0; url='${REQUEST_URL}?meta'">`;
document.body.appendChild(frame);
</script>
</body>
</html>
|