Files
MoviePilot/app/adapters/web/correlation.py
DDSRem 2de976f6b3 Merge pull request #7050 from DDSRem-Dev/codex-comment-migration
docs: 统一全项目中文注释和结构化契约说明
2026-10-17 19:26:29 +08:00

57 lines
2.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
HTTP 请求关联 ID 的 ASGI 适配器。
"""
from __future__ import annotations
from starlette.types import ASGIApp, Message, Receive, Scope, Send
from app.runtime.correlation import (
CORRELATION_ID_HEADER,
correlation_scope,
normalize_correlation_id,
)
class CorrelationIdMiddleware:
"""
验证入口 ID、绑定请求上下文并把同一 ID 写回响应。
"""
def __init__(self, app: ASGIApp) -> None:
"""
保存下游 ASGI 应用。
"""
self._app = app
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
"""
为 HTTP 请求绑定关联 ID,绑定范围覆盖完整流式响应生命周期。
其他连接类型直接转交下游;请求结束或抛出异常后恢复原有上下文。
"""
if scope.get("type") != "http":
await self._app(scope, receive, send)
return
raw_headers = dict(scope.get("headers") or [])
candidate = raw_headers.get(CORRELATION_ID_HEADER.lower().encode("ascii"))
correlation_id = normalize_correlation_id(
candidate.decode("ascii", errors="ignore") if candidate else None
)
scope.setdefault("state", {})["request_id"] = correlation_id
async def send_with_correlation(message: Message) -> None:
"""
在响应开始帧中覆盖为当前请求的安全关联 ID。
"""
if message.get("type") == "http.response.start":
headers = list(message.get("headers") or [])
header_name = CORRELATION_ID_HEADER.lower().encode("ascii")
headers = [item for item in headers if item[0].lower() != header_name]
headers.append((header_name, correlation_id.encode("ascii")))
message["headers"] = headers
await send(message)
with correlation_scope(correlation_id):
await self._app(scope, receive, send_with_correlation)