Skip to content

Commit 6ddcf80

Browse files
committed
feat: add system log in mcp_start
1 parent 8a10be0 commit 6ddcf80

2 files changed

Lines changed: 44 additions & 5 deletions

File tree

backend/common/audit/schemas/logger_decorator.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,34 @@ def get_client_info(request: Request) -> Dict[str, Optional[str]]:
127127
user_agent = None
128128

129129
if request:
130-
# Obtain IP address
131-
if request.client:
130+
# Prefer real client IP headers, then fallback to socket peer IP.
131+
header_candidates = [
132+
"x-forwarded-for",
133+
"x-real-ip",
134+
"cf-connecting-ip",
135+
"x-client-ip",
136+
"x-forwarded",
137+
"forwarded",
138+
]
139+
for key in header_candidates:
140+
value = request.headers.get(key)
141+
if value:
142+
if key == "x-forwarded-for":
143+
ip_address = value.split(",")[0].strip()
144+
elif key == "forwarded":
145+
# RFC 7239 format, e.g. for=203.0.113.43;proto=https;by=203.0.113.1
146+
parts = [part.strip() for part in value.split(";")]
147+
for part in parts:
148+
if part.lower().startswith("for="):
149+
ip_address = part.split("=", 1)[1].strip().strip('"')
150+
break
151+
else:
152+
ip_address = value.strip()
153+
if ip_address:
154+
break
155+
156+
if not ip_address and request.client:
132157
ip_address = request.client.host
133-
# Attempt to obtain the real IP from X-Forwarded-For
134-
if "x-forwarded-for" in request.headers:
135-
ip_address = request.headers["x-forwarded-for"].split(",")[0].strip()
136158

137159
# Get User Agent
138160
user_agent = request.headers.get("user-agent")

backend/main.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
from fastapi.routing import APIRoute
1111
from fastapi.staticfiles import StaticFiles
1212
from fastapi_mcp import FastApiMCP
13+
from starlette.datastructures import MutableHeaders
1314
from starlette.exceptions import HTTPException as StarletteHTTPException
1415
from starlette.middleware.cors import CORSMiddleware
16+
from starlette.middleware.base import BaseHTTPMiddleware
1517

1618
from alembic import command
1719
from apps.api import api_router
@@ -77,6 +79,20 @@ def custom_generate_unique_id(route: APIRoute) -> str:
7779
redoc_url=None
7880
)
7981

82+
83+
class McpClientIpForwardMiddleware(BaseHTTPMiddleware):
84+
async def dispatch(self, request: Request, call_next):
85+
client_host = request.client.host if request.client else None
86+
if client_host:
87+
headers = MutableHeaders(scope=request.scope)
88+
if not headers.get("x-real-ip"):
89+
headers["x-real-ip"] = client_host
90+
if not headers.get("x-forwarded-for"):
91+
headers["x-forwarded-for"] = client_host
92+
if not headers.get("x-client-ip"):
93+
headers["x-client-ip"] = client_host
94+
return await call_next(request)
95+
8096
# cache docs for different text
8197
_openapi_cache: Dict[str, Dict[str, Any]] = {}
8298

@@ -174,6 +190,7 @@ async def custom_swagger_ui(request: Request):
174190

175191

176192
mcp_app = FastAPI()
193+
mcp_app.add_middleware(McpClientIpForwardMiddleware)
177194
# mcp server, images path
178195
images_path = settings.MCP_IMAGE_PATH
179196
os.makedirs(images_path, exist_ok=True)

0 commit comments

Comments
 (0)