Skip to content

Commit

Permalink
Handle URL quoting username and password components. (#1159)
Browse files Browse the repository at this point in the history
* Handle URL quoting username and password components

* Tweak userinfo quoting
  • Loading branch information
tomchristie authored Aug 11, 2020
1 parent 557ad70 commit 655773e
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
12 changes: 6 additions & 6 deletions httpx/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import warnings
from collections.abc import MutableMapping
from http.cookiejar import Cookie, CookieJar
from urllib.parse import parse_qsl, urlencode
from urllib.parse import parse_qsl, quote, unquote, urlencode

import chardet
import rfc3986
Expand Down Expand Up @@ -100,12 +100,12 @@ def userinfo(self) -> str:
@property
def username(self) -> str:
userinfo = self._uri_reference.userinfo or ""
return userinfo.partition(":")[0]
return unquote(userinfo.partition(":")[0])

@property
def password(self) -> str:
userinfo = self._uri_reference.userinfo or ""
return userinfo.partition(":")[2]
return unquote(userinfo.partition(":")[2])

@property
def host(self) -> str:
Expand Down Expand Up @@ -175,8 +175,8 @@ def copy_with(self, **kwargs: typing.Any) -> "URL":
):
host = kwargs.pop("host", self.host)
port = kwargs.pop("port", self.port)
username = kwargs.pop("username", self.username)
password = kwargs.pop("password", self.password)
username = quote(kwargs.pop("username", self.username) or "")
password = quote(kwargs.pop("password", self.password) or "")

authority = host
if port is not None:
Expand All @@ -193,7 +193,7 @@ def copy_with(self, **kwargs: typing.Any) -> "URL":

def join(self, url: URLTypes) -> "URL":
"""
Return an absolute URL, using given this URL as the base.
Return an absolute URL, using this URL as the base.
"""
if self.is_relative_url:
return URL(url)
Expand Down
12 changes: 12 additions & 0 deletions tests/models/test_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,18 @@ def test_url_copywith_for_authority():
assert str(new) == "https://username:[email protected]:444"


def test_url_copywith_for_userinfo():
copy_with_kwargs = {
"username": "[email protected]",
"password": "abc123@ %",
}
url = URL("https://example.org")
new = url.copy_with(**copy_with_kwargs)
assert str(new) == "https://tom%40example.org:abc123%40%20%[email protected]"
assert new.username == "[email protected]"
assert new.password == "abc123@ %"


def test_url_invalid():
with pytest.raises(InvalidURL):
URL("https://😇/")

0 comments on commit 655773e

Please sign in to comment.