Spaces:
Sleeping
Sleeping
| """Defensive HTTP headers for every API response. | |
| X-Frame-Options / CSP frame-ancestors are deliberately omitted — the API | |
| returns JSON, not interactive HTML, so clickjacking doesn't apply, and | |
| asserting DENY breaks the HF Spaces dashboard preview iframe. The Vercel | |
| frontend (which actually serves HTML) sets those headers strictly itself. | |
| """ | |
| from __future__ import annotations | |
| from starlette.middleware.base import BaseHTTPMiddleware | |
| from starlette.requests import Request | |
| from starlette.responses import Response | |
| _HEADERS: dict[str, str] = { | |
| "Strict-Transport-Security": "max-age=63072000; includeSubDomains", | |
| "X-Content-Type-Options": "nosniff", | |
| "Referrer-Policy": "same-origin", | |
| "Permissions-Policy": "camera=(), microphone=(), geolocation=()", | |
| "Content-Security-Policy": "default-src 'none'", | |
| } | |
| class SecurityHeadersMiddleware(BaseHTTPMiddleware): | |
| async def dispatch(self, request: Request, call_next): | |
| response: Response = await call_next(request) | |
| for k, v in _HEADERS.items(): | |
| response.headers.setdefault(k, v) | |
| return response | |