summaryrefslogtreecommitdiffstats
path: root/dom/security/test/sec-fetch/test_iframe_src_metaRedirect.html
blob: 28eae802268e9b15cfa72f37efa7b5b29c198170 (plain)
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.src = "...".
 * 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.src = REQUEST_URL + "?meta";
document.body.appendChild(frame);

</script>
</body>
</html>