diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ceecee..6a6f4fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ## 3.1.2 -* Verify that base prefix doesn't end with '/' +* Verify that base prefix starts with '/' but doesn't end with '/' * Improve base prefix log message * Never send body for HEAD requests (again) diff --git a/radicale/app/__init__.py b/radicale/app/__init__.py index 685fb77..f1233e0 100644 --- a/radicale/app/__init__.py +++ b/radicale/app/__init__.py @@ -191,9 +191,10 @@ class Application(ApplicationPartDelete, ApplicationPartHead, base_prefix_src = ("HTTP_X_SCRIPT_NAME" if "HTTP_X_SCRIPT_NAME" in environ else "SCRIPT_NAME") base_prefix = environ.get(base_prefix_src, "") - if base_prefix.endswith("/"): - logger.error("Base prefix (from %s) must not end with '/': %r", - base_prefix_src, base_prefix) + if base_prefix and (base_prefix[0] != "/" or base_prefix[-1] == "/"): + logger.error("Base prefix (from %s) must %s with '/': %r", + base_prefix_src, "not end" if base_prefix[-1] == "/" + else "start", base_prefix) if base_prefix_src == "HTTP_X_SCRIPT_NAME": return response(*httputils.BAD_REQUEST) return response(*httputils.INTERNAL_SERVER_ERROR) diff --git a/radicale/tests/test_base.py b/radicale/tests/test_base.py index ea01cf6..03e2f63 100644 --- a/radicale/tests/test_base.py +++ b/radicale/tests/test_base.py @@ -67,7 +67,8 @@ permissions: RrWw""") def test_root_broken_script_name(self) -> None: """GET request at "/" with SCRIPT_NAME ending with "/".""" - self.get("/", check=500, SCRIPT_NAME="/radicale/") + for script_name in ["/", "/radicale/", "radicale"]: + self.get("/", check=500, SCRIPT_NAME=script_name) def test_root_http_x_script_name(self) -> None: """GET request at "/" with HTTP_X_SCRIPT_NAME.""" @@ -78,7 +79,8 @@ permissions: RrWw""") def test_root_broken_http_x_script_name(self) -> None: """GET request at "/" with HTTP_X_SCRIPT_NAME ending with "/".""" - self.get("/", check=400, HTTP_X_SCRIPT_NAME="/radicale/") + for script_name in ["/", "/radicale/", "radicale"]: + self.get("/", check=400, HTTP_X_SCRIPT_NAME=script_name) def test_sanitized_path(self) -> None: """GET request with unsanitized paths."""