diff --git a/CHANGES/5250.bugfix b/CHANGES/5250.bugfix new file mode 100644 index 00000000000..3e0bf0a30bb --- /dev/null +++ b/CHANGES/5250.bugfix @@ -0,0 +1 @@ +StaticResource prefixes no longer match URLs with a non-folder prefix. For example ``routes.static('/foo', '/foo')`` no longer matches the URL ``/foobar``. Previously, this would attempt to load the file ``/foo/ar``. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 1e7a6cf8df9..f1a3be11fc9 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -76,6 +76,7 @@ Claudiu Popa Colin Dunklau Cong Xu Damien Nadé +Dan King Dan Xu Daniel García Daniel Grossmann-Kavanagh diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index 03f4acadd35..a691661d7dd 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -495,6 +495,7 @@ def __init__(self, prefix: str, *, name: Optional[str] = None) -> None: assert prefix in ("", "/") or not prefix.endswith("/"), prefix super().__init__(name=name) self._prefix = _requote_path(prefix) + self._prefix2 = self._prefix + "/" @property def canonical(self) -> str: @@ -505,6 +506,7 @@ def add_prefix(self, prefix: str) -> None: assert not prefix.endswith("/") assert len(prefix) > 1 self._prefix = prefix + self._prefix + self._prefix2 = self._prefix + "/" def raw_match(self, prefix: str) -> bool: return False @@ -616,7 +618,7 @@ async def resolve(self, request: Request) -> _Resolve: path = request.rel_url.raw_path method = request.method allowed_methods = set(self._routes) - if not path.startswith(self._prefix): + if not path.startswith(self._prefix2) and path != self._prefix: return None, set() if method not in allowed_methods: @@ -732,7 +734,7 @@ def get_info(self) -> _InfoDict: async def resolve(self, request: Request) -> _Resolve: if ( - not request.url.raw_path.startswith(self._prefix + "/") + not request.url.raw_path.startswith(self._prefix2) and request.url.raw_path != self._prefix ): return None, set() diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py index ae19dec148d..ce2ec3cc77f 100644 --- a/tests/test_web_urldispatcher.py +++ b/tests/test_web_urldispatcher.py @@ -461,6 +461,21 @@ async def test_static_absolute_url(aiohttp_client: Any, tmp_path: Any) -> None: assert resp.status == 403 +async def test_for_issue_5250(aiohttp_client: Any, tmp_path: Any) -> None: + app = web.Application() + app.router.add_static("/foo", tmp_path) + + async def get_foobar(request): + return web.Response(body="success!") + + app.router.add_get("/foobar", get_foobar) + + client = await aiohttp_client(app) + async with await client.get("/foobar") as resp: + assert resp.status == 200 + assert (await resp.text()) == "success!" + + @pytest.mark.xfail( raises=AssertionError, reason="Regression in v3.7: https://github.com/aio-libs/aiohttp/issues/5621",