From b444c1b0f5c60d0e46b04adf00618969a65ac497 Mon Sep 17 00:00:00 2001 From: BlueSkyXN <63384277+BlueSkyXN@users.noreply.github.com> Date: Mon, 21 Apr 2025 16:16:57 +0800 Subject: [PATCH] 0.4.1 --- auth2xapikey.py | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 auth2xapikey.py diff --git a/auth2xapikey.py b/auth2xapikey.py new file mode 100644 index 0000000..693805f --- /dev/null +++ b/auth2xapikey.py @@ -0,0 +1,98 @@ +from fastapi import FastAPI, Request, Header +import httpx +import uvicorn +from typing import Optional +from fastapi.responses import StreamingResponse, Response +import logging + +# 设置日志 +logging.basicConfig(level=logging.INFO, + format='%(asctime)s [%(levelname)s] [%(name)s] %(message)s') +logger = logging.getLogger(__name__) + +app = FastAPI() + +TARGET_API_URL = "https://rad.huddlz.xyz" # 替换为您的目标API地址 + +@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"]) +async def proxy_request(request: Request, path: str, authorization: Optional[str] = Header(None)): + # 记录请求信息 + logger.info(f"接收到请求: {request.method} {request.url.path}") + + # 获取原始请求体 + body = await request.body() + + # 获取并处理原始请求头 + headers = dict(request.headers) + logger.debug(f"原始请求头: {headers}") + + # 从Authorization中提取token并设置为x-api-key + if authorization: + token = authorization.replace("Bearer ", "") + headers["x-api-key"] = token + logger.debug(f"从Authorization提取并设置x-api-key") + + # 移除可能导致问题的请求头 + headers.pop("host", None) + + # 处理内容编码相关头信息 + # 移除Accept-Encoding头,让httpx自己处理内容压缩/解压缩 + if "accept-encoding" in headers: + logger.debug(f"移除Accept-Encoding: {headers.get('accept-encoding')}") + headers.pop("accept-encoding", None) + + # 构建完整的目标URL + url = f"{TARGET_API_URL}/{path}" + logger.info(f"转发请求到: {url}") + + # 获取查询参数 + params = dict(request.query_params) + + try: + # 转发请求到目标API,禁用自动处理压缩内容 + async with httpx.AsyncClient(headers={"Accept-Encoding": "identity"}) as client: + response = await client.request( + method=request.method, + url=url, + params=params, + headers=headers, + content=body, + timeout=60.0, + follow_redirects=True + ) + + logger.info(f"收到响应: 状态码 {response.status_code}") + logger.debug(f"响应头: {response.headers}") + + # 处理响应头,移除可能导致问题的头信息 + response_headers = dict(response.headers) + + # 移除可能导致冲突的头信息 + headers_to_remove = [ + "content-length", + "transfer-encoding", + "content-encoding", # 重要:移除内容编码头 + "server", + "connection" + ] + + for header in headers_to_remove: + if header in response_headers: + logger.debug(f"移除响应头: {header}") + response_headers.pop(header, None) + + # 获取响应内容(已自动解压缩) + content = await response.aread() + + # 返回未压缩的响应 + return Response( + content=content, + status_code=response.status_code, + headers=response_headers + ) + except Exception as e: + logger.error(f"请求处理过程中发生错误: {str(e)}", exc_info=True) + return {"detail": f"代理服务器错误: {str(e)}"}, 500 + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=9898) \ No newline at end of file