Skip to content

Commit

Permalink
Backport 3.10: Add tests, accidentally dropped before (#8088) (#8141)
Browse files Browse the repository at this point in the history
Cherry picked from commit 0016004
  • Loading branch information
pajod authored Feb 8, 2024
1 parent 257a7c4 commit 0467c9b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGES/8088.contrib.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enabled HTTP parser tests originally intended for 3.9.2 release -- by :user:`pajod`.
55 changes: 46 additions & 9 deletions tests/test_http_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,20 @@ def test_parse_headers_longline(parser: Any) -> None:
parser.feed_data(text)


@pytest.fixture
def xfail_c_parser_status(request) -> None:
if isinstance(request.getfixturevalue("parser"), HttpRequestParserPy):
return
request.node.add_marker(
pytest.mark.xfail(
reason="Regression test for Py parser. May match C behaviour later.",
raises=http_exceptions.BadStatusLine,
)
)


@pytest.mark.usefixtures("xfail_c_parser_status")
def test_parse_unusual_request_line(parser) -> None:
if not isinstance(response, HttpResponseParserPy):
pytest.xfail("Regression test for Py parser. May match C behaviour later.")
text = b"#smol //a HTTP/1.3\r\n\r\n"
messages, upgrade, tail = parser.feed_data(text)
assert len(messages) == 1
Expand Down Expand Up @@ -612,24 +623,37 @@ def test_headers_content_length_err_2(parser) -> None:
}


@pytest.fixture
def xfail_c_parser_empty_header(request) -> None:
if not all(
(request.getfixturevalue(name) == b"") for name in ("pad1", "pad2", "hdr")
):
return
if isinstance(request.getfixturevalue("parser"), HttpRequestParserPy):
return
request.node.add_marker(
pytest.mark.xfail(
reason="Regression test for Py parser. May match C behaviour later.",
)
)


@pytest.mark.parametrize("hdr", [b"", b"foo"], ids=["name-empty", "with-name"])
@pytest.mark.parametrize("pad2", _pad.keys(), ids=["post-" + n for n in _pad.values()])
@pytest.mark.parametrize("pad1", _pad.keys(), ids=["pre-" + n for n in _pad.values()])
@pytest.mark.usefixtures("xfail_c_parser_empty_header")
def test_invalid_header_spacing(parser, pad1: bytes, pad2: bytes, hdr: bytes) -> None:
text = b"GET /test HTTP/1.1\r\n" b"%s%s%s: value\r\n\r\n" % (pad1, hdr, pad2)
expectation = pytest.raises(http_exceptions.BadHttpMessage)
if pad1 == pad2 == b"" and hdr != b"":
# one entry in param matrix is correct: non-empty name, not padded
expectation = nullcontext()
if pad1 == pad2 == hdr == b"":
if not isinstance(response, HttpResponseParserPy):
pytest.xfail("Regression test for Py parser. May match C behaviour later.")
with expectation:
parser.feed_data(text)


def test_empty_header_name(parser) -> None:
if not isinstance(response, HttpResponseParserPy):
if not isinstance(parser, HttpRequestParserPy):
pytest.xfail("Regression test for Py parser. May match C behaviour later.")
text = b"GET /test HTTP/1.1\r\n" b":test\r\n\r\n"
with pytest.raises(http_exceptions.BadHttpMessage):
Expand Down Expand Up @@ -807,9 +831,20 @@ def test_http_request_upgrade(parser: Any) -> None:
assert tail == b"some raw data"


@pytest.fixture
def xfail_c_parser_url(request) -> None:
if isinstance(request.getfixturevalue("parser"), HttpRequestParserPy):
return
request.node.add_marker(
pytest.mark.xfail(
reason="Regression test for Py parser. May match C behaviour later.",
raises=http_exceptions.InvalidURLError,
)
)


@pytest.mark.usefixtures("xfail_c_parser_url")
def test_http_request_parser_utf8_request_line(parser) -> None:
if not isinstance(response, HttpResponseParserPy):
pytest.xfail("Regression test for Py parser. May match C behaviour later.")
messages, upgrade, tail = parser.feed_data(
# note the truncated unicode sequence
b"GET /P\xc3\xbcnktchen\xa0\xef\xb7 HTTP/1.1\r\n" +
Expand All @@ -829,7 +864,9 @@ def test_http_request_parser_utf8_request_line(parser) -> None:
assert msg.compression is None
assert not msg.upgrade
assert not msg.chunked
assert msg.url.path == URL("/P%C3%BCnktchen\udca0\udcef\udcb7").path
# python HTTP parser depends on Cython and CPython URL to match
# .. but yarl.URL("/abs") is not equal to URL.build(path="/abs"), see #6409
assert msg.url == URL.build(path="/Pünktchen\udca0\udcef\udcb7", encoded=True)


def test_http_request_parser_utf8(parser) -> None:
Expand Down

0 comments on commit 0467c9b

Please sign in to comment.