bobocup commited on
Commit
2ee3bb2
·
verified ·
1 Parent(s): 757adbe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -30
app.py CHANGED
@@ -1,39 +1,108 @@
1
- from fastapi import FastAPI, Request
2
- from fastapi.responses import Response, HTMLResponse
3
- import requests
 
 
 
4
 
5
  app = FastAPI()
6
 
7
- @app.get("/", response_class=HTMLResponse)
8
- @app.get("/{path:path}", response_class=HTMLResponse)
9
- async def proxy(request: Request, path: str = ""):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  try:
11
- # 构建目标 URL
12
- if path.startswith("api/"):
13
- actual_path = path[4:] # 跳过 "api/"
14
- target_url = f"http://beibeioo.top/{actual_path}"
15
- else:
16
- target_url = "http://beibeioo.top"
17
 
18
- # 转发请求
19
- response = requests.get(
20
- target_url,
21
- headers={
22
- 'User-Agent': 'Mozilla/5.0',
23
- 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
24
- 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
25
- }
26
- )
 
 
 
 
 
 
 
 
27
 
28
- # 返回响应
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  return Response(
30
- content=response.content,
31
- media_type=response.headers.get('content-type', 'text/html'),
32
- headers={
33
- 'Access-Control-Allow-Origin': '*',
34
- 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
35
- 'Access-Control-Allow-Headers': '*'
36
- }
 
 
37
  )
38
  except Exception as e:
39
- return HTMLResponse(content=f"Error: {str(e)}", status_code=500)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request, Response
2
+ from fastapi.responses import StreamingResponse
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ import httpx
5
+ import asyncio
6
+ from typing import Optional
7
 
8
  app = FastAPI()
9
 
10
+ # 添加 CORS 支持
11
+ app.add_middleware(
12
+ CORSMiddleware,
13
+ allow_origins=["*"],
14
+ allow_credentials=True,
15
+ allow_methods=["*"],
16
+ allow_headers=["*"],
17
+ )
18
+
19
+ # 目标网站
20
+ TARGET_URL = "http://beibeioo.top"
21
+
22
+ # 创建一个全局的 httpx 客户端
23
+ async def get_http_client():
24
+ return httpx.AsyncClient(
25
+ timeout=30.0, # 30秒超时
26
+ follow_redirects=True,
27
+ http2=True
28
+ )
29
+
30
+ @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"])
31
+ async def proxy(path: str, request: Request):
32
  try:
33
+ # 构建目标URL
34
+ url = f"{TARGET_URL}/{path}"
 
 
 
 
35
 
36
+ # 获取并处理请求头
37
+ headers = dict(request.headers)
38
+ # 删除可能导致问题的头部
39
+ headers.pop('host', None)
40
+ headers.pop('connection', None)
41
+ headers.pop('content-length', None)
42
+ headers.pop('transfer-encoding', None)
43
+
44
+ # 如果有 referer,修改它
45
+ if 'referer' in headers:
46
+ headers['referer'] = headers['referer'].replace(str(request.base_url), TARGET_URL)
47
+
48
+ # 获取查询参数
49
+ params = dict(request.query_params)
50
+
51
+ # 获取请求体
52
+ body = await request.body()
53
 
54
+ async with await get_http_client() as client:
55
+ response = await client.request(
56
+ method=request.method,
57
+ url=url,
58
+ params=params,
59
+ headers=headers,
60
+ content=body if body else None,
61
+ )
62
+
63
+ # 处理响应头
64
+ response_headers = dict(response.headers)
65
+ # 删除可能导致问题的响应头
66
+ response_headers.pop('transfer-encoding', None)
67
+ response_headers.pop('content-encoding', None)
68
+
69
+ # 修改所有涉及原始域名的响应头
70
+ for key, value in response_headers.items():
71
+ if isinstance(value, str) and TARGET_URL in value:
72
+ response_headers[key] = value.replace(TARGET_URL, str(request.base_url).rstrip('/'))
73
+
74
+ # 返回响应
75
+ return StreamingResponse(
76
+ response.iter_bytes(),
77
+ status_code=response.status_code,
78
+ headers=response_headers,
79
+ media_type=response.headers.get('content-type')
80
+ )
81
+
82
+ except httpx.TimeoutException:
83
  return Response(
84
+ content="请求超时",
85
+ status_code=504,
86
+ media_type="text/plain"
87
+ )
88
+ except httpx.RequestError:
89
+ return Response(
90
+ content="无法连接到目标服务器",
91
+ status_code=502,
92
+ media_type="text/plain"
93
  )
94
  except Exception as e:
95
+ return Response(
96
+ content=f"服务器错误: {str(e)}",
97
+ status_code=500,
98
+ media_type="text/plain"
99
+ )
100
+
101
+ @app.get("/healthcheck")
102
+ async def healthcheck():
103
+ """健康检查端点"""
104
+ return {"status": "healthy"}
105
+
106
+ if __name__ == "__main__":
107
+ import uvicorn
108
+ uvicorn.run(app, host="0.0.0.0", port=7860)