J. Nick Koston bb7e1d4723
Reduce overhead to run headers middleware (#142032)
Instead of having to itererate a dict, update
the headers multidict using a pre-build CIMultiDict
which has an internal fast path
2025-04-02 09:09:39 +02:00

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)