Skip to content

Commit 54c79df

Browse files
authored
Fix CustomStaticResource with aiohttp 3.10+ (#689)
1 parent d0074cd commit 54c79df

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

aiohttp_devtools/runserver/serve.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -397,23 +397,49 @@ def _insert_footer(self, response: web.StreamResponse) -> web.StreamResponse:
397397
resp.last_modified = filepath.stat().st_mtime # type: ignore[assignment]
398398
return resp
399399

400+
def _insert_footer_if_exists(
401+
self, filename: str, response: web.StreamResponse
402+
) -> web.StreamResponse:
403+
"""Insert the footer if the file exists, otherwise return a 404 response."""
404+
resolved_path = self._directory.joinpath(filename).resolve()
405+
if not resolved_path.is_file():
406+
return self._make_not_found_response(resolved_path)
407+
return self._insert_footer(response)
408+
409+
def _make_not_found_response(self, raw_path: Path) -> web.StreamResponse:
410+
"""Create a 404 response with a list of available files under the requested path."""
411+
while not raw_path.is_dir():
412+
raw_path = raw_path.parent
413+
paths = "\n".join(
414+
" {}{}".format(p.relative_to(self._directory), "/" if p.is_dir() else "")
415+
for p in raw_path.iterdir()
416+
)
417+
msg = "404: Not Found\n\nAvailable files under '{}/':\n{}\n".format(
418+
raw_path.relative_to(self._directory), paths
419+
)
420+
return web.Response(text=msg, status=404, content_type="text/plain")
421+
400422
async def _handle(self, request: web.Request) -> web.StreamResponse:
401-
raw_path = self.modify_request(request)
423+
loop = asyncio.get_running_loop()
424+
raw_path = await loop.run_in_executor(None, self.modify_request, request)
402425
try:
403426
response = await super()._handle(request)
404427
except HTTPNotFound:
405-
while not raw_path.is_dir():
406-
raw_path = raw_path.parent
407-
paths = "\n".join(
408-
" {}{}".format(p.relative_to(self._directory), "/" if p.is_dir() else "")
409-
for p in raw_path.iterdir())
410-
msg = "404: Not Found\n\nAvailable files under '{}/':\n{}\n".format(
411-
raw_path.relative_to(self._directory), paths)
412-
response = web.Response(text=msg, status=404, content_type="text/plain")
428+
response = await loop.run_in_executor(
429+
None, self._make_not_found_response, raw_path
430+
)
413431
else:
414-
response = self._insert_footer(response)
432+
# With aiohttp 3.10+, we need to also check if the file actually
433+
# exists since the base class does not check this anymore as its
434+
# done in the response to enable handling various compressed files.
435+
response = await loop.run_in_executor(
436+
None,
437+
self._insert_footer_if_exists,
438+
request.match_info["filename"],
439+
response,
440+
)
415441
# Inject CORS headers to allow webfonts to load correctly
416-
response.headers['Access-Control-Allow-Origin'] = '*'
442+
response.headers["Access-Control-Allow-Origin"] = "*"
417443

418444
if not self._browser_cache:
419445
# Add no-cache header to avoid browser caching in local development.

0 commit comments

Comments
 (0)