fix(wpt): serve XHR response header fixtures

Model xhr/resources/headers.py with its duplicate, empty, cookie and non-ASCII response headers. Include HEAD behavior and precise fixture discovery regression coverage.

(cherry picked from commit 8557f41b0c)
This commit is contained in:
ldm0
2026-09-29 12:25:01 +08:00
parent d0ae4d2d74
commit a7df4ffe27
3 changed files with 53 additions and 7 deletions
@@ -872,7 +872,7 @@ def _xhr_response_handler_reference_patterns(directory: str) -> tuple[re.Pattern
"inspect-headers.py", "echo-headers.py", "content.py",
"echo-content-type.py", "win-1252-xml.py", "win-1252-html.py",
"invalid-utf8-html.py", "shift-jis-html.py", "img-utf8-html.py",
"empty-div-utf8-html.py", "bad-chunk-encoding.py", "infinite-redirects.py",
"empty-div-utf8-html.py", "headers.py", "bad-chunk-encoding.py", "infinite-redirects.py",
"access-control-basic-put-allow.py",
"access-control-preflight-request-allow-headers-returns-star.py"):
resource = f"xhr/resources/{name}"
@@ -93,6 +93,7 @@ XHR_BODY_RESOURCE_PATHS = {
}
XHR_RESPONSE_RESOURCE_PATHS = {
*XHR_BODY_RESOURCE_PATHS,
"/xhr/resources/headers.py",
"/xhr/resources/inspect-headers.py",
"/xhr/resources/echo-headers.py",
"/xhr/resources/access-control-basic-put-allow.py",
@@ -3088,6 +3089,19 @@ requestExecutor("{executor_uuid}", {start_on_js});
headers, body = _xhr_inspect_headers_fixture_response(
parsed.query, list(self.headers.raw_items()),
)
elif path == "/xhr/resources/headers.py":
status, reason, content_type, body = 200, None, "text/plain", b"TEST"
headers = [
("X-Custom-Header", "test"),
("Set-Cookie", "test"),
("Set-Cookie2", "test"),
("X-Custom-Header-Empty", ""),
("X-Custom-Header-Comma", "1"),
("X-Custom-Header-Comma", "2"),
# send_header encodes strings as Latin-1; preserve the
# UTF-8 ellipsis bytes written by the upstream fixture.
("X-Custom-Header-Bytes", "\u00e2\u0080\u00a6"),
]
elif path == "/xhr/resources/echo-headers.py":
status, reason, content_type = 200, None, "text/plain"
headers = []
@@ -48,6 +48,33 @@ class XhrHeaderFixtureTests(unittest.TestCase):
finally:
connection.close()
def test_fixed_response_preserves_empty_duplicate_cookie_and_non_ascii_headers(self) -> None:
server = self.server()
for method in ("GET", "HEAD"):
with self.subTest(method=method):
connection = HTTPConnection("127.0.0.1", server.port, timeout=2)
try:
connection.request(method, "/xhr/resources/headers.py")
response = connection.getresponse()
self.assertEqual(response.status, 200)
headers = response.getheaders()
self.assertIn(("Content-Type", "text/plain"), headers)
self.assertIn(("X-Custom-Header", "test"), headers)
self.assertIn(("Set-Cookie", "test"), headers)
self.assertIn(("Set-Cookie2", "test"), headers)
self.assertIn(("X-Custom-Header-Empty", ""), headers)
self.assertEqual(
[value for name, value in headers if name == "X-Custom-Header-Comma"],
["1", "2"],
)
self.assertEqual(
response.getheader("X-Custom-Header-Bytes").encode("latin-1"),
b"\xe2\x80\xa6",
)
self.assertEqual(response.read(), b"TEST" if method == "GET" else b"")
finally:
connection.close()
def test_name_filter_preserves_case_duplicates_whitespace_and_bytes(self) -> None:
server = self.server()
status, headers, body = self.request(server.port, "filter_name=X-CaSe", [
@@ -212,12 +239,14 @@ class XhrHeaderFixtureTests(unittest.TestCase):
"xhr/wrong-root.window.js": "fetch('inspect-headers.py');",
"xhr/nested/wrong-relative.window.js": "fetch('resources/inspect-headers.py');",
}
sources.update({
path.replace(".window.js", "-echo.window.js"): source.replace(
"inspect-headers.py", "echo-headers.py"
)
for path, source in list(sources.items())
})
base_sources = sources.copy()
for suffix, resource in (("fixed", "headers.py"), ("echo", "echo-headers.py")):
sources.update({
path.replace(".window.js", f"-{suffix}.window.js"): source.replace(
"inspect-headers.py", resource
)
for path, source in base_sources.items()
})
for path, source in sources.items():
target = self.root / path
target.parent.mkdir(parents=True, exist_ok=True)
@@ -225,9 +254,12 @@ class XhrHeaderFixtureTests(unittest.TestCase):
selected = enumerate_cases(self.root, dir_prefixes=("xhr",))
self.assertEqual([case.case_path for case in selected], [
"xhr/absolute-echo.window.js?moli-wpt-script=window",
"xhr/absolute-fixed.window.js?moli-wpt-script=window",
"xhr/absolute.window.js?moli-wpt-script=window",
"xhr/nested/parent-echo.window.js?moli-wpt-script=window",
"xhr/nested/parent-fixed.window.js?moli-wpt-script=window",
"xhr/nested/parent.window.js?moli-wpt-script=window",
"xhr/relative-echo.window.js?moli-wpt-script=window",
"xhr/relative-fixed.window.js?moli-wpt-script=window",
"xhr/relative.window.js?moli-wpt-script=window",
])