Skip to content

Commit

Permalink
Support credentials in URL with empty user (#6494) (#6495)
Browse files Browse the repository at this point in the history
  • Loading branch information
shuckc committed Aug 28, 2024
1 parent 64f5e11 commit ce9c4eb
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGES/6494.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added support for URL credentials with empty (zero-length) username, e.g. ``https://:password@host`` -- by :user:`shuckc`
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Chih-Yuan Chen
Chris AtLee
Chris Laws
Chris Moore
Chris Shucksmith
Christopher Schmitt
Claudiu Popa
Colin Dunklau
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ def update_host(self, url: URL) -> None:

# basic auth info
username, password = url.user, url.password
if username:
self.auth = helpers.BasicAuth(username, password or "")
if username or password:
self.auth = helpers.BasicAuth(username or "", password or "")

def update_version(self, version: Union[http.HttpVersion, str]) -> None:
"""Convert request version to two elements tuple.
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ def from_url(cls, url: URL, *, encoding: str = "latin1") -> Optional["BasicAuth"
"""Create BasicAuth from url."""
if not isinstance(url, URL):
raise TypeError("url should be yarl.URL instance")
if url.user is None:
if url.user is None and url.password is None:
return None
return cls(url.user, url.password or "", encoding=encoding)
return cls(url.user or "", url.password or "", encoding=encoding)

def encode(self) -> str:
"""Encode credentials."""
Expand Down
7 changes: 7 additions & 0 deletions tests/test_client_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,13 @@ def test_basic_auth_from_url(make_request: _RequestMaker) -> None:
assert "python.org" == req.host


def test_basic_auth_no_user_from_url(make_request: _RequestMaker) -> None:
req = make_request("get", "http://:1234@python.org")
assert "AUTHORIZATION" in req.headers
assert "Basic OjEyMzQ=" == req.headers["AUTHORIZATION"]
assert "python.org" == req.host


def test_basic_auth_from_url_overridden(make_request: _RequestMaker) -> None:
req = make_request(
"get", "http://garbage@python.org", auth=aiohttp.BasicAuth("nkim", "1234")
Expand Down
8 changes: 8 additions & 0 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ def test_basic_auth_from_url() -> None:
assert auth.password == "pass"


def test_basic_auth_no_user_from_url() -> None:
url = URL("http://:pass@example.com")
auth = helpers.BasicAuth.from_url(url)
assert auth is not None
assert auth.login == ""
assert auth.password == "pass"


def test_basic_auth_from_not_url() -> None:
with pytest.raises(TypeError):
helpers.BasicAuth.from_url("http://user:pass@example.com") # type: ignore[arg-type]
Expand Down

0 comments on commit ce9c4eb

Please sign in to comment.