From 25efc7d53b2010074794bee78f10750922efc892 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Fri, 27 Jan 2023 14:06:38 +0000 Subject: [PATCH] Bug 1810501 [wpt PR 37984] - Resource Timing: Expose firstInterimResponseStart, a=testonly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatic update from web-platform-tests Resource Timing: Expose firstInterimResponseStart This adds an entry to PerformanceResourceTiming: - firstInterimResponseStart: the time of the first early-hints header It also changes the meaning of responseStart to be the first non-informational header (non-103). Implemented for Quic, Spdy and HTTP. All behind a feature runtime flag (ResourceTimingInterimResponseTimes) Spec issue: https://github.com/w3c/resource-timing/issues/345 Bug: 1402089 Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4165825 Reviewed-by: Bence Béky Commit-Queue: Noam Rosenthal Cr-Commit-Position: refs/heads/main@{#1094571} -- wpt-commits: e75f154bb894b0e2bf78cf1ac04e1cbecedebdc6 wpt-pr: 37984 --- .../early-hints-response-time.h2.html | 27 ++++++++ .../resources/early-hints-delay.h2.py | 20 ++++++ .../interim-response-times.h2.html | 64 +++++++++++++++++++ .../interim-response-times.html | 62 ++++++++++++++++++ .../resource-timing/resource-timing-level1.js | 41 ------------ .../resources/header-delay.h2.py | 23 +++++++ .../resource-timing/resources/header-delay.py | 27 ++++++++ 7 files changed, 223 insertions(+), 41 deletions(-) create mode 100644 testing/web-platform/tests/loading/early-hints/early-hints-response-time.h2.html create mode 100644 testing/web-platform/tests/loading/early-hints/resources/early-hints-delay.h2.py create mode 100644 testing/web-platform/tests/resource-timing/interim-response-times.h2.html create mode 100644 testing/web-platform/tests/resource-timing/interim-response-times.html create mode 100644 testing/web-platform/tests/resource-timing/resources/header-delay.h2.py create mode 100644 testing/web-platform/tests/resource-timing/resources/header-delay.py diff --git a/testing/web-platform/tests/loading/early-hints/early-hints-response-time.h2.html b/testing/web-platform/tests/loading/early-hints/early-hints-response-time.h2.html new file mode 100644 index 0000000000000..ac70b3d332e65 --- /dev/null +++ b/testing/web-platform/tests/loading/early-hints/early-hints-response-time.h2.html @@ -0,0 +1,27 @@ + + + + + + + + + + + diff --git a/testing/web-platform/tests/loading/early-hints/resources/early-hints-delay.h2.py b/testing/web-platform/tests/loading/early-hints/resources/early-hints-delay.h2.py new file mode 100644 index 0000000000000..ba8796bc11a13 --- /dev/null +++ b/testing/web-platform/tests/loading/early-hints/resources/early-hints-delay.h2.py @@ -0,0 +1,20 @@ +import time + +def handle_headers(frame, request, response): + early_hints = [ + (b":status", b"103"), + (b"link", b"; rel=preload; as=script"), + ] + + time.sleep(int(request.GET.first(b"delay1")) / 1000) + response.writer.write_raw_header_frame(headers=early_hints, + end_headers=True) + + time.sleep(int(request.GET.first(b"delay2")) / 1000) + response.status = 200 + response.headers[b"content-type"] = "text/html" + response.write_status_headers() + + +def main(request, response): + response.writer.write_data(item="Hello", last=True) diff --git a/testing/web-platform/tests/resource-timing/interim-response-times.h2.html b/testing/web-platform/tests/resource-timing/interim-response-times.h2.html new file mode 100644 index 0000000000000..850ee7cb5f539 --- /dev/null +++ b/testing/web-platform/tests/resource-timing/interim-response-times.h2.html @@ -0,0 +1,64 @@ + + + + +Resource Timing: PerformanceResourceTiming interim resource times + + + + + + + + diff --git a/testing/web-platform/tests/resource-timing/interim-response-times.html b/testing/web-platform/tests/resource-timing/interim-response-times.html new file mode 100644 index 0000000000000..b922590d5d32c --- /dev/null +++ b/testing/web-platform/tests/resource-timing/interim-response-times.html @@ -0,0 +1,62 @@ + + + + +Resource Timing: PerformanceResourceTiming interim resource times + + + + + + + + diff --git a/testing/web-platform/tests/resource-timing/resource-timing-level1.js b/testing/web-platform/tests/resource-timing/resource-timing-level1.js index 95b5cdfb1ed0c..6167777fe68fa 100644 --- a/testing/web-platform/tests/resource-timing/resource-timing-level1.js +++ b/testing/web-platform/tests/resource-timing/resource-timing-level1.js @@ -235,47 +235,6 @@ window.onload = }); }); - // Test that responseStart uses the timing of 1XX responses by - // synthesizing a delay between a 100 and 200 status, and verifying that - // this delay is included before responseEnd. If the delay is not - // included, this implies that the 200 status line was (incorrectly) used - // for responseStart timing, despite the 100 response arriving earlier. - // - // Source: "In the case where more than one response is available for a - // request, due to an Informational 1xx response, the reported - // responseStart value is that of the first response to the last - // request." - [ - { initiator: "iframe", response: "(done)", mime: mimeHtml }, - { initiator: "xmlhttprequest", response: "(done)", mime: mimeText }, - { initiator: "script", response: '"";', mime: mimeScript }, - { initiator: "link", response: ".unused{}", mime: mimeCss }, - ] - .forEach(function (template) { - testCases.push({ - description: "'" + template.initiator + " responseStart uses 1XX (first) response timings'", - test: function (test) { - initiateFetch( - test, - template.initiator, - getSyntheticUrl("status:100" - + "&flush" - + "&" + serverStepDelay + "ms" - + "&status:200" - + "&mime:" + template.mime - + "&send:" + encodeURIComponent(template.response)), - function (initiator, entry) { - assert_greater_than_equal( - entry.responseEnd, - entry.responseStart + serverStepDelay, - "HTTP/1.1 1XX (first) response should determine 'responseStart' timing."); - - test.done(); - }); - } - }); - }); - // Function to run the next case in the queue. var currentTestIndex = -1; function runNextCase() { diff --git a/testing/web-platform/tests/resource-timing/resources/header-delay.h2.py b/testing/web-platform/tests/resource-timing/resources/header-delay.h2.py new file mode 100644 index 0000000000000..be29e52b0e836 --- /dev/null +++ b/testing/web-platform/tests/resource-timing/resources/header-delay.h2.py @@ -0,0 +1,23 @@ +from time import sleep + +def handle_headers(frame, request, response): + delay = int(request.GET.first(b"delay")) / 1000 + sleep(delay) + response.writer.write_raw_header_frame(headers=[(b":status", b"100")], end_headers=True) + sleep(delay) + + if b"with103" in request.GET: + response.writer.write_raw_header_frame(headers=[(b":status", b"103")], end_headers=True) + sleep(delay) + + response.status = 200 + + if b"tao" in request.GET: + response.headers[b"timing-allow-origin"] = "*" + + response.headers[b"content-type"] = "text/plain" + response.headers[b"access-control-allow-origin"] = "*" + response.write_status_headers() + +def main(request, response): + response.writer.write_data(item="Hello World", last=True) diff --git a/testing/web-platform/tests/resource-timing/resources/header-delay.py b/testing/web-platform/tests/resource-timing/resources/header-delay.py new file mode 100644 index 0000000000000..a47a63e9814a7 --- /dev/null +++ b/testing/web-platform/tests/resource-timing/resources/header-delay.py @@ -0,0 +1,27 @@ +from time import sleep + +def main(request, response): + delay = int(request.GET.first(b"delay")) / 1000 + + # TODO: make this exported from ResponseWriter + handler = response.writer._handler + sleep(delay) + handler.send_response(100) + handler.end_headers() + sleep(delay) + + if b"with103" in request.GET: + handler.send_response(103) + handler.send_header("Link", ";rel=preload;as=script") + handler.end_headers() + sleep(delay) + + handler.send_response(200) + + if b"tao" in request.GET: + handler.send_header("timing-allow-origin", "*") + + handler.send_header("content-type", "text/plain") + handler.send_header("access-control-allow-origin", "*") + handler.end_headers() + handler.wfile.write(bytes("Hello World", "utf8"))