mirror of
https://github.com/home-assistant/core.git
synced 2025-05-13 18:39:14 +00:00

Instead of having to itererate a dict, update the headers multidict using a pre-build CIMultiDict which has an internal fast path
50 lines
1.5 KiB
Python
50 lines
1.5 KiB
Python
"""Middleware that helps with the control of headers in our responses."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Awaitable, Callable
|
|
from typing import Final
|
|
|
|
from aiohttp import hdrs
|
|
from aiohttp.web import Application, Request, StreamResponse, middleware
|
|
from aiohttp.web_exceptions import HTTPException
|
|
from multidict import CIMultiDict, istr
|
|
|
|
from homeassistant.core import callback
|
|
|
|
REFERRER_POLICY: Final[istr] = istr("Referrer-Policy")
|
|
X_CONTENT_TYPE_OPTIONS: Final[istr] = istr("X-Content-Type-Options")
|
|
X_FRAME_OPTIONS: Final[istr] = istr("X-Frame-Options")
|
|
|
|
|
|
@callback
|
|
def setup_headers(app: Application, use_x_frame_options: bool) -> None:
|
|
"""Create headers middleware for the app."""
|
|
|
|
added_headers = CIMultiDict(
|
|
{
|
|
REFERRER_POLICY: "no-referrer",
|
|
X_CONTENT_TYPE_OPTIONS: "nosniff",
|
|
hdrs.SERVER: "", # Empty server header, to prevent aiohttp of setting one.
|
|
}
|
|
)
|
|
|
|
if use_x_frame_options:
|
|
added_headers[X_FRAME_OPTIONS] = "SAMEORIGIN"
|
|
|
|
@middleware
|
|
async def headers_middleware(
|
|
request: Request, handler: Callable[[Request], Awaitable[StreamResponse]]
|
|
) -> StreamResponse:
|
|
"""Process request and add headers to the responses."""
|
|
try:
|
|
response = await handler(request)
|
|
except HTTPException as err:
|
|
err.headers.update(added_headers)
|
|
raise
|
|
|
|
response.headers.update(added_headers)
|
|
return response
|
|
|
|
app.middlewares.append(headers_middleware)
|