bobocup commited on
Commit
00e65da
·
verified ·
1 Parent(s): 7c2325b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -45
app.py CHANGED
@@ -6,7 +6,6 @@ from typing import Optional
6
 
7
  app = FastAPI()
8
 
9
- # 添加 CORS 支持
10
  app.add_middleware(
11
  CORSMiddleware,
12
  allow_origins=["*"],
@@ -15,10 +14,8 @@ app.add_middleware(
15
  allow_headers=["*"],
16
  )
17
 
18
- # 目标网站
19
  TARGET_URL = "http://beibeioo.top"
20
 
21
- # 创建一个全局的 httpx 客户端
22
  async def get_http_client():
23
  return httpx.AsyncClient(
24
  timeout=30.0,
@@ -26,35 +23,22 @@ async def get_http_client():
26
  http2=True
27
  )
28
 
29
- # 处理 /api 路径
30
- @app.api_route("/api", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"])
31
- async def api_root(request: Request):
32
- return await proxy_handler("", request) # 传空字符串,直接访问根路径
33
-
34
- # 处理 /api/xxx 路径
35
- @app.api_route("/api/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"])
36
- async def api_proxy(path: str, request: Request):
37
- return await proxy_handler(path, request)
38
-
39
- # 处理其他所有路径
40
- @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"])
41
- async def general_proxy(path: str, request: Request):
42
- return await proxy_handler(path, request)
43
-
44
- # 代理处理函数
45
  async def proxy_handler(path: str, request: Request):
46
  try:
47
- # 构建目标URL
48
- url = f"{TARGET_URL}/{path}"
 
49
 
50
- # 获取并处理请求头
51
  headers = dict(request.headers)
52
  headers.pop('host', None)
53
  headers.pop('connection', None)
54
  headers.pop('content-length', None)
55
  headers.pop('transfer-encoding', None)
56
 
57
- # 获取查询参数和请求体
 
 
 
58
  params = dict(request.query_params)
59
  body = await request.body()
60
 
@@ -67,46 +51,57 @@ async def proxy_handler(path: str, request: Request):
67
  content=body if body else None,
68
  )
69
 
70
- # 处理响应头
71
  response_headers = dict(response.headers)
72
  response_headers.pop('transfer-encoding', None)
73
  response_headers.pop('content-encoding', None)
74
  response_headers.pop('content-length', None)
75
 
76
- # 修改涉及原始域名的响应头
77
- for key, value in response_headers.items():
78
- if isinstance(value, str) and TARGET_URL in value:
79
- response_headers[key] = value.replace(TARGET_URL, str(request.base_url).rstrip('/'))
 
 
 
80
 
81
  return Response(
82
- content=response.content,
83
  status_code=response.status_code,
84
  headers=response_headers,
85
  media_type=response.headers.get('content-type')
86
  )
87
 
88
  except httpx.TimeoutException:
89
- return Response(
90
- content="请求超时",
91
- status_code=504,
92
- media_type="text/plain"
93
- )
94
  except httpx.RequestError:
95
- return Response(
96
- content="无法连接到目标服务器",
97
- status_code=502,
98
- media_type="text/plain"
99
- )
100
  except Exception as e:
101
- return Response(
102
- content=f"服务器错误: {str(e)}",
103
- status_code=500,
104
- media_type="text/plain"
105
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  @app.get("/healthcheck")
108
  async def healthcheck():
109
- """健康检查端点"""
110
  return {"status": "healthy"}
111
 
112
  if __name__ == "__main__":
 
6
 
7
  app = FastAPI()
8
 
 
9
  app.add_middleware(
10
  CORSMiddleware,
11
  allow_origins=["*"],
 
14
  allow_headers=["*"],
15
  )
16
 
 
17
  TARGET_URL = "http://beibeioo.top"
18
 
 
19
  async def get_http_client():
20
  return httpx.AsyncClient(
21
  timeout=30.0,
 
23
  http2=True
24
  )
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  async def proxy_handler(path: str, request: Request):
27
  try:
28
+ # 移除开头和结尾的斜杠
29
+ path = path.strip('/')
30
+ url = f"{TARGET_URL}/{path}" if path else TARGET_URL
31
 
 
32
  headers = dict(request.headers)
33
  headers.pop('host', None)
34
  headers.pop('connection', None)
35
  headers.pop('content-length', None)
36
  headers.pop('transfer-encoding', None)
37
 
38
+ # 修改 referer
39
+ if 'referer' in headers:
40
+ headers['referer'] = headers['referer'].replace(str(request.base_url), f"{TARGET_URL}/")
41
+
42
  params = dict(request.query_params)
43
  body = await request.body()
44
 
 
51
  content=body if body else None,
52
  )
53
 
 
54
  response_headers = dict(response.headers)
55
  response_headers.pop('transfer-encoding', None)
56
  response_headers.pop('content-encoding', None)
57
  response_headers.pop('content-length', None)
58
 
59
+ # 修改响应中的所有目标URL引用
60
+ content = response.content
61
+ if response.headers.get('content-type', '').startswith(('text/html', 'text/css', 'application/javascript')):
62
+ content = content.replace(
63
+ TARGET_URL.encode(),
64
+ str(request.base_url).rstrip('/').encode()
65
+ )
66
 
67
  return Response(
68
+ content=content,
69
  status_code=response.status_code,
70
  headers=response_headers,
71
  media_type=response.headers.get('content-type')
72
  )
73
 
74
  except httpx.TimeoutException:
75
+ return Response(content="请求超时", status_code=504)
 
 
 
 
76
  except httpx.RequestError:
77
+ return Response(content="无法连接到目标服务器", status_code=502)
 
 
 
 
78
  except Exception as e:
79
+ return Response(content=f"服务器错误: {str(e)}", status_code=500)
80
+
81
+ # 处理 /api 路径(映射到根路径)
82
+ @app.api_route("/api", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"])
83
+ async def api_root(request: Request):
84
+ return await proxy_handler("", request)
85
+
86
+ # 处理 /api/ 路径(也映射到根路径)
87
+ @app.api_route("/api/", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"])
88
+ async def api_root_slash(request: Request):
89
+ return await proxy_handler("", request)
90
+
91
+ # 处理 /api/xxx 路径
92
+ @app.api_route("/api/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"])
93
+ async def api_proxy(path: str, request: Request):
94
+ return await proxy_handler(path, request)
95
+
96
+ # 处理其他路径
97
+ @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"])
98
+ async def general_proxy(path: str, request: Request):
99
+ if path == "api":
100
+ return await proxy_handler("", request)
101
+ return await proxy_handler(path, request)
102
 
103
  @app.get("/healthcheck")
104
  async def healthcheck():
 
105
  return {"status": "healthy"}
106
 
107
  if __name__ == "__main__":