File: headers.https.html

package info (click to toggle)
firefox 143.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,617,328 kB
  • sloc: cpp: 7,478,492; javascript: 6,417,157; ansic: 3,720,058; python: 1,396,372; xml: 627,523; asm: 438,677; java: 186,156; sh: 63,477; makefile: 19,171; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,405; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (159 lines) | stat: -rw-r--r-- 6,069 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<!DOCTYPE html>
<title>Sec-Purpose header on prerendered page</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.js"></script>

<body>
<script>
setup(() => assertSpeculationRulesIsSupported());

promise_test(async () => {
  const rcHelper = new PrerenderingRemoteContextHelper();
  const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' });
  const prerenderedRC = await referrerRC.addPrerender();

  const prerenderedHeaders = await prerenderedRC.getRequestHeaders();
  assertHeaders(prerenderedHeaders, true, true, 'prerendered page');

  const iframeRC = await prerenderedRC.addIframe();
  const iframeHeaders = await iframeRC.getRequestHeaders();
  assertHeaders(iframeHeaders, true, false, 'iframe');

  // No test for cross-origin iframe, since those requests are delayed until
  // after activation. See below.

  const imageHeaders = await insertImageAndGetRequestHeaders(prerenderedRC);
  assertHeaders(imageHeaders, true, false, 'image');

  const crossOriginImageHeaders = await insertImageAndGetRequestHeaders(
    prerenderedRC,
    get_host_info().HTTPS_REMOTE_ORIGIN
  );
  assertHeaders(crossOriginImageHeaders, true, false, 'cross-origin image');

  const fetchHeaders = await doFetchAndGetRequestHeaders(prerenderedRC);
  assertHeaders(fetchHeaders, true, false, 'fetch');

  const crossOriginFetchHeaders = await doFetchAndGetRequestHeaders(
    prerenderedRC,
    get_host_info().HTTPS_REMOTE_ORIGIN
  );
  assertHeaders(crossOriginFetchHeaders, true, false, 'cross-origin fetch');

  const navigatedToRC = await prerenderedRC.navigateToNew();
  const navigatedToHeaders = await navigatedToRC.getRequestHeaders();
  assertHeaders(navigatedToHeaders, true, false, 'navigated-to page');
}, 'Headers before activation, including prerendered page navigation');

promise_test(async () => {
  const rcHelper = new PrerenderingRemoteContextHelper();
  const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' });
  const prerenderedRC = await referrerRC.addPrerender();

  // Add the iframe now, but only check its headers after activation.
  const crossOriginIframeBeforeActivationRC = await prerenderedRC.addIframe({ origin: 'HTTPS_REMOTE_ORIGIN' });

  await referrerRC.navigateExpectingPrerenderingActivation(prerenderedRC);

  const crossOriginIframeBeforeActivationHeaders = await crossOriginIframeBeforeActivationRC.getRequestHeaders();
  assertHeaders(crossOriginIframeBeforeActivationHeaders, true, false, 'cross-origin iframe before activation');

  const iframeRC = await prerenderedRC.addIframe();
  const iframeHeaders = await iframeRC.getRequestHeaders();
  assertHeaders(iframeHeaders, false, false, 'post-activation iframe');

  const imageHeaders = await insertImageAndGetRequestHeaders(prerenderedRC);
  assertHeaders(imageHeaders, false, false, 'post-activation image');

  const crossOriginImageHeaders = await insertImageAndGetRequestHeaders(
    prerenderedRC,
    get_host_info().HTTPS_REMOTE_ORIGIN
  );
  assertHeaders(crossOriginImageHeaders, false, false, 'cross-origin image');

  const fetchHeaders = await doFetchAndGetRequestHeaders(prerenderedRC);
  assertHeaders(fetchHeaders, false, false, 'post-activation fetch');

  const crossOriginFetchHeaders = await doFetchAndGetRequestHeaders(
    prerenderedRC,
    get_host_info().HTTPS_REMOTE_ORIGIN
  );
  assertHeaders(crossOriginFetchHeaders, false, false, 'cross-origin fetch');
}, 'Headers after activation (plus cross-origin iframe before activation)');

async function insertImageAndGetRequestHeaders(rc, hostname) {
  const uuid = token();
  const url = (new URL(`resources/image-with-headers-stash.py?image=${uuid}`, location.href));
  const headersURL = (new URL(`resources/image-with-headers-stash.py?read=${uuid}`, location.href));

  if (hostname !== undefined) {
    url.hostname = hostname;
    headersURL.hostname = hostname;
  }

  await rc.executeScript(async (url) => {
    const img = new Image();
    img.src = url;
    const promise = new Promise(resolve => img.onload = resolve);
    document.body.append(img);
    return promise;
  }, [url]);

  const headersJSON = await (await fetch(headersURL)).json();
  assert_not_equals(headersJSON, null, 'image headers should not be null');
  return new Headers(headersJSON);
}

async function doFetchAndGetRequestHeaders(rc, hostname) {
  const uuid = token();
  const url = (new URL(`resources/image-with-headers-stash.py?image=${uuid}`, location.href));
  const headersURL = (new URL(`resources/image-with-headers-stash.py?read=${uuid}`, location.href));

  if (hostname !== undefined) {
    url.hostname = hostname;
    headersURL.hostname = hostname;
  }

  await rc.executeScript(async (url) => {
    return fetch(url, { mode: "cors" });
  }, [url]);

  const headersJSON = await (await fetch(headersURL)).json();
  assert_not_equals(headersJSON, null, 'fetch headers should not be null');
  return new Headers(headersJSON);
}

function assertHeaders(headers, secPurposeIsPrefetchPrerender, secSpeculationTagsIsPresent, label) {
  if (secPurposeIsPrefetchPrerender) {
    assert_equals(
      headers.get('Sec-Purpose'),
      'prefetch;prerender',
      `${label} Sec-Purpose`
    );
  } else {
    assert_false(
      headers.has('Sec-Purpose'),
      `${label} Sec-Purpose should not be present`
    );
  }
  if (secSpeculationTagsIsPresent) {
    assert_equals(
      headers.get('Sec-Speculation-Tags'),
      'null',
      `${label} Sec-Speculation-Tags`
    );
  } else {
    assert_false(
      headers.has('Sec-Speculation-Tags'),
      `${label} Sec-Speculation-Tags should not be present`
    );
  }
}
</script>