Source code for piccolo_api.csp.middleware
from __future__ import annotations
import typing as t
from dataclasses import dataclass
from functools import wraps
if t.TYPE_CHECKING: # pragma: no cover
from starlette.types import ASGIApp, Message, Receive, Scope, Send
[docs]
@dataclass
class CSPConfig:
report_uri: t.Optional[bytes] = None
default_src: str = "self"
[docs]
class CSPMiddleware:
"""
Adds Content Security Policy headers to the response.
"""
def __init__(self, app: ASGIApp, config: CSPConfig = CSPConfig()):
self.app = app
self.config = config
async def __call__(self, scope: Scope, receive: Receive, send: Send):
@wraps(send)
async def wrapped_send(message: Message):
if message["type"] == "http.response.start":
headers = message.get("headers", [])
header_value = bytes(
f"default-src '{self.config.default_src}'", "utf8"
)
if self.config.report_uri:
header_value = (
header_value
+ b"; report-uri "
+ self.config.report_uri
)
headers.append([b"content-security-policy", header_value])
message["headers"] = headers
await send(message)
await self.app(scope, receive, wrapped_send)