Skip to content

Commit

Permalink
[PR #7651/45f98b7d backport][3.9] Fix BadStatusLine message (#7667)
Browse files Browse the repository at this point in the history
**This is a backport of PR #7651 as merged into master
(45f98b7).**
  • Loading branch information
patchback[bot] committed Oct 6, 2023
1 parent b282ff9 commit 799585d
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGES/7651.bugfix
@@ -0,0 +1 @@
Fixed display of ``BadStatusLine`` messages from ``llhttp`` -- by :user:`Dreamsorcerer`
30 changes: 11 additions & 19 deletions aiohttp/_http_parser.pyx
Expand Up @@ -2,7 +2,6 @@
#
# Based on https://github.com/MagicStack/httptools
#
from __future__ import absolute_import, print_function

from cpython cimport (
Py_buffer,
Expand Down Expand Up @@ -813,7 +812,9 @@ cdef parser_error_from_errno(cparser.llhttp_t* parser, data, pointer):
cdef cparser.llhttp_errno_t errno = cparser.llhttp_get_errno(parser)
cdef bytes desc = cparser.llhttp_get_error_reason(parser)

if errno in (cparser.HPE_CB_MESSAGE_BEGIN,
err_msg = "{}:\n\n {!r}\n {}".format(desc.decode("latin-1"), data, pointer)

if errno in {cparser.HPE_CB_MESSAGE_BEGIN,
cparser.HPE_CB_HEADERS_COMPLETE,
cparser.HPE_CB_MESSAGE_COMPLETE,
cparser.HPE_CB_CHUNK_HEADER,
Expand All @@ -823,22 +824,13 @@ cdef parser_error_from_errno(cparser.llhttp_t* parser, data, pointer):
cparser.HPE_INVALID_CONTENT_LENGTH,
cparser.HPE_INVALID_CHUNK_SIZE,
cparser.HPE_INVALID_EOF_STATE,
cparser.HPE_INVALID_TRANSFER_ENCODING):
cls = BadHttpMessage

elif errno == cparser.HPE_INVALID_STATUS:
cls = BadStatusLine

elif errno == cparser.HPE_INVALID_METHOD:
cls = BadStatusLine

elif errno == cparser.HPE_INVALID_VERSION:
cls = BadStatusLine

cparser.HPE_INVALID_TRANSFER_ENCODING}:
return BadHttpMessage(err_msg)
elif errno in {cparser.HPE_INVALID_STATUS,
cparser.HPE_INVALID_METHOD,
cparser.HPE_INVALID_VERSION}:
return BadStatusLine(error=err_msg)
elif errno == cparser.HPE_INVALID_URL:
cls = InvalidURLError

else:
cls = BadHttpMessage
return InvalidURLError(err_msg)

return cls("{}:\n\n {!r}\n {}".format(desc.decode("latin-1"), data, pointer))
return BadHttpMessage(err_msg)
4 changes: 2 additions & 2 deletions aiohttp/http_exceptions.py
Expand Up @@ -95,10 +95,10 @@ def __init__(self, hdr: Union[bytes, str]) -> None:


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

Expand Down
4 changes: 3 additions & 1 deletion tests/test_http_parser.py
Expand Up @@ -656,8 +656,10 @@ def test_http_request_parser(parser) -> None:

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


def test_http_request_upgrade(parser) -> None:
Expand Down

0 comments on commit 799585d

Please sign in to comment.