Skip to content

Commit

Permalink
Fix how pure-Python HTTP parser interprets //
Browse files Browse the repository at this point in the history
  • Loading branch information
webknjaz committed Feb 25, 2021
1 parent e44f21d commit f2afa2f
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGES/5498.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Fix interpretation difference of the pure-Python and the Cython-based
HTTP parsers construct a ``yarl.URL`` object for HTTP request-target.

Before this fix, the Python parser would turn the URI's absolute-path
for ``//some-path`` into ``/`` while the Cython code preserved it as
``//some-path``. Now, both do the latter.
14 changes: 13 additions & 1 deletion aiohttp/http_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,9 @@ def parse_message(self, lines: List[bytes]) -> RawRequestMessage:
"Status line is too long", str(self.max_line_size), str(len(path))
)

path_part, _hash_separator, url_fragment = path.partition("#")
path_part, _question_mark_separator, qs_part = path_part.partition("?")

# method
if not METHRE.match(method):
raise BadStatusLine(method)
Expand Down Expand Up @@ -562,7 +565,16 @@ def parse_message(self, lines: List[bytes]) -> RawRequestMessage:
compression,
upgrade,
chunked,
URL(path),
# NOTE: `yarl.URL.build()` is used to mimic what the Cython-based
# NOTE: parser does, otherwise it results into the same
# NOTE: HTTP Request-Line input producing different
# NOTE: `yarl.URL()` objects
URL.build(
path=path_part,
query_string=qs_part,
fragment=url_fragment,
encoded=True,
),
)


Expand Down
1 change: 1 addition & 0 deletions tests/test_http_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ def test_http_request_parser_two_slashes(parser: Any) -> None:

assert msg.method == "GET"
assert msg.path == "//path"
assert msg.url.path == "//path"
assert msg.version == (1, 1)
assert not msg.should_close
assert msg.compression is None
Expand Down

0 comments on commit f2afa2f

Please sign in to comment.