Skip to content

Commit a0b6145

Browse files
committed
fix(mcp): use pure ASGI middleware for client IP forwarding #1444
1 parent 9720cd8 commit a0b6145

1 file changed

Lines changed: 16 additions & 13 deletions

File tree

‎backend/main.py‎

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from starlette.datastructures import MutableHeaders
1414
from starlette.exceptions import HTTPException as StarletteHTTPException
1515
from starlette.middleware.cors import CORSMiddleware
16-
from starlette.middleware.base import BaseHTTPMiddleware
16+
from starlette.types import ASGIApp, Receive, Scope, Send
1717

1818
from alembic import command
1919
from apps.api import api_router
@@ -98,18 +98,21 @@ def custom_generate_unique_id(route: APIRoute) -> str:
9898
)
9999

100100

101-
class McpClientIpForwardMiddleware(BaseHTTPMiddleware):
102-
async def dispatch(self, request: Request, call_next):
103-
client_host = request.client.host if request.client else None
104-
if client_host:
105-
headers = MutableHeaders(scope=request.scope)
106-
if not headers.get("x-real-ip"):
107-
headers["x-real-ip"] = client_host
108-
if not headers.get("x-forwarded-for"):
109-
headers["x-forwarded-for"] = client_host
110-
if not headers.get("x-client-ip"):
111-
headers["x-client-ip"] = client_host
112-
return await call_next(request)
101+
class McpClientIpForwardMiddleware:
102+
def __init__(self, app: ASGIApp) -> None:
103+
self.app = app
104+
105+
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
106+
# MCP SSE uses the ASGI send channel directly. Do not wrap its response
107+
# in BaseHTTPMiddleware's response-body iterator.
108+
if scope["type"] == "http":
109+
client = scope.get("client")
110+
if client:
111+
headers = MutableHeaders(scope=scope)
112+
for name in ("x-real-ip", "x-forwarded-for", "x-client-ip"):
113+
if not headers.get(name):
114+
headers[name] = client[0]
115+
await self.app(scope, receive, send)
113116

114117
# cache docs for different text
115118
_openapi_cache: Dict[str, Dict[str, Any]] = {}

0 commit comments

Comments
 (0)