From ca6a880c45094619702dd62ade89aca0c647091a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 31 Jul 2024 16:51:45 -0500 Subject: [PATCH 1/4] Fix urldispatcher index when variable is preceeded by a fixed string after a slash. --- aiohttp/web_urldispatcher.py | 7 +++++-- tests/test_web_urldispatcher.py | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index 2ad065d2483..76a05c3334a 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -1108,8 +1108,11 @@ def register_resource(self, resource: AbstractResource) -> None: def _get_resource_index_key(self, resource: AbstractResource) -> str: """Return a key to index the resource in the resource index.""" - # strip at the first { to allow for variables - return resource.canonical.partition("{")[0].rstrip("/") or "/" + if "{" in (index_key := resource.canonical): + # strip at the first { to allow for variables, and than + # rpartition at / to allow for variable parts in the path + index_key = index_key.partition("{")[0].rpartition("/")[0] + return index_key.rstrip("/") or "/" def index_resource(self, resource: AbstractResource) -> None: """Add a resource to the resource index.""" diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py index fe941c8e5e1..f87a4521d7d 100644 --- a/tests/test_web_urldispatcher.py +++ b/tests/test_web_urldispatcher.py @@ -916,3 +916,27 @@ async def get(self) -> web.Response: r = await client.get("///a") assert r.status == 200 await r.release() + + +async def test_route_with_regex(aiohttp_client: AiohttpClient) -> None: + """Test a route with a regex.""" + app = web.Application() + + async def handler(request: web.Request) -> web.Response: + assert isinstance(request.match_info._route.resource, Resource) + return web.Response(text=request.match_info._route.resource.canonical) + + app.router.add_get("/core/locations{tail:.*}", handler) + client = await aiohttp_client(app) + + r = await client.get("/core/locations/tail/here") + assert r.status == 200 + assert await r.text() == "/core/locations{tail}" + + r = await client.get("/core/locations_tail_here") + assert r.status == 200 + assert await r.text() == "/core/locations{tail}" + + r = await client.get("/core/locations_tail;id=abcdef") + assert r.status == 200 + assert await r.text() == "/core/locations{tail}" From 1cb0ea56b92ec2532303b1451ead18f6a697d2e1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 31 Jul 2024 17:08:39 -0500 Subject: [PATCH 2/4] Update tests/test_web_urldispatcher.py --- tests/test_web_urldispatcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py index f87a4521d7d..2a73e750618 100644 --- a/tests/test_web_urldispatcher.py +++ b/tests/test_web_urldispatcher.py @@ -919,7 +919,7 @@ async def get(self) -> web.Response: async def test_route_with_regex(aiohttp_client: AiohttpClient) -> None: - """Test a route with a regex.""" + """Test a route with a regex preceded by a fixed string.""" app = web.Application() async def handler(request: web.Request) -> web.Response: From d38b50fa72a3173e57bfe9beed91a55543553b1c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 31 Jul 2024 17:14:30 -0500 Subject: [PATCH 3/4] improve comment --- aiohttp/web_urldispatcher.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index 76a05c3334a..8a1b93e57d6 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -1111,6 +1111,9 @@ def _get_resource_index_key(self, resource: AbstractResource) -> str: if "{" in (index_key := resource.canonical): # strip at the first { to allow for variables, and than # rpartition at / to allow for variable parts in the path + # For example if the canonical path is `/core/locations{tail:.*}` + # the index key will be `/core` since index is based on the + # url parts split by `/` index_key = index_key.partition("{")[0].rpartition("/")[0] return index_key.rstrip("/") or "/" From 068b976a6b3a06ecf6ebd7d83f4bf97f3fbe8936 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Aug 2024 10:02:03 -0500 Subject: [PATCH 4/4] changelog --- CHANGES/8566.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGES/8566.bugfix.rst diff --git a/CHANGES/8566.bugfix.rst b/CHANGES/8566.bugfix.rst new file mode 100644 index 00000000000..61365c0bb61 --- /dev/null +++ b/CHANGES/8566.bugfix.rst @@ -0,0 +1 @@ +Fixed url dispatcher index not matching when a variable is preceded by a fixed string after a slash -- by :user:`bdraco`.