diff --git a/homeassistant/components/http/static.py b/homeassistant/components/http/static.py index 5e2c4a7a7a9..1ab4ef5bd6f 100644 --- a/homeassistant/components/http/static.py +++ b/homeassistant/components/http/static.py @@ -1,7 +1,8 @@ """Static file handling for HTTP component.""" from __future__ import annotations -from collections.abc import Mapping +from collections.abc import Mapping, MutableMapping +import mimetypes from pathlib import Path from typing import Final @@ -16,10 +17,11 @@ from homeassistant.core import HomeAssistant from .const import KEY_HASS CACHE_TIME: Final = 31 * 86400 # = 1 month -CACHE_HEADERS: Final[Mapping[str, str]] = { - hdrs.CACHE_CONTROL: f"public, max-age={CACHE_TIME}" -} -PATH_CACHE = LRU(512) +CACHE_HEADER = f"public, max-age={CACHE_TIME}" +CACHE_HEADERS: Mapping[str, str] = {hdrs.CACHE_CONTROL: CACHE_HEADER} +PATH_CACHE: MutableMapping[ + tuple[str, Path, bool], tuple[Path | None, str | None] +] = LRU(512) def _get_file_path(rel_url: str, directory: Path, follow_symlinks: bool) -> Path | None: @@ -48,7 +50,7 @@ class CachingStaticResource(StaticResource): """Return requested file from disk as a FileResponse.""" rel_url = request.match_info["filename"] key = (rel_url, self._directory, self._follow_symlinks) - if (filepath := PATH_CACHE.get(key)) is None: + if (filepath_content_type := PATH_CACHE.get(key)) is None: hass: HomeAssistant = request.app[KEY_HASS] try: filepath = await hass.async_add_executor_job(_get_file_path, *key) @@ -62,13 +64,24 @@ class CachingStaticResource(StaticResource): # perm error or other kind! request.app.logger.exception(error) raise HTTPNotFound() from error - PATH_CACHE[key] = filepath - if filepath: + content_type: str | None = None + if filepath is not None: + content_type = (mimetypes.guess_type(rel_url))[ + 0 + ] or "application/octet-stream" + PATH_CACHE[key] = (filepath, content_type) + else: + filepath, content_type = filepath_content_type + + if filepath and content_type: return FileResponse( filepath, chunk_size=self._chunk_size, - headers=CACHE_HEADERS, + headers={ + hdrs.CACHE_CONTROL: CACHE_HEADER, + hdrs.CONTENT_TYPE: content_type, + }, ) return await super()._handle(request)