Skip to content

Commit

Permalink
fix: use re.match instead of re.search for mounted app path (#3501) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
0xE111 authored May 25, 2024
1 parent 17db66b commit 702dd84
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 2 deletions.
4 changes: 2 additions & 2 deletions litestar/_asgi/routing_trie/traversal.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ def parse_path_to_route(
asgi_app, handler = parse_node_handlers(node=root_node.children[path], method=method)
return asgi_app, handler, path, {}

if mount_paths_regex and (match := mount_paths_regex.search(path)):
mount_path = path[match.start() : match.end()]
if mount_paths_regex and (match := mount_paths_regex.match(path)):
mount_path = path[: match.end()]
mount_node = mount_routes[mount_path]
remaining_path = path[match.end() :]
# since we allow regular handlers under static paths, we must validate that the request does not match
Expand Down
93 changes: 93 additions & 0 deletions tests/unit/test_asgi/test_routing_trie/test_traversal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from typing import Any

from litestar import Router, asgi, get
from litestar.response.base import ASGIResponse
from litestar.status_codes import HTTP_404_NOT_FOUND
from litestar.testing import create_test_client


def test_parse_path_to_route_mounted_app_path_root() -> None:
# test that paths are correctly dispatched to handlers when mounting an app
# and other handlers to root path /

@asgi("/foobar", is_mount=True)
async def mounted_handler(scope: Any, receive: Any, send: Any) -> None:
response = ASGIResponse(body="mounted")
await response(scope, receive, send)

@get("/{number:int}/foobar/")
async def parametrized_handler() -> str:
return "parametrized"

@get("/static/foobar/")
async def static_handler() -> str:
return "static"

with create_test_client(
[
mounted_handler,
parametrized_handler,
static_handler,
]
) as client:
response = client.get("/foobar")
assert response.text == "mounted"

response = client.get("/foobar/123/")
assert response.text == "mounted"

response = client.get("/123/foobar/")
assert response.text == "parametrized"

response = client.get("/static/foobar/")
assert response.text == "static"

response = client.get("/unknown/foobar/")
assert response.status_code == HTTP_404_NOT_FOUND


def test_parse_path_to_route_mounted_app_path_router() -> None:
# test that paths are correctly dispatched to handlers when mounting an app
# and other handlers inside subrouter

@asgi("/foobar", is_mount=True)
async def mounted_handler(scope: Any, receive: Any, send: Any) -> None:
response = ASGIResponse(body="mounted")
await response(scope, receive, send)

@get("/{number:int}/foobar/")
async def parametrized_handler() -> str:
return "parametrized"

@get("/static/foobar/")
async def static_handler() -> str:
return "static"

sub_router = Router(
path="/sub",
route_handlers=[
mounted_handler,
parametrized_handler,
static_handler,
],
)
base_router = Router(path="/base", route_handlers=[sub_router])

with create_test_client([base_router]) as client:
response = client.get("/foobar")
assert response.status_code == HTTP_404_NOT_FOUND

response = client.get("/base/sub/foobar")
assert response.text == "mounted"

response = client.get("/base/sub/foobar/123/")
assert response.text == "mounted"

response = client.get("/base/sub/123/foobar/")
assert response.text == "parametrized"

response = client.get("/base/sub/static/foobar/")
assert response.text == "static"

response = client.get("/base/sub/unknown/foobar/")
assert response.status_code == HTTP_404_NOT_FOUND

0 comments on commit 702dd84

Please sign in to comment.