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