Просмотр исходного кода

Warning instead of error when base prefix ends with '/'

Workaround for #1210
Unrud 4 лет назад
Родитель
Сommit
2cbbd4dc9c
2 измененных файлов с 23 добавлено и 8 удалено
  1. 7 4
      radicale/app/__init__.py
  2. 16 4
      radicale/tests/test_base.py

+ 7 - 4
radicale/app/__init__.py

@@ -191,13 +191,16 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
         base_prefix_src = ("HTTP_X_SCRIPT_NAME" if "HTTP_X_SCRIPT_NAME" in
         base_prefix_src = ("HTTP_X_SCRIPT_NAME" if "HTTP_X_SCRIPT_NAME" in
                            environ else "SCRIPT_NAME")
                            environ else "SCRIPT_NAME")
         base_prefix = environ.get(base_prefix_src, "")
         base_prefix = environ.get(base_prefix_src, "")
-        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 and base_prefix[0] != "/":
+            logger.error("Base prefix (from %s) must start with '/': %r",
+                         base_prefix_src, base_prefix)
             if base_prefix_src == "HTTP_X_SCRIPT_NAME":
             if base_prefix_src == "HTTP_X_SCRIPT_NAME":
                 return response(*httputils.BAD_REQUEST)
                 return response(*httputils.BAD_REQUEST)
             return response(*httputils.INTERNAL_SERVER_ERROR)
             return response(*httputils.INTERNAL_SERVER_ERROR)
+        if base_prefix.endswith("/"):
+            logger.warning("Base prefix (from %s) must not end with '/': %r",
+                           base_prefix_src, base_prefix)
+            base_prefix = base_prefix.rstrip("/")
         logger.debug("Base prefix (from %s): %r", base_prefix_src, base_prefix)
         logger.debug("Base prefix (from %s): %r", base_prefix_src, base_prefix)
         # Sanitize request URI (a WSGI server indicates with an empty path,
         # Sanitize request URI (a WSGI server indicates with an empty path,
         # that the URL targets the application root without a trailing slash)
         # that the URL targets the application root without a trailing slash)

+ 16 - 4
radicale/tests/test_base.py

@@ -67,8 +67,14 @@ permissions: RrWw""")
 
 
     def test_root_broken_script_name(self) -> None:
     def test_root_broken_script_name(self) -> None:
         """GET request at "/" with SCRIPT_NAME ending with "/"."""
         """GET request at "/" with SCRIPT_NAME ending with "/"."""
-        for script_name in ["/", "/radicale/", "radicale"]:
-            self.get("/", check=500, SCRIPT_NAME=script_name)
+        for script_name, prefix in [
+                ("/", ""), ("//", ""), ("/radicale/", "/radicale"),
+                ("radicale", None), ("radicale//", None)]:
+            _, headers, _ = self.request(
+                "GET", "/", check=500 if prefix is None else 302,
+                SCRIPT_NAME=script_name)
+            assert (prefix is None or
+                    headers.get("Location") == prefix + "/.web")
 
 
     def test_root_http_x_script_name(self) -> None:
     def test_root_http_x_script_name(self) -> None:
         """GET request at "/" with HTTP_X_SCRIPT_NAME."""
         """GET request at "/" with HTTP_X_SCRIPT_NAME."""
@@ -79,8 +85,14 @@ permissions: RrWw""")
 
 
     def test_root_broken_http_x_script_name(self) -> None:
     def test_root_broken_http_x_script_name(self) -> None:
         """GET request at "/" with HTTP_X_SCRIPT_NAME ending with "/"."""
         """GET request at "/" with HTTP_X_SCRIPT_NAME ending with "/"."""
-        for script_name in ["/", "/radicale/", "radicale"]:
-            self.get("/", check=400, HTTP_X_SCRIPT_NAME=script_name)
+        for script_name, prefix in [
+                ("/", ""), ("//", ""), ("/radicale/", "/radicale"),
+                ("radicale", None), ("radicale//", None)]:
+            _, headers, _ = self.request(
+                "GET", "/", check=400 if prefix is None else 302,
+                HTTP_X_SCRIPT_NAME=script_name)
+            assert (prefix is None or
+                    headers.get("Location") == prefix + "/.web")
 
 
     def test_sanitized_path(self) -> None:
     def test_sanitized_path(self) -> None:
         """GET request with unsanitized paths."""
         """GET request with unsanitized paths."""