<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<meta name="timeout" content="long">
<title>This test validates the response status of resources.</title>
<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="resources/entry-invariants.js"></script>
<script src="resources/resource-loaders.js"></script>
<script src="/common/get-host-info.sub.js"></script>
</head>
<body>
<script>
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
const SAME_ORIGIN = location.origin;
const status_codes = [
200, 203,
400, 401, 403, 404,
500, 501, 502, 503,
];
const load_image_object = async path => {
return load.object(path, "image/png");
}
const load_frame_object = async path => {
return load.object(path, "text/html");
}
const load_null_object = async path => {
return load.object(path, null);
}
// Response status for same origin resources is exposed.
for(const loader of [
load.font,
load.image,
load.script,
load.stylesheet,
load.xhr_sync,
load.xhr_async,
load.iframe,
load_image_object,
load_frame_object,
load_null_object
]) {
for(const status of status_codes) {
let path = (loader == load.font) ? '/fonts/pass.woff' :
'/resource-timing/resources/empty.js';
path += `?pipe=status(${status})`;
attribute_test(
loader, new URL(path, ORIGIN),
entry => {
assert_equals(entry.responseStatus, status,
`response status for ${entry.name} should be ${status}`);
}
);
}
}
// Response status is exposed for CORS requests for cross-origin resources.
for(const loader of [
load.image_with_attrs,
load.script_with_attrs,
load.stylesheet_with_attrs
]) {
for(const status of status_codes) {
const path = `/resource-timing/resources/empty.js?pipe=status(${status})`
+ `|header(access-control-allow-origin, ${ORIGIN})`;
loader_with_crossOrigin_attr = async url => {
return loader(url, {"crossOrigin": "anonymous"});
}
attribute_test(
loader_with_crossOrigin_attr, new URL(path, REMOTE_ORIGIN),
entry => {
assert_equals(entry.responseStatus, status,
`response status for ${entry.name} should be ${status}`);
}
);
}
}
// Response status is 0 when a no-cors request is made for cross origin
// fonts, images, scripts, stylesheets.
// Response status is 0 when request's mode is "navigate" and response's
// URL's origin is not same origin with request's origin. So response
// status is not exposed for cross origin iframes.
for(const loader of [
load.font,
load.image,
load.script,
load.stylesheet,
load.iframe,
load_image_object,
load_frame_object,
load_null_object
]) {
for(const tao of [false, true]) {
for(const status of status_codes) {
let path = (loader == load.font) ? '/fonts/pass.woff' :
'/resource-timing/resources/empty.js';
path += `?pipe=status(${status})`;
if (tao) {
path += `|header(timing-allow-origin, *)`;
}
attribute_test(
loader, new URL(path, REMOTE_ORIGIN),
entry => {
assert_equals(entry.responseStatus, 0,
`response status for ${entry.name} should be 0`);
}
);
}
}
}
// Response status for iframes is 0 when cross origin redirects are present
// Same-Origin => Cross-Origin => Same-Origin => Same-Origin redirect chain
for(const loader of [
load.iframe,
load_frame_object,
load_null_object
]) {
for(const status of status_codes) {
const destUrl =
`${SAME_ORIGIN}/resource-timing/resources/multi_redirect.py` +
`?page_origin=${SAME_ORIGIN}` +
`&cross_origin=${REMOTE_ORIGIN}` +
`&final_resource=` +
`/resource-timing/resources/empty.js?pipe=status(${status})`;
attribute_test(
loader, new URL(destUrl),
entry => {
assert_equals(entry.responseStatus, 0,
`response status should be 0 for iframes having cross origin`
+ ` redirects`);
}
);
}
}
// Response status for iframes is exposed for same origin redirects
for(const loader of [
load.iframe,
load_frame_object,
load_null_object
]) {
for(const status of status_codes) {
const destUrl = `${SAME_ORIGIN}/resource-timing/resources/redirect-cors.py`
+ `?location=${SAME_ORIGIN}/resource-timing/resources/empty.js`
+ `?pipe=status(${status})`;
attribute_test(
loader, new URL(destUrl),
entry => {
assert_equals(entry.responseStatus, status,
`response status should be exposed for iframes having only same`
+ ` origin redirects`);
}
);
}
};
</script>
</body>
</html>