Skip to content

Commit

Permalink
Pre encoded path/params/fragments should be kept
Browse files Browse the repository at this point in the history
  • Loading branch information
elupus committed Dec 4, 2023
1 parent 9ef08c7 commit bb0dcfc
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
6 changes: 3 additions & 3 deletions httpx/_urlparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,16 +258,16 @@ def urlparse(url: str = "", **kwargs: typing.Optional[str]) -> ParseResult:
# specific component.

# For 'path' we need to drop ? and # from the GEN_DELIMS set.
parsed_path: str = quote(path, safe=SUB_DELIMS + ":/[]@")
parsed_path: str = quote(path, safe=SUB_DELIMS + ":/[]@%")
# For 'query' we need to drop '#' from the GEN_DELIMS set.
# We also exclude '/' because it is more robust to replace it with a percent
# encoding despite it not being a requirement of the spec.
parsed_query: typing.Optional[str] = (
None if query is None else quote(query, safe=SUB_DELIMS + ":?[]@")
None if query is None else quote(query, safe=SUB_DELIMS + ":?[]@%")
)
# For 'fragment' we can include all of the GEN_DELIMS set.
parsed_fragment: typing.Optional[str] = (
None if fragment is None else quote(fragment, safe=SUB_DELIMS + ":/?#[]@")
None if fragment is None else quote(fragment, safe=SUB_DELIMS + ":/?#[]@%")
)

# The parsed ASCII bytestrings are our canonical form.
Expand Down
28 changes: 23 additions & 5 deletions tests/test_urlparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,24 @@ def test_param_with_existing_escape_requires_encoding():
url = httpx.URL("http://webservice", params={"u": "http://example.com?q=foo%2Fa"})
assert str(url) == "http://webservice?u=http%3A%2F%2Fexample.com%3Fq%3Dfoo%252Fa"

def test_param_with_existing_escape():
url = httpx.URL("https://webservice/?u=/%3D%26&v=1%202")
assert str(url) == "https://webservice/?u=%2F%3D%26&v=1%202"
assert url.params["u"] == "/=&"
assert url.params["v"] == "1 2"

def test_param_nested_urls_in_query():
src = "special;string with:reserved?cha%20raca/ters&d"
data = str(httpx.URL("http://webservice", params={"u": src}))
data = str(httpx.URL("http://webservice", params={"u": data}))
data = str(httpx.URL("http://webservice", params={"u": data}))

url = httpx.URL(data)
url = httpx.URL(url.params["u"])
url = httpx.URL(url.params["u"])

assert url.params["u"] == src


# Tests for invalid URLs

Expand Down Expand Up @@ -260,9 +278,9 @@ def test_copy_with():

def test_path_percent_encoding():
# Test percent encoding for SUB_DELIMS ALPHA NUM and allowable GEN_DELIMS
url = httpx.URL("https://example.com/!$&'()*+,;= abc ABC 123 :/[]@")
assert url.raw_path == b"/!$&'()*+,;=%20abc%20ABC%20123%20:/[]@"
assert url.path == "/!$&'()*+,;= abc ABC 123 :/[]@"
url = httpx.URL("https://example.com/!$&'()*+,;= abc ABC 123 :/[]@%20")
assert url.raw_path == b"/!$&'()*+,;=%20abc%20ABC%20123%20:/[]@%20"
assert url.path == "/!$&'()*+,;= abc ABC 123 :/[]@ "
assert url.query == b""
assert url.fragment == ""

Expand All @@ -278,8 +296,8 @@ def test_query_percent_encoding():

def test_fragment_percent_encoding():
# Test percent encoding for SUB_DELIMS ALPHA NUM and allowable GEN_DELIMS
url = httpx.URL("https://example.com/#!$&'()*+,;= abc ABC 123 :/[]@" + "?#")
url = httpx.URL("https://example.com/#!$&'()*+,;= abc ABC 123 :/[]@%20" + "?#")
assert url.raw_path == b"/"
assert url.path == "/"
assert url.query == b""
assert url.fragment == "!$&'()*+,;= abc ABC 123 :/[]@?#"
assert url.fragment == "!$&'()*+,;= abc ABC 123 :/[]@ ?#"

0 comments on commit bb0dcfc

Please sign in to comment.