From 51c421c9a2ddfb6aa2c892fe930c24c6dfdc1ba4 Mon Sep 17 00:00:00 2001 From: disqualifier Date: Mon, 6 Jul 2026 16:47:35 -0400 Subject: [PATCH] fix: overwrite_domain accepts a bare IPv6 replacement instead of rejecting any ':' the guard rejected any replacement containing ':', which over-rejected a valid bare IPv6 literal host ('::1', '2001:db8::1') that yarl's URL.with_host() accepts and brackets. it now delegates the check to yarl (try with_host, catch ValueError), so a bare IPv6 is accepted (rewrites to http://[::1]/...) while a genuine host:port or pre-bracketed form still raises. Signed-off-by: disqualifier --- src/aioweb/session.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/aioweb/session.py b/src/aioweb/session.py index e0501f7..d1c725f 100644 --- a/src/aioweb/session.py +++ b/src/aioweb/session.py @@ -188,17 +188,19 @@ class ExtendedSession: def overwrite_domain(self, target, replacement): """register a host-substring rewrite (target -> replacement) - raises: - ValueError: if replacement contains a port (e.g. 'host:1234') - yarl's - with_host() rejects any ':' in a host at request time, deep inside - yarl with a stack trace far from this call; caught here instead + raises ValueError if the replacement is not a valid host for yarl's with_host() + (e.g. a 'host:port' string or a pre-bracketed '[::1]') - caught here rather than + deep in yarl at request time. a bare IPv6 literal ('::1', '2001:db8::1') is valid + and accepted: yarl brackets it itself. """ - if ":" in replacement: + try: + URL("http://placeholder").with_host(replacement) + except ValueError as exc: raise ValueError( - f"overwrite_domain replacement {replacement!r} contains a port - " - "yarl's URL.with_host() cannot take a host:port string; rewrite the " - "port separately or via a full URL override, not domain_overwrites" - ) + f"overwrite_domain replacement {replacement!r} is not a valid host: {exc}; " + "pass a bare hostname or IP (a bare IPv6 literal is fine), not a host:port or " + "bracketed form - rewrite a port via a full URL override, not domain_overwrites" + ) from exc self.domain_overwrites[target] = replacement def _apply_domain_overwrites(self, url: str) -> str: