From 19afa80a37d32e36599f45348a40cafe1f8b8b58 Mon Sep 17 00:00:00 2001 From: David Lord Date: Thu, 17 Mar 2022 07:44:30 -0700 Subject: [PATCH] disable autocorrect_location_header --- CHANGES.rst | 3 +++ src/werkzeug/wrappers/response.py | 10 +++++++--- tests/middleware/test_proxy_fix.py | 8 ++++++-- tests/test_test.py | 4 ++-- tests/test_utils.py | 19 ++++++++++++++----- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 093796ec49..b3a5ae2666 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -96,6 +96,9 @@ Unreleased to the routing system to use 308. :issue:`2351` - Fix ``ValueError: I/O operation on closed file.`` with the test client when following more than one redirect. :issue:`2353` +- ``Response.autocorrect_location_header`` is disabled by default. + The ``Location`` header URL will remain relative, and exclude the + scheme and domain, by default. :issue:`2352` Version 2.0.3 diff --git a/src/werkzeug/wrappers/response.py b/src/werkzeug/wrappers/response.py index dcb3d62b1b..d648062e7b 100644 --- a/src/werkzeug/wrappers/response.py +++ b/src/werkzeug/wrappers/response.py @@ -142,11 +142,15 @@ def application(environ, start_response): #: your code to the name change. implicit_sequence_conversion = True - #: Should this response object correct the location header to be RFC - #: conformant? This is true by default. + #: If a redirect ``Location`` header is a relative URL, make it an + #: absolute URL, including scheme and domain. + #: + #: .. versionchanged:: 2.1 + #: This is disabled by default, so responses will send relative + #: redirects. #: #: .. versionadded:: 0.8 - autocorrect_location_header = True + autocorrect_location_header = False #: Should this response object automatically set the content-length #: header if possible? This is true by default. diff --git a/tests/middleware/test_proxy_fix.py b/tests/middleware/test_proxy_fix.py index abbc05c33b..6dc318141e 100644 --- a/tests/middleware/test_proxy_fix.py +++ b/tests/middleware/test_proxy_fix.py @@ -7,6 +7,7 @@ from werkzeug.test import create_environ from werkzeug.utils import redirect from werkzeug.wrappers import Request +from werkzeug.wrappers import Response @pytest.mark.parametrize( @@ -158,7 +159,9 @@ ), ), ) -def test_proxy_fix(kwargs, base, url_root): +def test_proxy_fix(monkeypatch, kwargs, base, url_root): + monkeypatch.setattr(Response, "autocorrect_location_header", True) + @Request.application def app(request): # for header @@ -173,7 +176,8 @@ def app(request): # match doesn't include prefix assert urls.match("/parrot")[0] == "parrot" - # location header will start with url_root + # With autocorrect_location_header enabled, location header will + # start with url_root return redirect(parrot_url) url_map = Map([Rule("/parrot", endpoint="parrot")]) diff --git a/tests/test_test.py b/tests/test_test.py index 9da1cd5257..80eeea0e36 100644 --- a/tests/test_test.py +++ b/tests/test_test.py @@ -556,13 +556,13 @@ def app(request): assert response.history[-1].request.path == "/second" assert response.history[-1].status_code == 307 - assert response.history[-1].location == "http://localhost/third" + assert response.history[-1].location == "/third" assert len(response.history[-1].history) == 1 assert response.history[-1].history[-1] is response.history[-2] assert response.history[-2].request.path == "/first" assert response.history[-2].status_code == 307 - assert response.history[-2].location == "http://localhost/second" + assert response.history[-2].location == "/second" assert len(response.history[-2].history) == 0 diff --git a/tests/test_utils.py b/tests/test_utils.py index 67888b7f4e..4db3176e0e 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -3,6 +3,7 @@ import pytest +from werkzeug import Request from werkzeug import utils from werkzeug.datastructures import Headers from werkzeug.http import http_date @@ -237,7 +238,7 @@ def test_header_set_duplication_bug(): @pytest.mark.parametrize( - "path, base_url, expected_location", + ("path", "base_url", "absolute_location"), [ ("foo", "http://example.org/app", "http://example.org/app/foo/"), ("/foo", "http://example.org/app", "http://example.org/app/foo/"), @@ -250,14 +251,22 @@ def test_header_set_duplication_bug(): ("/", "http://example.org/app", "http://example.org/app/"), ], ) -def test_append_slash_redirect(path, base_url, expected_location): - def app(env, sr): - return utils.append_slash_redirect(env)(env, sr) +@pytest.mark.parametrize("autocorrect", [False, True]) +def test_append_slash_redirect(autocorrect, path, base_url, absolute_location): + @Request.application + def app(request): + rv = utils.append_slash_redirect(request.environ) + rv.autocorrect_location_header = autocorrect + return rv client = Client(app) response = client.get(path, base_url=base_url) assert response.status_code == 308 - assert response.headers["Location"] == expected_location + + if not autocorrect: + assert response.headers["Location"].count("/") == 1 + else: + assert response.headers["Location"] == absolute_location def test_cached_property_doc():