File: document-state.https.html

package info (click to toggle)
thunderbird 1%3A115.16.0esr-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,476,252 kB
  • sloc: cpp: 6,972,150; javascript: 5,209,211; ansic: 3,507,222; python: 1,137,609; asm: 432,531; xml: 205,149; java: 175,761; sh: 116,485; makefile: 22,152; perl: 13,971; objc: 12,561; yacc: 4,583; pascal: 2,840; lex: 1,720; ruby: 1,075; exp: 762; sql: 666; awk: 580; php: 436; lisp: 430; sed: 70; csh: 10
file content (135 lines) | stat: -rw-r--r-- 6,312 bytes parent folder | download | duplicates (4)
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test the properties of a session history entry's document state</title>
<link rel="help" href="https://html.spec.whatwg.org/#document-state">
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<body>
<script>
// In this test, we create an auxiliary window with a session history A -> B,
// where the document on site B is the current active document. Bf-cache is
// disabled via `Cache-Control: no-store` headers. We then `history.back()` to
// site A, and perform `location.replace(B)`. This makes the first document in
// the session history now same-origin/site with the URL in the subsequent
// session history entry's document state.
//
// We then perform `history.forward()` in the first document, which loads the
// second document (from network). We confirm that the resulting navigation
// request was made with the expected state, stored on the history entry's
// document state. The consequences of this are:
//  - The navigation is made with the `Sec-Fetch-Site: cross-site` header,
//    indicating that the *original* document state's initiator origin was
//    preserved
//  - The navigation is made with a cross-origin `Referer` header, indicating
//    that the *original* document state's referrer was preserved
//  - The resulting document has a cross-origin `document.referrer`, indicating
//    the same as above
promise_test(async t => {
  const rcHelper = new RemoteContextHelper();
  const A = await rcHelper.addWindow();

  // Create B on a new origin (with bf-cache disabled).
  const B = await A.navigateToNew({
    origin: 'HTTPS_NOTSAMESITE_ORIGIN',
    headers: [['Cache-Control', 'no-store']],
  });

  // This is the origin we're going to navigate A to, so that it becomes
  // same-origin with B.
  const originB = new URL(await B.executeScript(() => location.href)).origin;
  await B.historyBack();

  // Make A navigate to the same document but in origin B:
  const urlA = await A.executeScript(() => location.href);
  const originA = new URL(urlA).origin;
  assert_not_equals(originA, originB, 'Contexts A and B are cross-origin');

  // Load A's current document but on origin B.
  const newUrlOnOriginB = urlA.replace(originA, originB);
  await A.navigate((url) => {
    location.replace(url);
  }, [newUrlOnOriginB]);

  // Assert that A and B are now same-origin:
  const newUrlA = await A.executeScript(() => {
    return location.href;
  });

  // Now the session history looks like:
  // B -> B (initiator origin: A)
  assert_equals(new URL(newUrlA).origin, originB);

  // This means that when we navigate forward, we should request the second
  // document with the history entry's document state, which mostly preserves
  // parameters from the original initiator (a cross-site document), despite a
  // now-same-origin document initiating this navigation via history.
  await A.historyForward();

  const secFetchSite = await B.executeScript(() => window.requestHeaders['sec-fetch-site']);
  const referrer = await B.executeScript(() => window.requestHeaders['referer']);
  const documentReferrer = await B.executeScript(() => document.referrer);

  assert_equals(secFetchSite, 'cross-site',
      'Same-origin forward history navigation to a document whose original ' +
      'initiator was cross-site, ends up with Sec-Fetch-Dest: cross-site ' +
      'header');
  assert_equals(referrer, originA + '/',
      'Same-origin forward history navigation to a document whose original ' +
      'initiator was cross-site ends up with the Referer header that is the ' +
      'original cross-site initiator');
  assert_equals(documentReferrer, originA + '/',
      'Same-origin forward history navigation to a document whose original ' +
      'initiator was cross-site ends up with document.referrer that is the ' +
      'original cross-site initiator');
}, "A navigation's initiator origin and referrer are stored in the document " +
   "state and used in the document repopulation case");

// This test is similar to the above, but instead of testing for the true
// history entry -> document state -> document repopulation case, we stay on [B]
// (the document who was navigated to from [A]) and run `location.reload()` to
// confirm that the initiator information from the [A] -> [B] navigation is used
// when reloading [B], not [B]'s own same-origin information.
promise_test(async t => {
  const rcHelper = new RemoteContextHelper();
  const A = await rcHelper.addWindow();

  const originA = new URL(await A.executeScript(() => location.href)).origin;

  // Create B on a new origin.
  const B = await A.navigateToNew({
    origin: 'HTTPS_NOTSAMESITE_ORIGIN',
  });

  const originB = new URL(await B.executeScript(() => location.href)).origin;
  assert_not_equals(originA, originB, 'Contexts A and B are cross-origin');

  // Reload B.
  await B.navigate(() => {
    location.reload();
  }, []);

  const secFetchSite = await B.executeScript(() => window.requestHeaders['sec-fetch-site']);
  const referrer = await B.executeScript(() => window.requestHeaders['referer']);
  const documentReferrer = await B.executeScript(() => document.referrer);

  assert_equals(secFetchSite, 'cross-site',
      'Same-origin forward history navigation to a document whose original ' +
      'initiator was cross-site, ends up with Sec-Fetch-Dest: cross-site ' +
      'header');
  assert_equals(referrer, originA + '/',
      'Same-origin forward history navigation to a document whose original ' +
      'initiator was cross-site ends up with the Referer header that is the ' +
      'original cross-site initiator');
  assert_equals(documentReferrer, originA + '/',
      'Same-origin forward history navigation to a document whose original ' +
      'initiator was cross-site ends up with document.referrer that is the ' +
      'original cross-site initiator');
}, "A navigation's initiator origin and referrer are stored in the document " +
   "state and used on location.reload()");
</script>
</body>