mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 09:17:10 +00:00
Cache the mime type of static files (#103281)
This commit is contained in:
parent
4778c55d2b
commit
062b510ec0
@ -1,7 +1,8 @@
|
|||||||
"""Static file handling for HTTP component."""
|
"""Static file handling for HTTP component."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping, MutableMapping
|
||||||
|
import mimetypes
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
@ -16,10 +17,11 @@ from homeassistant.core import HomeAssistant
|
|||||||
from .const import KEY_HASS
|
from .const import KEY_HASS
|
||||||
|
|
||||||
CACHE_TIME: Final = 31 * 86400 # = 1 month
|
CACHE_TIME: Final = 31 * 86400 # = 1 month
|
||||||
CACHE_HEADERS: Final[Mapping[str, str]] = {
|
CACHE_HEADER = f"public, max-age={CACHE_TIME}"
|
||||||
hdrs.CACHE_CONTROL: f"public, max-age={CACHE_TIME}"
|
CACHE_HEADERS: Mapping[str, str] = {hdrs.CACHE_CONTROL: CACHE_HEADER}
|
||||||
}
|
PATH_CACHE: MutableMapping[
|
||||||
PATH_CACHE = LRU(512)
|
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:
|
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."""
|
"""Return requested file from disk as a FileResponse."""
|
||||||
rel_url = request.match_info["filename"]
|
rel_url = request.match_info["filename"]
|
||||||
key = (rel_url, self._directory, self._follow_symlinks)
|
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]
|
hass: HomeAssistant = request.app[KEY_HASS]
|
||||||
try:
|
try:
|
||||||
filepath = await hass.async_add_executor_job(_get_file_path, *key)
|
filepath = await hass.async_add_executor_job(_get_file_path, *key)
|
||||||
@ -62,13 +64,24 @@ class CachingStaticResource(StaticResource):
|
|||||||
# perm error or other kind!
|
# perm error or other kind!
|
||||||
request.app.logger.exception(error)
|
request.app.logger.exception(error)
|
||||||
raise HTTPNotFound() from 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(
|
return FileResponse(
|
||||||
filepath,
|
filepath,
|
||||||
chunk_size=self._chunk_size,
|
chunk_size=self._chunk_size,
|
||||||
headers=CACHE_HEADERS,
|
headers={
|
||||||
|
hdrs.CACHE_CONTROL: CACHE_HEADER,
|
||||||
|
hdrs.CONTENT_TYPE: content_type,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return await super()._handle(request)
|
return await super()._handle(request)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user