diff options
| author | khadyottakale <khadyottakale@gmail.com> | 2026-02-22 14:28:45 +0530 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-03-06 17:32:32 -0500 |
| commit | b33c31d992591bc8e8d20ac156809e4ae5b45375 (patch) | |
| tree | 4a2804521266827bbc37ad11a46a95eb5d3fd35d | |
| parent | 864850b20f7ef89ed2f6bd8baf1a45acc9245a6c (diff) | |
Fixed #36940 -- Fixed script name edge case in ASGIRequest.path_info.
Paths that happened to begin with the script name were inappropriately
stripped, instead of checking that script name preceded a slash.
| -rw-r--r-- | django/core/handlers/asgi.py | 9 | ||||
| -rw-r--r-- | tests/handlers/tests.py | 20 |
2 files changed, 26 insertions, 3 deletions
diff --git a/django/core/handlers/asgi.py b/django/core/handlers/asgi.py index c8118e1691..9555860a7e 100644 --- a/django/core/handlers/asgi.py +++ b/django/core/handlers/asgi.py @@ -54,10 +54,13 @@ class ASGIRequest(HttpRequest): self.path = scope["path"] self.script_name = get_script_prefix(scope) if self.script_name: - # TODO: Better is-prefix checking, slash handling? - self.path_info = scope["path"].removeprefix(self.script_name) + script_name = self.script_name.rstrip("/") + if self.path.startswith(script_name + "/") or self.path == script_name: + self.path_info = self.path[len(script_name) :] + else: + self.path_info = self.path else: - self.path_info = scope["path"] + self.path_info = self.path # HTTP basics. self.method = self.scope["method"].upper() # Ensure query string is encoded correctly. diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py index 83dfd95713..625090a66d 100644 --- a/tests/handlers/tests.py +++ b/tests/handlers/tests.py @@ -346,6 +346,26 @@ class AsyncHandlerRequestTests(SimpleTestCase): self.assertEqual(request.script_name, "/FORCED_PREFIX") self.assertEqual(request.path_info, "/somepath/") + def test_root_path_prefix_boundary(self): + async_request_factory = AsyncRequestFactory() + # When path shares a textual prefix with root_path but not at a + # segment boundary, path_info should be the full path. + request = async_request_factory.request( + **{"path": "/rootprefix/somepath/", "root_path": "/root"} + ) + self.assertEqual(request.path, "/rootprefix/somepath/") + self.assertEqual(request.script_name, "/root") + self.assertEqual(request.path_info, "/rootprefix/somepath/") + + def test_root_path_trailing_slash(self): + async_request_factory = AsyncRequestFactory() + request = async_request_factory.request( + **{"path": "/root/somepath/", "root_path": "/root/"} + ) + self.assertEqual(request.path, "/root/somepath/") + self.assertEqual(request.script_name, "/root/") + self.assertEqual(request.path_info, "/somepath/") + async def test_sync_streaming(self): response = await self.async_client.get("/streaming/") self.assertEqual(response.status_code, 200) |
