#32 Backport support for llhttp 9.2.1
Merged 2 months ago by music. Opened 2 months ago by music.
rpms/ music/python-aiohttp llhttp-9.2.1  into  rawhide

@@ -0,0 +1,202 @@ 

+ From ad4d2a2584e3d53ecbe7c691fff2f3e46fe8bca7 Mon Sep 17 00:00:00 2001

+ From: Sam Bull <git@sambull.org>

+ Date: Thu, 4 Apr 2024 18:25:36 +0100

+ Subject: [PATCH 1/4] Create 8292.feature.rst

+ 

+ ---

+  CHANGES/8292.feature.rst | 1 +

+  1 file changed, 1 insertion(+)

+  create mode 100644 CHANGES/8292.feature.rst

+ 

+ diff --git a/CHANGES/8292.feature.rst b/CHANGES/8292.feature.rst

+ new file mode 100644

+ index 00000000..782449e4

+ --- /dev/null

+ +++ b/CHANGES/8292.feature.rst

+ @@ -0,0 +1 @@

+ +Upgraded to LLHTTP 9.2.1 -- by :user:`Dreamsorcerer`.

+ -- 

+ 2.44.0

+ 

+ 

+ From 5febd9e8749c47ec6ad24c62d5623b690c192018 Mon Sep 17 00:00:00 2001

+ From: Sam Bull <git@sambull.org>

+ Date: Thu, 4 Apr 2024 23:08:43 +0100

+ Subject: [PATCH 2/4] Update test_http_parser.py

+ 

+ ---

+  tests/test_http_parser.py | 50 ++++++++++++++++++++++++++++++++-------

+  1 file changed, 42 insertions(+), 8 deletions(-)

+ 

+ diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py

+ index b9317305..bbe14b5b 100644

+ --- a/tests/test_http_parser.py

+ +++ b/tests/test_http_parser.py

+ @@ -108,8 +108,7 @@ def test_c_parser_loaded():

+  

+  def test_parse_headers(parser: Any) -> None:

+      text = b"""GET /test HTTP/1.1\r

+ -test: line\r

+ - continue\r

+ +test: a line\r

+  test2: data\r

+  \r

+  """

+ @@ -117,13 +116,24 @@ test2: data\r

+      assert len(messages) == 1

+      msg = messages[0][0]

+  

+ -    assert list(msg.headers.items()) == [("test", "line continue"), ("test2", "data")]

+ -    assert msg.raw_headers == ((b"test", b"line continue"), (b"test2", b"data"))

+ +    assert list(msg.headers.items()) == [("test", "a line"), ("test2", "data")]

+ +    assert msg.raw_headers == ((b"test", b"a line"), (b"test2", b"data"))

+      assert not msg.should_close

+      assert msg.compression is None

+      assert not msg.upgrade

+  

+  

+ +def test_reject_obsolete_line_folding(parser: Any) -> None:

+ +    text = b"""GET /test HTTP/1.1\r

+ +test: line\r

+ + Content-Length: 48\r

+ +test2: data\r

+ +\r

+ +"""

+ +    with pytest.raises(http_exceptions.BadHttpMessage):

+ +        parser.feed_data(text)

+ +

+ +

+  @pytest.mark.skipif(NO_EXTENSIONS, reason="Only tests C parser.")

+  def test_invalid_character(loop: Any, protocol: Any, request: Any) -> None:

+      parser = HttpRequestParserC(

+ @@ -341,8 +351,8 @@ def test_parse_delayed(parser) -> None:

+  

+  def test_headers_multi_feed(parser) -> None:

+      text1 = b"GET /test HTTP/1.1\r\n"

+ -    text2 = b"test: line\r"

+ -    text3 = b"\n continue\r\n\r\n"

+ +    text2 = b"test: line"

+ +    text3 = b" continue\r\n\r\n"

+  

+      messages, upgrade, tail = parser.feed_data(text1)

+      assert len(messages) == 0

+ @@ -708,7 +718,7 @@ def test_max_header_value_size_under_limit(parser) -> None:

+  @pytest.mark.parametrize("size", [40965, 8191])

+  def test_max_header_value_size_continuation(parser, size) -> None:

+      name = b"T" * (size - 5)

+ -    text = b"GET /test HTTP/1.1\r\n" b"data: test\r\n " + name + b"\r\n\r\n"

+ +    text = b"GET /test HTTP/1.1\r\n" b"data: test " + name + b"\r\n\r\n"

+  

+      match = f"400, message:\n  Got more than 8190 bytes \\({size}\\) when reading"

+      with pytest.raises(http_exceptions.LineTooLong, match=match):

+ @@ -717,7 +727,7 @@ def test_max_header_value_size_continuation(parser, size) -> None:

+  

+  def test_max_header_value_size_continuation_under_limit(parser) -> None:

+      value = b"A" * 8185

+ -    text = b"GET /test HTTP/1.1\r\n" b"data: test\r\n " + value + b"\r\n\r\n"

+ +    text = b"GET /test HTTP/1.1\r\n" b"data: test " + value + b"\r\n\r\n"

+  

+      messages, upgrade, tail = parser.feed_data(text)

+      msg = messages[0][0]

+ @@ -971,6 +981,30 @@ def test_http_response_parser_utf8_without_reason(response: Any) -> None:

+      assert not tail

+  

+  

+ +def test_http_response_parser_obs_line_folding(response: Any) -> None:

+ +    text = b"HTTP/1.1 200 Ok\r\ntest: line\r\n continue\r\n\r\n"

+ +

+ +    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 == "Ok"

+ +    assert msg.headers == CIMultiDict([("TEST", "line continue")])

+ +    assert msg.raw_headers == ((b"test", b"line continue"),)

+ +    assert not upgraded

+ +    assert not tail

+ +

+ +

+ +@pytest.mark.dev_mode

+ +def test_http_response_parser_strict_obs_line_folding(response: Any) -> None:

+ +    text = b"HTTP/1.1 200 Ok\r\ntest: line\r\n continue\r\n\r\n"

+ +

+ +    with pytest.raises(http_exceptions.BadHttpMessage):

+ +        response.feed_data(text)

+ +

+ +

+  @pytest.mark.parametrize("size", [40962, 8191])

+  def test_http_response_parser_bad_status_line_too_long(response, size) -> None:

+      reason = b"t" * (size - 2)

+ -- 

+ 2.44.0

+ 

+ 

+ From 5fcecdc3edd50a0dbe07a53efdb1dcc7e1545dc8 Mon Sep 17 00:00:00 2001

+ From: Sam Bull <git@sambull.org>

+ Date: Thu, 4 Apr 2024 23:16:25 +0100

+ Subject: [PATCH 3/4] Update http_parser.py

+ 

+ ---

+  aiohttp/http_parser.py | 6 ++++--

+  1 file changed, 4 insertions(+), 2 deletions(-)

+ 

+ diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py

+ index 1877f558..4e25c111 100644

+ --- a/aiohttp/http_parser.py

+ +++ b/aiohttp/http_parser.py

+ @@ -126,10 +126,12 @@ class HeadersParser:

+          max_line_size: int = 8190,

+          max_headers: int = 32768,

+          max_field_size: int = 8190,

+ +        lax: bool = False

+      ) -> None:

