| <!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> |