Coverage for polar/kit/cors.py: 62%
49 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 17:15 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 17:15 +0000
1import dataclasses 1a
2from collections.abc import Sequence 1a
3from typing import Protocol 1a
5from starlette.datastructures import Headers 1a
6from starlette.middleware.cors import CORSMiddleware 1a
7from starlette.types import ASGIApp, Receive, Scope, Send 1a
10class CORSMatcher(Protocol): 1a
11 def __call__(self, origin: str, scope: Scope) -> bool: ... 11 ↛ exitline 11 didn't return from function '__call__' because 1a
14@dataclasses.dataclass 1a
15class CORSConfig: 1a
16 matcher: CORSMatcher 1a
17 allow_origins: Sequence[str] = () 1a
18 allow_methods: Sequence[str] = ("GET",) 1a
19 allow_headers: Sequence[str] = () 1a
20 allow_credentials: bool = False 1a
21 allow_origin_regex: str | None = None 1a
22 expose_headers: Sequence[str] = () 1a
23 max_age: int = 600 1a
25 def get_middleware(self, app: ASGIApp) -> CORSMiddleware: 1a
26 return CORSMiddleware(
27 app=app,
28 allow_origins=self.allow_origins,
29 allow_methods=self.allow_methods,
30 allow_headers=self.allow_headers,
31 allow_credentials=self.allow_credentials,
32 allow_origin_regex=self.allow_origin_regex,
33 expose_headers=self.expose_headers,
34 max_age=self.max_age,
35 )
38class CORSMatcherMiddleware: 1a
39 def __init__(self, app: ASGIApp, *, configs: Sequence[CORSConfig]) -> None: 1a
40 self.app = app
41 self.config_middlewares = tuple(
42 (config, config.get_middleware(app)) for config in configs
43 )
45 async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: 1a
46 if scope["type"] != "http": # pragma: no cover 1cb
47 await self.app(scope, receive, send)
48 return
50 method = scope["method"] 1cb
51 headers = Headers(scope=scope) 1cb
52 origin = headers.get("origin") 1cb
54 if origin is None: 54 ↛ 58line 54 didn't jump to line 58 because the condition on line 54 was always true1cb
55 await self.app(scope, receive, send) 1cb
56 return 1cb
58 middleware = self._get_config_middleware(origin, scope)
59 if middleware is None:
60 await self.app(scope, receive, send)
61 return
63 if method == "OPTIONS" and "access-control-request-method" in headers:
64 response = middleware.preflight_response(request_headers=headers)
65 await response(scope, receive, send)
66 return
67 await middleware.simple_response(scope, receive, send, request_headers=headers)
69 def _get_config_middleware( 1a
70 self, origin: str, scope: Scope
71 ) -> CORSMiddleware | None:
72 for config, middleware in self.config_middlewares:
73 if config.matcher(origin, scope):
74 return middleware
75 return None
78__all__ = ["CORSConfig", "CORSMatcherMiddleware", "Scope"] 1a