From 2c4556efd14e260514d34e4d15ad7e0e78c2a61a Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Fri, 18 Nov 2022 13:39:23 +0000 Subject: [PATCH] [IMP] http_routing: support redirect of double slash in middle of path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move code to support only the redirect from url containing double '/' in the middle of the path. Keep same behavior than v15 and default Apache behavior. domain.com//shop/product/1 -> 404 domain.com/shop//product/1 -> 301 -> /shop/product/1 opw-3063387 closes odoo/odoo#106137 X-original-commit: fdd6bf9942e2807b6d1460dba1ca5f61404c7b06 Signed-off-by: Julien Castiaux Signed-off-by: Jérémy Kersten --- addons/http_routing/models/ir_http.py | 7 +++++++ addons/website/tests/test_http_endpoint.py | 7 +++++++ odoo/addons/test_http/tests/test_misc.py | 3 +-- odoo/http.py | 8 -------- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py index 444a8e5241f..8a8513392d8 100644 --- a/addons/http_routing/models/ir_http.py +++ b/addons/http_routing/models/ir_http.py @@ -421,6 +421,13 @@ class IrHttp(models.AbstractModel): and getattr(request, 'is_frontend_multilang', True) ) + # Some URLs in website are concatenated, first url ends with /, + # second url starts with /, resulting url contains two following + # slashes that must be merged. + if allow_redirect and '//' in path: + new_url = path.replace('//', '/') + werkzeug.exceptions.abort(request.redirect(new_url, code=301, local=True)) + # There is no user on the environment yet but the following code # requires one to set the lang on the request. Temporary grant # the public user. Don't try it at home! diff --git a/addons/website/tests/test_http_endpoint.py b/addons/website/tests/test_http_endpoint.py index c81d6cf8934..b275a014377 100644 --- a/addons/website/tests/test_http_endpoint.py +++ b/addons/website/tests/test_http_endpoint.py @@ -2,6 +2,8 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.tests import HttpCase +import werkzeug + class TestHttpEndPoint(HttpCase): @@ -30,3 +32,8 @@ class TestHttpEndPoint(HttpCase): r = self.url_open('/') r.raise_for_status() + + def test_redirect_double_slash(self): + res = self.url_open('/test_http//greeting', allow_redirects=False) + self.assertEqual(res.status_code, 301) + self.assertEqual(werkzeug.urls.url_parse(res.headers.get('Location', '')).path, '/test_http/greeting') diff --git a/odoo/addons/test_http/tests/test_misc.py b/odoo/addons/test_http/tests/test_misc.py index 5aebb826613..d316c049784 100644 --- a/odoo/addons/test_http/tests/test_misc.py +++ b/odoo/addons/test_http/tests/test_misc.py @@ -19,8 +19,7 @@ from .test_common import TestHttpBase class TestHttpMisc(TestHttpBase): def test_misc0_redirect(self): res = self.nodb_url_open('/test_http//greeting') - self.assertEqual(res.status_code, 301) - self.assertEqual(urlparse(res.headers.get('Location', '')).path, '/test_http/greeting') + self.assertEqual(res.status_code, 404) def test_misc1_reverse_proxy(self): # client <-> reverse-proxy <-> odoo diff --git a/odoo/http.py b/odoo/http.py index ea093266d46..1d1fa290b94 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -1968,14 +1968,6 @@ class Application: return ProxyFix(fake_app)(environ, fake_start_response) - # Some URLs in website are concatenated, first url ends with /, - # second url starts with /, resulting url contains two following - # slashes that must be merged. - if environ['REQUEST_METHOD'] == 'GET' and '//' in environ['PATH_INFO']: - response = werkzeug.utils.redirect( - environ['PATH_INFO'].replace('//', '/'), 301) - return response(environ, start_response) - httprequest = werkzeug.wrappers.Request(environ) httprequest.user_agent_class = UserAgent # use vendored userAgent since it will be removed in 2.1 httprequest.parameter_storage_class = (