From 390540eebdbf823eab1e99a7aeb0815c6a04282e Mon Sep 17 00:00:00 2001 From: Ricardo Madriz Date: Sun, 18 Feb 2024 14:25:53 -0600 Subject: [PATCH] Make FastAPI's root_path take precedence --- fastapi/applications.py | 18 +++++++++--------- tests/test_root_path_redirects.py | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/fastapi/applications.py b/fastapi/applications.py index b4cb13c59..2d9944c99 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -1052,19 +1052,19 @@ class FastAPI(Starlette): if self.root_path: root_path = scope.get("root_path", "") if root_path and self.root_path != root_path: - raise RuntimeError( + logger.warning( f"The ASGI server is using a different root path than the one " f"configured in FastAPI. The configured root path is: " f"{self.root_path}, the ASGI server root path is: {root_path}. " + f"The former will be used." ) - else: - scope["root_path"] = self.root_path - path = scope.get("path") - if path and not path.startswith(self.root_path): - scope["path"] = self.root_path + path - raw_path: bytes | None = scope.get("raw_path") - if raw_path and not raw_path.startswith(self.root_path.encode()): - scope["raw_path"] = self.root_path.encode() + raw_path + scope["root_path"] = self.root_path + path = scope.get("path") + if path and not path.startswith(self.root_path): + scope["path"] = self.root_path + path + raw_path: bytes | None = scope.get("raw_path") + if raw_path and not raw_path.startswith(self.root_path.encode()): + scope["raw_path"] = self.root_path.encode() + raw_path await super().__call__(scope, receive, send) def add_api_route( diff --git a/tests/test_root_path_redirects.py b/tests/test_root_path_redirects.py index 5a6d6cd2a..0542f39f0 100644 --- a/tests/test_root_path_redirects.py +++ b/tests/test_root_path_redirects.py @@ -34,3 +34,19 @@ def test_redirects_with_root_path(): response = client.get("/hello", follow_redirects=False) assert response.status_code == 307 assert response.headers["location"] == "http://testserver/api/hello/" + + +def test_invalid_combination_of_root_path(): + app = FastAPI(root_path="/api") + router = APIRouter() + + @router.get("/hello/") + def hello_page() -> str: + return "Hello, World!" + + app.include_router(router) + + client = TestClient(app, base_url="http://testserver", root_path="/notapi") + response = client.get("/hello", follow_redirects=False) + assert response.status_code == 307 + assert response.headers["location"] == "http://testserver/api/hello/"