From 658353de069cce3abb83ff56d950fca7b437f404 Mon Sep 17 00:00:00 2001 From: mimi89999 Date: Fri, 14 Nov 2025 12:27:42 +0100 Subject: [PATCH] Keep original host on IDNA decode errors --- httpx/_urls.py | 9 ++++++++- tests/models/test_url.py | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/httpx/_urls.py b/httpx/_urls.py index 301d0874d5..8c3a8aee87 100644 --- a/httpx/_urls.py +++ b/httpx/_urls.py @@ -170,6 +170,7 @@ def host(self) -> str: """ The URL host as a string. Always normalized to lowercase, with IDNA hosts decoded into unicode. + Invalid IDNA encodings are kept in their original xn-- form. Examples: @@ -182,13 +183,19 @@ def host(self) -> str: url = httpx.URL("http://xn--fiqs8s.icom.museum") assert url.host == "中国.icom.museum" + url = httpx.URL("https://xn--ls8h.la/") + assert url.host == "xn--ls8h.la" + url = httpx.URL("https://[::ffff:192.168.0.1]") assert url.host == "::ffff:192.168.0.1" """ host: str = self._uri_reference.host if host.startswith("xn--"): - host = idna.decode(host) + try: + host = idna.decode(host) + except idna.IDNAError: + pass return host diff --git a/tests/models/test_url.py b/tests/models/test_url.py index 03072e8f5c..1acb2afbe4 100644 --- a/tests/models/test_url.py +++ b/tests/models/test_url.py @@ -802,6 +802,12 @@ def test_url_invalid_idna_host(): assert str(exc.value) == "Invalid IDNA hostname: '☃.com'" +def test_url_invalid_idna_encoding_kept(): + url = httpx.URL("https://xn--ls8h.la/") + assert url.host == "xn--ls8h.la" + assert url.raw_host == b"xn--ls8h.la" + + # Tests for IPv4 hostname support.