diff options
Diffstat (limited to 'testing/web-platform/tests/fetch/h1-parsing')
10 files changed, 180 insertions, 0 deletions
diff --git a/testing/web-platform/tests/fetch/h1-parsing/README.md b/testing/web-platform/tests/fetch/h1-parsing/README.md new file mode 100644 index 0000000000..487a892dcf --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/README.md @@ -0,0 +1,5 @@ +This directory tries to document "rough consensus" on where HTTP/1 parsing should end up between browsers. + +Any tests that browsers currently fail should have associated bug reports. + +[whatwg/fetch issue #1156](https://github.com/whatwg/fetch/issues/1156) provides context for this effort and pointers to the various issues, pull requests, and bug reports that are associated with it. diff --git a/testing/web-platform/tests/fetch/h1-parsing/lone-cr.window.js b/testing/web-platform/tests/fetch/h1-parsing/lone-cr.window.js new file mode 100644 index 0000000000..6b46ed632f --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/lone-cr.window.js @@ -0,0 +1,23 @@ +// These tests expect that a network error is returned if there's a CR that is not immediately +// followed by LF before reaching message-body. +// +// No browser does this currently, but Firefox does treat it equivalently to a space which gives +// hope. + +[ + "HTTP/1.1\r200 OK\n\nBODY", + "HTTP/1.1 200\rOK\n\nBODY", + "HTTP/1.1 200 OK\n\rHeader: Value\n\nBODY", + "HTTP/1.1 200 OK\nHeader\r: Value\n\nBODY", + "HTTP/1.1 200 OK\nHeader:\r Value\n\nBODY", + "HTTP/1.1 200 OK\nHeader: Value\r\n\nBody", + "HTTP/1.1 200 OK\nHeader: Value\r\r\nBODY", + "HTTP/1.1 200 OK\nHeader: Value\rHeader2: Value2\n\nBODY", + "HTTP/1.1 200 OK\nHeader: Value\n\rBODY", + "HTTP/1.1 200 OK\nHeader: Value\n\r" +].forEach(input => { + promise_test(t => { + const message = encodeURIComponent(input); + return promise_rejects_js(t, TypeError, fetch(`resources/message.py?message=${message}`)); + }, `Parsing response with a lone CR before message-body (${input})`); +}); diff --git a/testing/web-platform/tests/fetch/h1-parsing/resources-with-0x00-in-header.window.js b/testing/web-platform/tests/fetch/h1-parsing/resources-with-0x00-in-header.window.js new file mode 100644 index 0000000000..f1afeeb740 --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/resources-with-0x00-in-header.window.js @@ -0,0 +1,31 @@ +async_test(t => { + const script = document.createElement("script"); + t.add_cleanup(() => script.remove()); + script.src = "resources/script-with-0x00-in-header.py"; + script.onerror = t.step_func_done(); + script.onload = t.unreached_func(); + document.body.append(script); +}, "Expect network error for script with 0x00 in a header"); + +async_test(t => { + const frame = document.createElement("iframe"); + t.add_cleanup(() => frame.remove()); + frame.src = "resources/document-with-0x00-in-header.py"; + // If network errors result in load events for frames per + // https://github.com/whatwg/html/issues/125 and https://github.com/whatwg/html/issues/1230 this + // should be changed to use the load event instead. + t.step_timeout(() => { + assert_equals(frame.contentDocument, null); + t.done(); + }, 1000); + document.body.append(frame); +}, "Expect network error for frame navigation to resource with 0x00 in a header"); + +async_test(t => { + const img = document.createElement("img"); + t.add_cleanup(() => img.remove()); + img.src = "resources/blue-with-0x00-in-a-header.asis"; + img.onerror = t.step_func_done(); + img.onload = t.unreached_func(); + document.body.append(img); +}, "Expect network error for image with 0x00 in a header"); diff --git a/testing/web-platform/tests/fetch/h1-parsing/resources/README.md b/testing/web-platform/tests/fetch/h1-parsing/resources/README.md new file mode 100644 index 0000000000..2175d27408 --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/resources/README.md @@ -0,0 +1,6 @@ +`blue-with-0x00-in-a-header.asis` is a copy from `../../images/blue.png` with the following prepended using Control Pictures to signify actual newlines and 0x00: +``` +HTTP/1.1 200 AN IMAGE␍␊ +Content-Type: image/png␍␊ +Custom: ␀␍␊␍␊ +``` diff --git a/testing/web-platform/tests/fetch/h1-parsing/resources/blue-with-0x00-in-a-header.asis b/testing/web-platform/tests/fetch/h1-parsing/resources/blue-with-0x00-in-a-header.asis Binary files differnew file mode 100644 index 0000000000..102340a631 --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/resources/blue-with-0x00-in-a-header.asis diff --git a/testing/web-platform/tests/fetch/h1-parsing/resources/document-with-0x00-in-header.py b/testing/web-platform/tests/fetch/h1-parsing/resources/document-with-0x00-in-header.py new file mode 100644 index 0000000000..223b3c4027 --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/resources/document-with-0x00-in-header.py @@ -0,0 +1,4 @@ +def main(request, response): + response.headers.set(b"Content-Type", b"text/html") + response.headers.set(b"Custom", b"\0") + return b"<!doctype html><b>This is a document.</b>" diff --git a/testing/web-platform/tests/fetch/h1-parsing/resources/message.py b/testing/web-platform/tests/fetch/h1-parsing/resources/message.py new file mode 100644 index 0000000000..640080c18b --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/resources/message.py @@ -0,0 +1,3 @@ +def main(request, response): + response.writer.write(request.GET.first(b"message")) + response.close_connection = True diff --git a/testing/web-platform/tests/fetch/h1-parsing/resources/script-with-0x00-in-header.py b/testing/web-platform/tests/fetch/h1-parsing/resources/script-with-0x00-in-header.py new file mode 100644 index 0000000000..39f58d8270 --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/resources/script-with-0x00-in-header.py @@ -0,0 +1,4 @@ +def main(request, response): + response.headers.set(b"Content-Type", b"text/javascript") + response.headers.set(b"Custom", b"\0") + return b"var thisIsJavaScript = 0" diff --git a/testing/web-platform/tests/fetch/h1-parsing/resources/status-code.py b/testing/web-platform/tests/fetch/h1-parsing/resources/status-code.py new file mode 100644 index 0000000000..5421893b26 --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/resources/status-code.py @@ -0,0 +1,6 @@ +def main(request, response): + output = b"HTTP/1.1 " + output += request.GET.first(b"input") + output += b"\nheader-parsing: is sad\n" + response.writer.write(output) + response.close_connection = True diff --git a/testing/web-platform/tests/fetch/h1-parsing/status-code.window.js b/testing/web-platform/tests/fetch/h1-parsing/status-code.window.js new file mode 100644 index 0000000000..5776cf4050 --- /dev/null +++ b/testing/web-platform/tests/fetch/h1-parsing/status-code.window.js @@ -0,0 +1,98 @@ +[ + { + input: "", + expected: null + }, + { + input: "BLAH", + expected: null + }, + { + input: "0 OK", + expected: { + status: 0, + statusText: "OK" + } + }, + { + input: "1 OK", + expected: { + status: 1, + statusText: "OK" + } + }, + { + input: "99 NOT OK", + expected: { + status: 99, + statusText: "NOT OK" + } + }, + { + input: "077 77", + expected: { + status: 77, + statusText: "77" + } + }, + { + input: "099 HELLO", + expected: { + status: 99, + statusText: "HELLO" + } + }, + { + input: "200", + expected: { + status: 200, + statusText: "" + } + }, + { + input: "999 DOES IT MATTER", + expected: { + status: 999, + statusText: "DOES IT MATTER" + } + }, + { + input: "1000 BOO", + expected: null + }, + { + input: "0200 BOO", + expected: null + }, + { + input: "65736 NOT 200 OR SOME SUCH", + expected: null + }, + { + input: "131072 HI", + expected: null + }, + { + input: "-200 TEST", + expected: null + }, + { + input: "0xA", + expected: null + }, + { + input: "C8", + expected: null + } +].forEach(({ description, input, expected }) => { + promise_test(async t => { + if (expected !== null) { + const response = await fetch("resources/status-code.py?input=" + input); + assert_equals(response.status, expected.status); + assert_equals(response.statusText, expected.statusText); + assert_equals(response.headers.get("header-parsing"), "is sad"); + } else { + await promise_rejects_js(t, TypeError, fetch("resources/status-code.py?input=" + input)); + } + }, `HTTP/1.1 ${input} ${expected === null ? "(network error)" : ""}`); +}); |