From cdfed8b884ced3231b01c68a2f85bf2fbb94d30f Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:30:42 +0000 Subject: [PATCH] [PR #7776/0c938122 backport][3.9] Bugfix Edge Case Handling for ResponseParser for missing reason value (#7779) **This is a backport of PR #7776 as merged into master (0c938122b0d94701899d48e99cd3db32af306739).** For cases where response stream does not contain a reason, the current HttpResponseParser throws "Bad Status Line" Error. HTTP/1.1 protocol does not mandate reason to be present, hence this PR adds logic fix to handle this edge case. ## Are there changes in behavior for the user? No, this is not changing user behavior. Standard "HTTP/1.1 200 OK" and edge case of "HTTP/1.1 200 " should work after this PR gets merged. ## Related issue number No. This edge case is handled in 3.7 and earlier, but breaks from 3.8 forward versions. ## Checklist - [x] I think the code is well written - [x] Unit tests for the changes exist - [ ] Documentation reflects the changes - [ ] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [ ] Add a new news fragment into the `CHANGES` folder * name it `.` for example (588.bugfix) * if you don't have an `issue_id` change it to the pr id after creating the pr * ensure type is one of the following: * `.feature`: Signifying a new feature. * `.bugfix`: Signifying a bug fix. * `.doc`: Signifying a documentation improvement. * `.removal`: Signifying a deprecation or removal of public API. * `.misc`: A ticket has been closed, but it is not of interest to users. * Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files." Co-authored-by: jparag --- CHANGES/7776.bugfix | 1 + CONTRIBUTORS.txt | 1 + aiohttp/http_parser.py | 1 + tests/test_http_parser.py | 16 ++++++++++++++++ 4 files changed, 19 insertions(+) create mode 100644 CHANGES/7776.bugfix diff --git a/CHANGES/7776.bugfix b/CHANGES/7776.bugfix new file mode 100644 index 00000000000..97ba4c886e9 --- /dev/null +++ b/CHANGES/7776.bugfix @@ -0,0 +1 @@ +Edge Case Handling for ResponseParser for missing reason value diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 6dd291876be..557440d52aa 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -251,6 +251,7 @@ Olaf Conradi Pahaz Blinov Panagiotis Kolokotronis Pankaj Pandey +Parag Jain Pau Freixes Paul Colomiets Paulius Šileikis diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py index 00dc86ac9fd..f87161cb0a9 100644 --- a/aiohttp/http_parser.py +++ b/aiohttp/http_parser.py @@ -668,6 +668,7 @@ def parse_message(self, lines: List[bytes]) -> RawResponseMessage: try: status, reason = status.split(maxsplit=1) except ValueError: + status = status.strip() reason = "" if len(reason) > self.max_line_size: diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py index 42ec403b47e..452f8f50c6e 100644 --- a/tests/test_http_parser.py +++ b/tests/test_http_parser.py @@ -819,6 +819,22 @@ def test_http_response_parser_utf8(response) -> None: assert not tail +def test_http_response_parser_utf8_without_reason(response: Any) -> None: + text = "HTTP/1.1 200 \r\nx-test:тест\r\n\r\n".encode() + + messages, upgraded, tail = response.feed_data(text) + assert len(messages) == 1 + msg = messages[0][0] + + assert msg.version == (1, 1) + assert msg.code == 200 + assert msg.reason == "" + assert msg.headers == CIMultiDict([("X-TEST", "тест")]) + assert msg.raw_headers == ((b"x-test", "тест".encode()),) + assert not upgraded + assert not tail + + @pytest.mark.parametrize("size", [40962, 8191]) def test_http_response_parser_bad_status_line_too_long(response, size) -> None: reason = b"t" * (size - 2)