diff --git a/CHANGES/9972.bugfix.rst b/CHANGES/9972.bugfix.rst index d8d69d09044..c3ea8ef19d7 100644 --- a/CHANGES/9972.bugfix.rst +++ b/CHANGES/9972.bugfix.rst @@ -1,3 +1 @@ -Reverted an optimization to avoid rebuilding the allowed methods for ``StaticResource`` on every request -- by :user:`bdraco`. - -``aiohttp-cors`` needs to be able to modify the allowed methods at run time via this internal. +Fixed ``StaticResource`` not allowing the ``OPTIONS`` method after calling ``set_options_route`` -- by :user:`bdraco`. diff --git a/CHANGES/9976.bugfix.rst b/CHANGES/9976.bugfix.rst new file mode 120000 index 00000000000..18bf311de3b --- /dev/null +++ b/CHANGES/9976.bugfix.rst @@ -0,0 +1 @@ +9972.bugfix.rst \ No newline at end of file diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index 025962bc594..5e3b71ff2e6 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -580,6 +580,7 @@ def __init__( "HEAD", self._handle, self, expect_handler=expect_handler ), } + self._allowed_methods = set(self._routes) def url_for( # type: ignore[override] self, @@ -642,6 +643,7 @@ def set_options_route(self, handler: Handler) -> None: self._routes["OPTIONS"] = ResourceRoute( "OPTIONS", handler, self, expect_handler=self._expect_handler ) + self._allowed_methods.add("OPTIONS") async def resolve(self, request: Request) -> _Resolve: path = request.rel_url.path_safe @@ -649,7 +651,7 @@ async def resolve(self, request: Request) -> _Resolve: if not path.startswith(self._prefix2) and path != self._prefix: return None, set() - allowed_methods = set(self._routes) + allowed_methods = self._allowed_methods if method not in allowed_methods: return None, allowed_methods diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index 72555adfe76..79eda49e196 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -498,6 +498,7 @@ async def test_add_static_access_resources(router: web.UrlDispatcher) -> None: "/st", pathlib.Path(aiohttp.__file__).parent, name="static" ) resource._routes[hdrs.METH_OPTIONS] = resource._routes[hdrs.METH_GET] + resource._allowed_methods.add(hdrs.METH_OPTIONS) mapping, allowed_methods = await resource.resolve( make_mocked_request("OPTIONS", "/st/path") )