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 160 161 162
|
<!DOCTYPE html>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src='/resources/testdriver-vendor.js'></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/subset-tests-by-key.js"></script>
<script src="/common/utils.js"></script>
<script src="../../resources/utils.js"></script>
<script src="../resources/utils.sub.js"></script>
<meta name="variant" content="?include=unchanged">
<meta name="variant" content="?include=changed">
<meta name="variant" content="?include=unchangedWithRedirect">
<meta name="variant" content="?include=changedWithRedirect">
<meta name="variant" content="?include=changedWithRedirect2">
<meta name="variant" content="?include=changedWithRedirect3">
<!--
This is a test for the integration of
https://mnot.github.io/I-D/draft-nottingham-http-availability-hints.html
with prefetch. Chromium has an implementation of such integration
behind a flag; see https://issues.chromium.org/issues/328628231.
-->
<script>
setup(() => assertSpeculationRulesIsSupported());
subsetTestByKey("unchanged", promise_test, async t => {
await test_driver.delete_all_cookies();
document.cookie = 'vary1=hello';
let agent = await spawnWindow(t);
let nextUrl = agent.getExecutorURL({ executor: "cookies.py", cookieindices: "1" });
await agent.forceSinglePrefetch(nextUrl);
await agent.navigate(nextUrl);
assert_prefetched(await agent.getRequestHeaders());
let request_cookies = await agent.getRequestCookies();
let response_cookies = await agent.getResponseCookies();
assert_equals(request_cookies.vary1, "hello");
assert_equals(request_cookies.vary2, undefined);
assert_equals(response_cookies.vary1, "hello");
assert_equals(response_cookies.vary2, undefined);
}, "Cookie-Indices should not prevent a prefetch from succeeding if the cookie has not changed.");
subsetTestByKey("changed", promise_test, async t => {
await test_driver.delete_all_cookies();
document.cookie = 'vary1=hello';
let agent = await spawnWindow(t);
let nextUrl = agent.getExecutorURL({ executor: "cookies.py", cookieindices: "1" });
await agent.forceSinglePrefetch(nextUrl);
document.cookie = 'vary1=two';
await agent.navigate(nextUrl);
assert_not_prefetched(await agent.getRequestHeaders());
let request_cookies = await agent.getRequestCookies();
let response_cookies = await agent.getResponseCookies();
assert_equals(request_cookies.vary1, "two");
assert_equals(request_cookies.vary2, undefined);
assert_equals(response_cookies.vary1, "two");
assert_equals(response_cookies.vary2, undefined);
}, "Cookie-Indices should prevent a prefetch from being used if the cookie has changed.");
subsetTestByKey("unchangedWithRedirect", promise_test, async t => {
await test_driver.delete_all_cookies();
document.cookie = 'vary1=hello';
let agent = await spawnWindow(t);
let finalUrl = agent.getExecutorURL({ executor: "cookies.py", cookieindices: "1" });
let nextUrl = new URL("/common/redirect.py?location=" + encodeURIComponent(finalUrl), document.baseURI);
await agent.forceSinglePrefetch(nextUrl);
await agent.navigate(nextUrl, {expectedDestinationUrl: finalUrl});
assert_prefetched(await agent.getRequestHeaders());
let request_cookies = await agent.getRequestCookies();
let response_cookies = await agent.getResponseCookies();
assert_equals(request_cookies.vary1, "hello");
assert_equals(request_cookies.vary2, undefined);
assert_equals(response_cookies.vary1, "hello");
assert_equals(response_cookies.vary2, undefined);
}, "Cookie-Indices should not prevent a prefetch from succeeding with unchanged cookies, even with redirect");
subsetTestByKey("changedWithRedirect", promise_test, async t => {
await test_driver.delete_all_cookies();
document.cookie = 'vary1=hello';
let agent = await spawnWindow(t);
let finalUrl = agent.getExecutorURL({ executor: "cookies.py", cookieindices: "1" });
let nextUrl = new URL("/common/redirect.py?location=" + encodeURIComponent(finalUrl), document.baseURI);
await agent.forceSinglePrefetch(nextUrl);
document.cookie = 'vary1=two';
await agent.navigate(nextUrl, {expectedDestinationUrl: finalUrl});
assert_not_prefetched(await agent.getRequestHeaders());
let request_cookies = await agent.getRequestCookies();
let response_cookies = await agent.getResponseCookies();
assert_equals(request_cookies.vary1, "two");
assert_equals(request_cookies.vary2, undefined);
assert_equals(response_cookies.vary1, "two");
assert_equals(response_cookies.vary2, undefined);
}, "Cookie-Indices should prevent a prefetch from succeeding if the cookie changed, with a redirect");
subsetTestByKey("changedWithRedirect2", promise_test, async t => {
await test_driver.delete_all_cookies();
document.cookie = 'vary1=hello';
let agent = await spawnWindow(t);
// One subtlety here: the wptserve pipe parser doesn't allow commas inside
// the header value (since that delimits the pipe arguments).
// There is currently no way around this, so we simply don't use a value with a comma.
let finalUrl = agent.getExecutorURL({ executor: "cookies.py" });
let pipe = "header(Cache-Control,no-store)|header(Vary,Cookie)|header(Cookie-Indices,\"vary1\")";
let nextUrl = new URL(`/common/redirect.py?location=${encodeURIComponent(finalUrl)}&pipe=${encodeURIComponent(pipe)}`, document.baseURI);
await agent.forceSinglePrefetch(nextUrl);
document.cookie = 'vary1=two';
await agent.navigate(nextUrl, {expectedDestinationUrl: finalUrl});
assert_prefetched(await agent.getRequestHeaders());
let request_cookies = await agent.getRequestCookies();
let response_cookies = await agent.getResponseCookies();
assert_equals(request_cookies.vary1, "hello");
assert_equals(request_cookies.vary2, undefined);
assert_equals(response_cookies.vary1, "two");
assert_equals(response_cookies.vary2, undefined);
}, "If the redirect needs to be rerequested but goes to the same place and that one doesn't vary, we actually can use the prefetched final response.");
subsetTestByKey("changedWithRedirect3", promise_test, async t => {
await test_driver.delete_all_cookies();
document.cookie = 'vary1=hello';
let agent = await spawnWindow(t);
// One subtlety here: the wptserve pipe parser doesn't allow commas inside
// the header value (since that delimits the pipe arguments).
// There is currently no way around this, so we simply don't use a value with a comma.
let finalUrl = agent.getExecutorURL({ executor: "cookies.py" });
let pipe = "header(Cache-Control,no-store)|header(Vary,Cookie)|header(Cookie-Indices,\"vary1\")";
let nextUrl = new URL(`resources/random_redirect.py?location=${encodeURIComponent(finalUrl)}&pipe=${encodeURIComponent(pipe)}`, document.baseURI);
await agent.forceSinglePrefetch(nextUrl);
document.cookie = 'vary1=two';
await agent.navigate(nextUrl, {expectedDestinationUrl: null});
assert_not_prefetched(await agent.getRequestHeaders());
let request_cookies = await agent.getRequestCookies();
let response_cookies = await agent.getResponseCookies();
assert_equals(request_cookies.vary1, "two");
assert_equals(request_cookies.vary2, undefined);
assert_equals(response_cookies.vary1, "two");
assert_equals(response_cookies.vary2, undefined);
}, "If the redirect needs to be rerequested and goes elsewhere, we cannot can use the prefetched final response.");
</script>
|