Skip to content

Commit 8c128d4

Browse files
[PR #7651/45f98b7d backport][3.8] Fix BadStatusLine message (#7666)
**This is a backport of PR #7651 as merged into master (45f98b7).**
1 parent 89b7df1 commit 8c128d4

File tree

4 files changed

+17
-22
lines changed

4 files changed

+17
-22
lines changed

CHANGES/7651.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed display of ``BadStatusLine`` messages from ``llhttp`` -- by :user:`Dreamsorcerer`

aiohttp/_http_parser.pyx

+11-19
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#
33
# Based on https://github.com/MagicStack/httptools
44
#
5-
from __future__ import absolute_import, print_function
65

76
from cpython cimport (
87
Py_buffer,
@@ -813,7 +812,9 @@ cdef parser_error_from_errno(cparser.llhttp_t* parser, data, pointer):
813812
cdef cparser.llhttp_errno_t errno = cparser.llhttp_get_errno(parser)
814813
cdef bytes desc = cparser.llhttp_get_error_reason(parser)
815814

816-
if errno in (cparser.HPE_CB_MESSAGE_BEGIN,
815+
err_msg = "{}:\n\n {!r}\n {}".format(desc.decode("latin-1"), data, pointer)
816+
817+
if errno in {cparser.HPE_CB_MESSAGE_BEGIN,
817818
cparser.HPE_CB_HEADERS_COMPLETE,
818819
cparser.HPE_CB_MESSAGE_COMPLETE,
819820
cparser.HPE_CB_CHUNK_HEADER,
@@ -823,22 +824,13 @@ cdef parser_error_from_errno(cparser.llhttp_t* parser, data, pointer):
823824
cparser.HPE_INVALID_CONTENT_LENGTH,
824825
cparser.HPE_INVALID_CHUNK_SIZE,
825826
cparser.HPE_INVALID_EOF_STATE,
826-
cparser.HPE_INVALID_TRANSFER_ENCODING):
827-
cls = BadHttpMessage
828-
829-
elif errno == cparser.HPE_INVALID_STATUS:
830-
cls = BadStatusLine
831-
832-
elif errno == cparser.HPE_INVALID_METHOD:
833-
cls = BadStatusLine
834-
835-
elif errno == cparser.HPE_INVALID_VERSION:
836-
cls = BadStatusLine
837-
827+
cparser.HPE_INVALID_TRANSFER_ENCODING}:
828+
return BadHttpMessage(err_msg)
829+
elif errno in {cparser.HPE_INVALID_STATUS,
830+
cparser.HPE_INVALID_METHOD,
831+
cparser.HPE_INVALID_VERSION}:
832+
return BadStatusLine(error=err_msg)
838833
elif errno == cparser.HPE_INVALID_URL:
839-
cls = InvalidURLError
840-
841-
else:
842-
cls = BadHttpMessage
834+
return InvalidURLError(err_msg)
843835

844-
return cls("{}:\n\n {!r}\n {}".format(desc.decode("latin-1"), data, pointer))
836+
return BadHttpMessage(err_msg)

aiohttp/http_exceptions.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ def __init__(self, hdr: Union[bytes, str]) -> None:
9595

9696

9797
class BadStatusLine(BadHttpMessage):
98-
def __init__(self, line: str = "") -> None:
98+
def __init__(self, line: str = "", error: Optional[str] = None) -> None:
9999
if not isinstance(line, str):
100100
line = repr(line)
101-
super().__init__(f"Bad status line {line!r}")
101+
super().__init__(error or f"Bad status line {line!r}")
102102
self.args = (line,)
103103
self.line = line
104104

tests/test_http_parser.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,10 @@ def test_http_request_parser(parser) -> None:
649649

650650
def test_http_request_bad_status_line(parser) -> None:
651651
text = b"getpath \r\n\r\n"
652-
with pytest.raises(http_exceptions.BadStatusLine):
652+
with pytest.raises(http_exceptions.BadStatusLine) as exc_info:
653653
parser.feed_data(text)
654+
# Check for accidentally escaped message.
655+
assert r"\n" not in exc_info.value.message
654656

655657

656658
def test_http_request_upgrade(parser) -> None:

0 commit comments

Comments
 (0)