Skip to content

Commit a8f01d7

Browse files
patchback[bot]dankingasvetlov
authored
[PR #5534/9c7f3d37 backport][3.8] StaticResource only matches folder-like URL prefix (#6179)
* StaticResource only matches folder-like URL prefix (#5534) Co-authored-by: Andrew Svetlov <andrew.svetlov@gmail.com> (cherry picked from commit 9c7f3d3) * fix Co-authored-by: Dan King <daniel.zidan.king@gmail.com> Co-authored-by: Andrew Svetlov <andrew.svetlov@gmail.com>
1 parent eeaea0c commit a8f01d7

File tree

4 files changed

+22
-2
lines changed

4 files changed

+22
-2
lines changed

CHANGES/5250.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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``.

CONTRIBUTORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Claudiu Popa
7474
Colin Dunklau
7575
Cong Xu
7676
Damien Nadé
77+
Dan King
7778
Dan Xu
7879
Daniel García
7980
Daniel Grossmann-Kavanagh

aiohttp/web_urldispatcher.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ def __init__(self, prefix: str, *, name: Optional[str] = None) -> None:
513513
assert prefix in ("", "/") or not prefix.endswith("/"), prefix
514514
super().__init__(name=name)
515515
self._prefix = _requote_path(prefix)
516+
self._prefix2 = self._prefix + "/"
516517

517518
@property
518519
def canonical(self) -> str:
@@ -523,6 +524,7 @@ def add_prefix(self, prefix: str) -> None:
523524
assert not prefix.endswith("/")
524525
assert len(prefix) > 1
525526
self._prefix = prefix + self._prefix
527+
self._prefix2 = self._prefix + "/"
526528

527529
def raw_match(self, prefix: str) -> bool:
528530
return False
@@ -634,7 +636,7 @@ async def resolve(self, request: Request) -> _Resolve:
634636
path = request.rel_url.raw_path
635637
method = request.method
636638
allowed_methods = set(self._routes)
637-
if not path.startswith(self._prefix):
639+
if not path.startswith(self._prefix2) and path != self._prefix:
638640
return None, set()
639641

640642
if method not in allowed_methods:
@@ -750,7 +752,7 @@ def get_info(self) -> _InfoDict:
750752

751753
async def resolve(self, request: Request) -> _Resolve:
752754
if (
753-
not request.url.raw_path.startswith(self._prefix + "/")
755+
not request.url.raw_path.startswith(self._prefix2)
754756
and request.url.raw_path != self._prefix
755757
):
756758
return None, set()

tests/test_web_urldispatcher.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import shutil
66
import sys
77
import tempfile
8+
from typing import Any
89
from unittest import mock
910
from unittest.mock import MagicMock
1011

@@ -519,6 +520,21 @@ async def test_static_absolute_url(aiohttp_client, tmpdir) -> None:
519520
assert resp.status == 403
520521

521522

523+
async def test_for_issue_5250(aiohttp_client: Any, tmp_path: Any) -> None:
524+
app = web.Application()
525+
app.router.add_static("/foo", tmp_path)
526+
527+
async def get_foobar(request):
528+
return web.Response(body="success!")
529+
530+
app.router.add_get("/foobar", get_foobar)
531+
532+
client = await aiohttp_client(app)
533+
async with await client.get("/foobar") as resp:
534+
assert resp.status == 200
535+
assert (await resp.text()) == "success!"
536+
537+
522538
@pytest.mark.xfail(
523539
raises=AssertionError,
524540
reason="Regression in v3.7: https://github.com/aio-libs/aiohttp/issues/5621",

0 commit comments

Comments
 (0)