<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>This test validates the values in resource timing for cross-origin
redirects.</title>
<link rel="author" title="Intel" href="http://www.intel.com/" />
<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#sec-performanceresourcetiming"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/custom-cors-response.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/entry-invariants.js"></script>
<script src="resources/resource-loaders.js"></script>
<script src="resources/tao-response.js"></script>
</head>
<body>
<script>
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
const HTTP_SO_to_XO_redirect_url = url => {
// Make an initial request to a same-domain resource that will return a 302
// redirect to the given (possibly cross-origin) url.
return `/resource-timing/resources/redirect-cors.py?location=${url}`;
};
const HTTP_SO_resource = () => {
if (location.protocol != "http:") {
throw new Error("Can only make an HTTP SO request if this page was " +
"served over HTTP.");
}
return tao_response("*", ORIGIN);
};
const HTTP_XO_redirect = (url, tao) => {
const ret = new URL(
`${REMOTE_ORIGIN}/resource-timing/resources/redirect-cors.py`);
ret.searchParams.append("location", url);
ret.searchParams.append("allow_origin", "*");
ret.searchParams.append("timing_allow_origin", tao);
return ret.href;
};
attribute_test(
load.iframe, HTTP_SO_to_XO_redirect_url(custom_cors_response({},
REMOTE_ORIGIN)),
invariants.assert_http_to_cross_origin_redirected_resource,
"Verify that cross-origin resources' timings aren't exposed through HTTP " +
"redirects.");
attribute_test(
load.iframe, HTTP_SO_to_XO_redirect_url(remote_tao_response("no-match")),
invariants.assert_cross_origin_redirected_resource,
"Verify that a redirected cross-origin resources' timings aren't exposed " +
"when the TAO check fails.");
attribute_test(
load.iframe, HTTP_SO_to_XO_redirect_url(remote_tao_response("*")),
invariants.assert_http_to_tao_enabled_cross_origin_https_redirected_resource,
"Verify that cross-origin resources' timings are exposed when the TAO " +
"check succeeds. Also verify that secureConnectionStart is 0 since the " +
"original request was over HTTP.");
attribute_test(
load.iframe, HTTP_XO_redirect(HTTP_XO_redirect(HTTP_SO_resource(), "*"), "*"),
invariants.assert_http_to_tao_enabled_cross_origin_https_redirected_resource,
"Verify that a redirect chain through cross-origin resources have their " +
"timings exposed when all TAO checks succeed. Also verify that " +
"secureConnectionStart is 0 since the original request was over HTTP.");
const failure_permutations = [
["fail", "fail", "fail"],
["fail", "fail", "*" ],
["fail", "*", "fail"],
["fail", "*", "*" ],
["*", "fail", "fail"],
["*", "fail", "*" ],
["*", "*", "fail"],
];
const test_case = (so_tao, xo1_tao, xo2_tao) => {
return HTTP_XO_redirect(HTTP_XO_redirect(HTTP_SO_resource(
so_tao), xo2_tao), xo1_tao);
};
const test_label = perm => {
return perm.map(x => {
if (x == "*" ) return "PASS";
if (x == "fail" ) return "FAIL";
throw new Error(`unexpected element ${x}`);
}).join(" -> ");
};
for (const permutation of failure_permutations) {
attribute_test(
load.iframe, test_case.apply(permutation),
invariants.assert_tao_failure_resource,
`Verify that a redirect chain through cross-origin resources do not have ` +
`their timings exposed when any of the TAO checks fail. ` +
`(${test_label(permutation)})`);
}
</script>
</body>
</html>