Skip to content

Commit b33c31d

Browse files
KhadyotTakalejacobtylerwalls
authored andcommitted
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.
1 parent 864850b commit b33c31d

2 files changed

Lines changed: 26 additions & 3 deletions

File tree

django/core/handlers/asgi.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,13 @@ def __init__(self, scope, body_file):
5454
self.path = scope["path"]
5555
self.script_name = get_script_prefix(scope)
5656
if self.script_name:
57-
# TODO: Better is-prefix checking, slash handling?
58-
self.path_info = scope["path"].removeprefix(self.script_name)
57+
script_name = self.script_name.rstrip("/")
58+
if self.path.startswith(script_name + "/") or self.path == script_name:
59+
self.path_info = self.path[len(script_name) :]
60+
else:
61+
self.path_info = self.path
5962
else:
60-
self.path_info = scope["path"]
63+
self.path_info = self.path
6164
# HTTP basics.
6265
self.method = self.scope["method"].upper()
6366
# Ensure query string is encoded correctly.

tests/handlers/tests.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,26 @@ def test_force_script_name(self):
346346
self.assertEqual(request.script_name, "/FORCED_PREFIX")
347347
self.assertEqual(request.path_info, "/somepath/")
348348

349+
def test_root_path_prefix_boundary(self):
350+
async_request_factory = AsyncRequestFactory()
351+
# When path shares a textual prefix with root_path but not at a
352+
# segment boundary, path_info should be the full path.
353+
request = async_request_factory.request(
354+
**{"path": "/rootprefix/somepath/", "root_path": "/root"}
355+
)
356+
self.assertEqual(request.path, "/rootprefix/somepath/")
357+
self.assertEqual(request.script_name, "/root")
358+
self.assertEqual(request.path_info, "/rootprefix/somepath/")
359+
360+
def test_root_path_trailing_slash(self):
361+
async_request_factory = AsyncRequestFactory()
362+
request = async_request_factory.request(
363+
**{"path": "/root/somepath/", "root_path": "/root/"}
364+
)
365+
self.assertEqual(request.path, "/root/somepath/")
366+
self.assertEqual(request.script_name, "/root/")
367+
self.assertEqual(request.path_info, "/somepath/")
368+
349369
async def test_sync_streaming(self):
350370
response = await self.async_client.get("/streaming/")
351371
self.assertEqual(response.status_code, 200)

0 commit comments

Comments
 (0)