import logging from typing import List import httpx from fastapi import FastAPI, Request, Response, HTTPException from starlette.status import HTTP_502_BAD_GATEWAY from alien_gateway.config import settings app = FastAPI( title=f"{settings.PROJECT_NAME} - Gateway & Auth Service", version="1.0.0" ) logger = logging.getLogger("alien_gateway") @app.get("/health") async def health(): return {"service": "alien_gateway", "status": "ok"} # 此模块未来将承担 JWT 签发、权限校验中间件、路由聚合等核心功能 @app.post("/auth/login") async def login(): return {"message": "Auth logic here"} HOP_BY_HOP_HEADERS: List[str] = [ "connection", "keep-alive", "proxy-authenticate", "proxy-authorization", "te", "trailers", "transfer-encoding", "upgrade", ] def _clean_headers(headers): """移除 hop-by-hop 头,避免转发问题。""" return {k: v for k, v in headers.items() if k.lower() not in HOP_BY_HOP_HEADERS} @app.api_route("/api/store/{full_path:path}", methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]) async def proxy_to_store(full_path: str, request: Request): """ 简易网关:监听 33333 端口,将 /api/store/* 转发到 alien_store 服务。 """ target_url = f"{settings.STORE_BASE_URL}/api/store/{full_path}" client_ip = request.client.host if request.client else "-" # 读取请求体 body = await request.body() # 过滤头部 headers = _clean_headers(dict(request.headers)) try: async with httpx.AsyncClient(timeout=30.0) as client: resp = await client.request( request.method, target_url, content=body, headers=headers, params=request.query_params, ) except Exception as exc: logger.error("proxy to store failed ip=%s url=%s err=%s", client_ip, target_url, exc) raise HTTPException(status_code=HTTP_502_BAD_GATEWAY, detail="Upstream unavailable") # 返回下游响应 return Response( content=resp.content, status_code=resp.status_code, headers=_clean_headers(resp.headers), media_type=resp.headers.get("content-type"), ) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=33333)