From 1e60343490d41211d822efc7a7390b0475749410 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Mon, 2 Sep 2024 17:34:50 +0100 Subject: [PATCH 1/3] Fix changing scheme/host in Response.clone() for absolute URLs --- aiohttp/web_request.py | 12 ++++++++---- tests/test_web_request.py | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/aiohttp/web_request.py b/aiohttp/web_request.py index 84951e1f789..4f823199d71 100644 --- a/aiohttp/web_request.py +++ b/aiohttp/web_request.py @@ -177,6 +177,10 @@ def __init__( self._cache: Dict[str, Any] = {} url = message.url if url.is_absolute(): + if scheme is not None: + url = url.with_scheme(scheme) + if host is not None: + url = url.with_host(host) # absolute URL is given, # override auto-calculating url, host, and scheme # all other properties should be good @@ -186,6 +190,10 @@ def __init__( self._rel_url = url.relative() else: self._rel_url = message.url + if scheme is not None: + self._cache["scheme"] = scheme + if host is not None: + self._cache["host"] = host self._post: Optional[MultiDictProxy[Union[str, bytes, FileField]]] = None self._read_bytes: Optional[bytes] = None @@ -199,10 +207,6 @@ def __init__( self._transport_sslcontext = transport.get_extra_info("sslcontext") self._transport_peername = transport.get_extra_info("peername") - if scheme is not None: - self._cache["scheme"] = scheme - if host is not None: - self._cache["host"] = host if remote is not None: self._cache["remote"] = remote diff --git a/tests/test_web_request.py b/tests/test_web_request.py index 14a2e933003..016b72e5e74 100644 --- a/tests/test_web_request.py +++ b/tests/test_web_request.py @@ -169,6 +169,22 @@ def test_absolute_url() -> None: assert req.rel_url == URL.build(path="/path/to", query={"a": "1"}) +def test_clone_absolute_scheme() -> None: + req = make_mocked_request("GET", "https://example.com/path/to?a=1") + assert req.scheme == "https" + req2 = req.clone(scheme="http") + assert req2.scheme == "http" + assert req2.url.scheme == "http" + + +def test_clone_absolute_host() -> None: + req = make_mocked_request("GET", "https://example.com/path/to?a=1") + assert req.host == "example.com" + req2 = req.clone(host="foo.test") + assert req2.host == "foo.test" + assert req2.url.host == "foo.test" + + def test_content_length() -> None: req = make_mocked_request("Get", "/", CIMultiDict([("CONTENT-LENGTH", "123")])) @@ -707,18 +723,22 @@ def test_save_state_on_clone() -> None: def test_clone_scheme() -> None: req = make_mocked_request("GET", "/") + assert req.scheme == "http" req2 = req.clone(scheme="https") assert req2.scheme == "https" + assert req2.url.scheme == "https" def test_clone_host() -> None: req = make_mocked_request("GET", "/") + assert req.host != "example.com" req2 = req.clone(host="example.com") assert req2.host == "example.com" def test_clone_remote() -> None: req = make_mocked_request("GET", "/") + assert req.remote != "11.11.11.11" req2 = req.clone(remote="11.11.11.11") assert req2.remote == "11.11.11.11" From 73f4d213975174a0eb0bb7ae605137e12012171a Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Mon, 2 Sep 2024 17:37:00 +0100 Subject: [PATCH 2/3] Create 8990.bugfix.rst --- CHANGES/8990.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGES/8990.bugfix.rst diff --git a/CHANGES/8990.bugfix.rst b/CHANGES/8990.bugfix.rst new file mode 100644 index 00000000000..9a9783103fd --- /dev/null +++ b/CHANGES/8990.bugfix.rst @@ -0,0 +1 @@ +Fixed changing scheme/host in ``Response.clone()`` for absolute URLs -- by :user:`Dreamsorcerer`. From 196c5d296e9243dd0950ddaffbda735f04872089 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Mon, 2 Sep 2024 17:39:36 +0100 Subject: [PATCH 3/3] Update tests/test_web_request.py --- tests/test_web_request.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_web_request.py b/tests/test_web_request.py index 016b72e5e74..11aa21e84e3 100644 --- a/tests/test_web_request.py +++ b/tests/test_web_request.py @@ -734,6 +734,7 @@ def test_clone_host() -> None: assert req.host != "example.com" req2 = req.clone(host="example.com") assert req2.host == "example.com" + assert req2.url.host == "example.com" def test_clone_remote() -> None: