Commit 28a2e63a authored by Andrew Comminos's avatar Andrew Comminos Committed by Commit Bot

Add web platform test for verifying first byte timing of responseStart

Verfies that the UA measures the time before the end of header parsing
in responseStart by simulating a delay after writing the status line and
flushing to the client. Chrome fails this test for now, but Firefox
passes.

Bug: 568024
Change-Id: I61569c6a5b0d8ea2f3a06cb37a3d1ed36c06d40f
Reviewed-on: https://chromium-review.googlesource.com/c/1354645
Commit-Queue: Andrew Comminos <acomminos@fb.com>
Reviewed-by: default avatarNicolás Peña Moreno <npm@chromium.org>
Reviewed-by: default avatarYoav Weiss <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612412}
parent 448f5849
......@@ -4,7 +4,9 @@ import time
def main(request, response):
index = request.request_path.index("?")
args = request.request_path[index+1:].split("&")
headersSent = 0
headers = []
statusSent = False
headersSent = False
for arg in args:
if arg.startswith("ignored"):
continue
......@@ -13,14 +15,28 @@ def main(request, response):
elif arg.startswith("redirect:"):
return (302, "WEBPERF MARKETING"), [("Location", urllib.unquote(arg[9:]))], "TEST"
elif arg.startswith("mime:"):
response.headers.set("Content-Type", urllib.unquote(arg[5:]))
headers.append(("Content-Type", urllib.unquote(arg[5:])))
elif arg.startswith("send:"):
text = urllib.unquote(arg[5:])
if headersSent == 0:
response.write_status_headers()
headersSent = 1
if not statusSent:
# Default to a 200 status code.
response.writer.write_status(200)
statusSent = True
if not headersSent:
for key, value in headers:
response.writer.write_header(key, value)
response.writer.end_headers()
headersSent = True
response.writer.write_content(text)
elif arg.startswith("status:"):
code = int(urllib.unquote(arg[7:]))
response.writer.write_status(code)
statusSent = True
elif arg == "flush":
response.writer.flush()
# else:
# error " INVALID ARGUMENT %s" % arg
......@@ -2,6 +2,7 @@
<html>
<head>
<title>Resource-Timing Level 1</title>
<meta name="timeout" content="long">
<!-- To aid debugability, explicitly link the testharness's CSS to avoid demand
loading it while the test executes. -->
<script src="/resources/testharness.js"></script>
......
......@@ -224,6 +224,44 @@ window.onload =
});
});
// Ensure that responseStart only measures the time up to the first few
// bytes of the header response. This is tested by writing an HTTP 1.1
// status line, followed by a flush, then a pause before the end of the
// headers. The tests makes sure that responseStart is not delayed by
// this pause.
[
{ 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 + " " + serverStepDelay + "ms delay in headers does not affect responseStart'",
test: function (test) {
initiateFetch(
test,
template.initiator,
getSyntheticUrl("status:200"
+ "&flush"
+ "&" + serverStepDelay + "ms"
+ "&mime:" + template.mime
+ "&send:" + encodeURIComponent(template.response)),
function (initiator, entry) {
// Test that the delay between 'requestStart' and
// 'responseStart' does not include the added delay
// post-statusline.
assert_less_than(
entry.responseStart - entry.requestStart,
serverStepDelay,
"Delay after HTTP/1.1 status should not affect 'responseStart'.");
test.done();
});
}
});
});
// Function to run the next case in the queue.
var currentTestIndex = -1;
function runNextCase() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment