Skip to content

Commit

Permalink
Fix how pure-Python HTTP parser interprets //
Browse files Browse the repository at this point in the history
(cherry picked from commit f2afa2f)
  • Loading branch information
webknjaz committed Feb 25, 2021
1 parent 5c1efbc commit b61f0fd
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 @@ -498,6 +498,9 @@ def parse_message(self, lines: List[bytes]) -> Any:
"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 @@ -538,7 +541,16 @@ def parse_message(self, lines: List[bytes]) -> Any:
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 @@ -528,6 +528,7 @@ def test_http_request_parser_two_slashes(parser) -> 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 b61f0fd

Please sign in to comment.