+          self.max_line_size = max_line_size

+          self.max_headers = max_headers

+          self.max_field_size = max_field_size

+ +        self._lax = lax

+  

+      def parse_headers(

+          self, lines: List[bytes]

+ @@ -176,7 +178,7 @@ class HeadersParser:

+              line = lines[lines_idx]

+  

+              # consume continuation lines

+ -            continuation = line and line[0] in (32, 9)  # (' ', '\t')

+ +            continuation = self._lax and line and line[0] in (32, 9)  # (' ', '\t')

+  

+              # Deprecated: https://www.rfc-editor.org/rfc/rfc9112.html#name-obsolete-line-folding

+              if continuation:

+ @@ -266,7 +268,7 @@ class HttpParser(abc.ABC, Generic[_MsgT]):

+          self._payload_parser: Optional[HttpPayloadParser] = None

+          self._auto_decompress = auto_decompress

+          self._limit = limit

+ -        self._headers_parser = HeadersParser(max_line_size, max_headers, max_field_size)

+ +        self._headers_parser = HeadersParser(max_line_size, max_headers, max_field_size, self.lax)

+  

+      @abc.abstractmethod

+      def parse_message(self, lines: List[bytes]) -> _MsgT:

+ -- 

+ 2.44.0

+ 

+ 

+ From deaf7786bb88a82b22dda9c4d8bca5fa51adbc39 Mon Sep 17 00:00:00 2001

+ From: Sam Bull <git@sambull.org>

+ Date: Thu, 4 Apr 2024 23:18:01 +0100

+ Subject: [PATCH 4/4] Update 8292.feature.rst

+ 

+ ---

+  CHANGES/8292.feature.rst | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/CHANGES/8292.feature.rst b/CHANGES/8292.feature.rst

+ index 782449e4..db83aa7e 100644

+ --- a/CHANGES/8292.feature.rst

+ +++ b/CHANGES/8292.feature.rst

+ @@ -1 +1 @@

+ -Upgraded to LLHTTP 9.2.1 -- by :user:`Dreamsorcerer`.

+ +Upgraded to LLHTTP 9.2.1, and started rejected obsolete line folding in Python parser to match -- by :user:`Dreamsorcerer`.

+ -- 

+ 2.44.0

+ 

file modified
+4
@@ -13,6 +13,10 @@ 

  

  # downstream only patch

  Patch:          0001-Unbundle-llhttp.patch

+ # Upgrade to llhttp 9.2.1

+ # https://github.com/aio-libs/aiohttp/pull/8292

+ # Rebased on v3.9.3

+ Patch:          aiohttp-3.9.3-llhttp-9.2.1.patch

  

  BuildRequires:  gcc

  

  • Started rejecting obsolete line folding in Python parser to match

To be merged and built in a side tag with https://src.fedoraproject.org/rpms/llhttp/pull-request/26.

This will be released upstream in 3.9.4, hopefully soon.

Currently testing in COPR.

Merge Failed.

This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset.

In https://copr.fedorainfracloud.org/coprs/music/aiohttp/packages/, everything rebuilt OK except the following, which already failed in Koschei for unrelated reasons:

Additionally:

  • python-sentry-sdk has not failed in Koschei yet, but its FTBFS is nevertheless unrelated, and I can reproduce it in a control build:
No match for argument: python3dist(pytest-asyncio) <= 0.21.1

Pull-Request has been merged by music

2 months ago

Build failed. More information on how to proceed and troubleshoot errors available at https://fedoraproject.org/wiki/Zuul-based-ci
https://fedora.softwarefactory-project.io/zuul/buildset/df06e39610e34519b3981da8347154fc