From bc2cb8e825537d95aeb12a39dea1ffcf841a3d25 Mon Sep 17 00:00:00 2001 From: Pablo Ventura Date: Thu, 16 Jul 2026 12:33:44 -0300 Subject: [PATCH] requests: Fix protocol-relative redirect Locations. Handle Location values that start with "//" before absolute-path rewrites so they keep the redirect host. Fixes #931. Signed-off-by: Pablo Ventura --- python-ecosys/requests/requests/__init__.py | 4 +++- python-ecosys/requests/test_requests.py | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/python-ecosys/requests/requests/__init__.py b/python-ecosys/requests/requests/__init__.py index 41f5cc47b..41cc9d648 100644 --- a/python-ecosys/requests/requests/__init__.py +++ b/python-ecosys/requests/requests/__init__.py @@ -207,7 +207,9 @@ def request( elif l.startswith(b"Location:") and not 200 <= status <= 299: if status in [301, 302, 303, 307, 308]: redirect = str(l[10:-2], "utf-8") - if redirect.startswith("/"): + if redirect.startswith("//"): + redirect = proto + redirect + elif redirect.startswith("/"): redirect = proto + "//" + host + ":" + str(port) + redirect else: raise NotImplementedError("Redirect %d not yet supported" % status) diff --git a/python-ecosys/requests/test_requests.py b/python-ecosys/requests/test_requests.py index 7b7a8f6c3..fe1e4b368 100644 --- a/python-ecosys/requests/test_requests.py +++ b/python-ecosys/requests/test_requests.py @@ -311,6 +311,24 @@ def test_redirect_relative(): socket.socket = lambda *a, **k: Socket() +def test_redirect_protocol_relative(): + server = iter( + [ + b"HTTP/1.1 301 OK\r\nLocation: //example.com/index\r\n\r\n", + SERVER_RESPONSE_200_OK, + ] + ) + socket.socket = lambda *a, **k: Socket(next(server)) + + response = requests.request("GET", "http://example.com") + + assert response.raw._write_buffer.getvalue() == ( + b"GET /index HTTP/1.1\r\nConnection: close\r\nHost: example.com\r\n\r\n" + ), format_message(response) + + socket.socket = lambda *a, **k: Socket() + + test_simple_get() test_get_auth() test_get_custom_header() @@ -331,3 +349,4 @@ def test_redirect_relative(): test_raw_readinto_content_length() test_redirect_absolute() test_redirect_relative() +test_redirect_protocol_relative()