Skip to content

Commit

Permalink
Fix url parsing of ipv6 urls on URL.replace (#1965)
Browse files Browse the repository at this point in the history
Co-authored-by: Florimond Manca <florimond.manca@protonmail.com>
  • Loading branch information
kousikmitra and florimondmanca authored Feb 6, 2023
1 parent 51c1de1 commit 94a22b8
Showing 2 changed files with 26 additions and 1 deletion.
9 changes: 8 additions & 1 deletion starlette/datastructures.py
Original file line number Diff line number Diff line change
@@ -113,11 +113,18 @@ def replace(self, **kwargs: typing.Any) -> "URL":
or "hostname" in kwargs
or "port" in kwargs
):
hostname = kwargs.pop("hostname", self.hostname)
hostname = kwargs.pop("hostname", None)
port = kwargs.pop("port", self.port)
username = kwargs.pop("username", self.username)
password = kwargs.pop("password", self.password)

if hostname is None:
netloc = self.netloc
_, _, hostname = netloc.rpartition("@")

if hostname[-1] != "]":
hostname = hostname.rsplit(":", 1)[0]

netloc = hostname
if port is not None:
netloc += f":{port}"
18 changes: 18 additions & 0 deletions tests/test_datastructures.py
Original file line number Diff line number Diff line change
@@ -40,6 +40,24 @@ def test_url():
assert new == "https://example.com:123/path/to/somewhere?abc=123#anchor"
assert new.hostname == "example.com"

ipv6_url = URL("https://[fe::2]:12345")
new = ipv6_url.replace(port=8080)
assert new == "https://[fe::2]:8080"

new = ipv6_url.replace(username="username", password="password")
assert new == "https://username:password@[fe::2]:12345"
assert new.netloc == "username:password@[fe::2]:12345"

ipv6_url = URL("https://[fe::2]")
new = ipv6_url.replace(port=123)
assert new == "https://[fe::2]:123"

url = URL("http://u:p@host/")
assert url.replace(hostname="bar") == URL("http://u:p@bar/")

url = URL("http://u:p@host:80")
assert url.replace(port=88) == URL("http://u:p@host:88")


def test_url_query_params():
u = URL("https://example.org/path/?page=3")

0 comments on commit 94a22b8

Please sign in to comment.