Skip to content

Commit

Permalink
Fix root_path usage
Browse files Browse the repository at this point in the history
The path should be excluding the root_path, not including it as
before. This matches how WSGI apps work and should match user
expectations.

Note the path is set to a space so as to trigger Quart's routing and a
normal 404 response - this allows users to configure it (rather than
the asgi module returning it's own 404).
  • Loading branch information
pgjones committed Sep 10, 2023
1 parent 4e7d98d commit 7be545c
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 9 deletions.
14 changes: 14 additions & 0 deletions src/quart/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ def _create_request_from_scope(self, send: ASGISendCallable) -> Request:

path = self.scope["path"]
path = path if path[0] == "/" else urlparse(path).path
root_path = self.scope.get("root_path", "")
if root_path != "":
try:
path = path.split(root_path, 1)[1]
path = " " if path == "" else path
except IndexError:
path = " " # Invalid in paths, hence will result in 404

return self.app.request_class(
self.scope["method"],
Expand Down Expand Up @@ -183,6 +190,13 @@ def _create_websocket_from_scope(self, send: ASGISendCallable) -> Websocket:

path = self.scope["path"]
path = path if path[0] == "/" else urlparse(path).path
root_path = self.scope.get("root_path", "")
if root_path != "":
try:
path = path.split(root_path, 1)[1]
path = " " if path == "" else path
except IndexError:
path = " " # Invalid in paths, hence will result in 404

return self.app.websocket_class(
path,
Expand Down
10 changes: 1 addition & 9 deletions src/quart/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,13 @@ def bind_to_request(
else:
subdomain = ".".join(filter(None, request_host_parts[:offset]))

if request.root_path:
try:
path = request.path.split(request.root_path, 1)[1]
except IndexError:
path = " " # Invalid in paths, hence will result in 404
else:
path = request.path

return super().bind(
host,
request.root_path,
subdomain,
request.scheme,
request.method,
path,
request.path,
request.query_string.decode(),
)

Expand Down
52 changes: 52 additions & 0 deletions tests/test_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,32 @@ def test_http_path_from_absolute_target() -> None:
assert request.path == "/path"


@pytest.mark.parametrize(
"path, expected",
[("/app", "/ "), ("/", "/ "), ("/app/", "/"), ("/app/2", "/2")],
)
def test_http_path_with_root_path(path: str, expected: str) -> None:
app = Quart(__name__)
scope: HTTPScope = {
"type": "http",
"asgi": {},
"http_version": "1.1",
"method": "GET",
"scheme": "https",
"path": path,
"raw_path": b"/",
"query_string": b"",
"root_path": "/app",
"headers": [(b"host", b"quart")],
"client": ("127.0.0.1", 80),
"server": None,
"extensions": {},
}
connection = ASGIHTTPConnection(app, scope)
request = connection._create_request_from_scope(lambda: None) # type: ignore
assert request.path == expected


def test_websocket_path_from_absolute_target() -> None:
app = Quart(__name__)
scope: WebsocketScope = {
Expand All @@ -196,6 +222,32 @@ def test_websocket_path_from_absolute_target() -> None:
assert websocket.path == "/path"


@pytest.mark.parametrize(
"path, expected",
[("/app", "/ "), ("/", "/ "), ("/app/", "/"), ("/app/2", "/2")],
)
def test_websocket_path_with_root_path(path: str, expected: str) -> None:
app = Quart(__name__)
scope: WebsocketScope = {
"type": "websocket",
"asgi": {},
"http_version": "1.1",
"scheme": "wss",
"path": path,
"raw_path": b"/",
"query_string": b"",
"root_path": "/app",
"headers": [(b"host", b"quart")],
"client": ("127.0.0.1", 80),
"server": None,
"subprotocols": [],
"extensions": {"websocket.http.response": {}},
}
connection = ASGIWebsocketConnection(app, scope)
websocket = connection._create_websocket_from_scope(lambda: None) # type: ignore
assert websocket.path == expected


@pytest.mark.parametrize(
"scope, headers, subprotocol, has_headers",
[
Expand Down

0 comments on commit 7be545c

Please sign in to comment.