diff --git a/CHANGES/10142.bugfix.rst b/CHANGES/10142.bugfix.rst new file mode 100644 index 00000000000..821db59818d --- /dev/null +++ b/CHANGES/10142.bugfix.rst @@ -0,0 +1 @@ +Improved the parser error message shown when TLS handshake bytes are received on an HTTP port -- by :user:`puneetdixit200`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b65e45ddc4a..428ac1a1fee 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -316,6 +316,7 @@ Phebe Polk Philipp A. Pierre-Louis Peeters Pieter van Beek +Puneet Dixit Qiao Han Rafael Viotti Rahul Nahata diff --git a/aiohttp/_http_parser.pyx b/aiohttp/_http_parser.pyx index b1b642330bd..b323fe5a846 100644 --- a/aiohttp/_http_parser.pyx +++ b/aiohttp/_http_parser.pyx @@ -932,6 +932,8 @@ cdef parser_error_from_errno(cparser.llhttp_t* parser, data, pointer): cparser.HPE_INVALID_TRANSFER_ENCODING}: return BadHttpMessage(err_msg) elif errno == cparser.HPE_INVALID_METHOD: + if data.startswith(b"\x16\x03"): + return BadHttpMethod(error="Received HTTPS traffic on an HTTP port") return BadHttpMethod(error=err_msg) elif errno in {cparser.HPE_INVALID_STATUS, cparser.HPE_INVALID_VERSION, diff --git a/aiohttp/http_exceptions.py b/aiohttp/http_exceptions.py index 95d0d6373ae..8afb0f07a68 100644 --- a/aiohttp/http_exceptions.py +++ b/aiohttp/http_exceptions.py @@ -98,6 +98,8 @@ class BadHttpMethod(BadStatusLine): """Invalid HTTP method in status line.""" def __init__(self, line: str = "", error: str | None = None) -> None: + if error is None and line.startswith("\x16\x03"): + error = "Received HTTPS traffic on an HTTP port" super().__init__(line, error or f"Bad HTTP method in status line {line!r}") diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py index bb9ef3393bb..88269684973 100644 --- a/tests/test_http_parser.py +++ b/tests/test_http_parser.py @@ -1600,6 +1600,15 @@ def test_http_request_parser_bad_method( ) +def test_http_request_parser_tls_handshake_on_http_port( + parser: HttpRequestParser, +) -> None: + with pytest.raises(http_exceptions.BadHttpMethod) as ctx: + parser.feed_data(b"\x16\x03\x03\x01F\x01\r\n\r\n") + + assert "Received HTTPS traffic on an HTTP port" in str(ctx.value) + + def test_http_request_parser_bad_version(parser: HttpRequestParser) -> None: with pytest.raises(http_exceptions.BadHttpMessage): parser.feed_data(b"GET //get HT/11\r\nHost: a\r\n\r\n")