| <!DOCTYPE html> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/resources/get-host-info.js?pipe=sub"></script> |
| <script> |
| // Redirects for fetch() always apply CORS rules, whereas normal resources |
| // don't, so this test covers extra code paths beyond those covered by |
| // resource-timing-sizes-redirect.html. |
| |
| const baseUrl = new URL('/resources/square20.png', location.href).href; |
| |
| // Because apache decrements the Keep-Alive max value on each request, the |
| // transferSize will vary slightly between requests for the same resource. |
| const fuzzFactor = 3; // bytes |
| |
| const minHeaderSize = 100; |
| |
| const hostInfo = get_host_info(); |
| |
| var directUrl, sameOriginRedirect, crossOriginRedirect, mixedRedirect; |
| var complexRedirect; |
| var t = async_test('PerformanceResourceTiming sizes redirects img'); |
| |
| function checkResourceSizes() { |
| var entries = performance.getEntriesByType('resource'); |
| var lowerBound, upperBound, withRedirectLowerBound; |
| var seenCount = 0; |
| for (var entry of entries) { |
| switch (entry.name) { |
| case directUrl: |
| assert_greater_than(entry.transferSize, minHeaderSize, |
| 'direct transferSize'); |
| lowerBound = entry.transferSize - fuzzFactor; |
| upperBound = entry.transferSize + fuzzFactor; |
| withRedirectLowerBound = entry.transferSize + minHeaderSize; |
| ++seenCount; |
| break; |
| |
| case sameOriginRedirect: |
| assert_greater_than(entry.transferSize, withRedirectLowerBound, |
| 'same origin transferSize'); |
| ++seenCount; |
| break; |
| |
| case crossOriginRedirect: |
| case mixedRedirect: |
| case complexRedirect: |
| assert_between_exclusive(entry.transferSize, lowerBound, upperBound, |
| 'cross origin transferSize'); |
| ++seenCount; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| assert_equals(seenCount, 5, 'seenCount'); |
| t.done(); |
| } |
| |
| function redirectUrl(redirectSourceOrigin, targetUrl) { |
| return redirectSourceOrigin + |
| '/resources/redirect.php?url=' + encodeURIComponent(targetUrl); |
| } |
| |
| // Loads the images in |urlArray| in sequence, finally calling |callback|. |
| // |callback| will be wrapped in t.step_func() when called. |
| function loadImages(urlArray, callback) { |
| var url = urlArray.shift(); |
| var onload; |
| if (urlArray.length === 0) { |
| onload = t.step_func(callback); |
| } else { |
| onload = () => { loadImages(urlArray, callback); }; |
| } |
| var img = document.createElement('img'); |
| img.src = url; |
| img.onload = onload; |
| img.onerror = t.step_func(() => assert_unreached('Failed to load ' + url)); |
| img.style = 'display: none;'; |
| } |
| |
| function cacheBustedUrl() { |
| return baseUrl + '?unique=' + Math.random().toString().substring(2); |
| } |
| |
| function runTest() { |
| directUrl = cacheBustedUrl(); |
| sameOriginRedirect = redirectUrl(hostInfo.HTTP_ORIGIN, cacheBustedUrl()); |
| crossOriginRedirect = redirectUrl(hostInfo.HTTP_REMOTE_ORIGIN, |
| cacheBustedUrl()); |
| mixedRedirect = redirectUrl(hostInfo.HTTP_REMOTE_ORIGIN, |
| redirectUrl( |
| hostInfo.HTTP_ORIGIN, cacheBustedUrl())); |
| complexRedirect = redirectUrl(hostInfo.HTTP_ORIGIN, |
| redirectUrl(hostInfo.HTTP_REMOTE_ORIGIN, |
| redirectUrl(hostInfo.HTTP_ORIGIN, |
| cacheBustedUrl()))); |
| loadImages([directUrl, sameOriginRedirect, crossOriginRedirect, |
| mixedRedirect, complexRedirect], checkResourceSizes); |
| } |
| |
| t.step(runTest); |
| </script> |