File size: 3,425 Bytes
da21cc3 4c34c0c a32f715 d87880a da21cc3 d87880a 4c34c0c d87880a da21cc3 9a4bcfd da21cc3 d87880a 4c34c0c da21cc3 4c34c0c da21cc3 871b55b d87880a da21cc3 d87880a 2b2c18d d87880a 2b2c18d d87880a 2b2c18d d87880a 2b2c18d d87880a da21cc3 2b2c18d d87880a 871b55b 1dec9a0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
from fastapi import FastAPI, Request, Response, WebSocket, WebSocketDisconnect
import httpx
import uvicorn
import asyncio
import websockets
import logging
app = FastAPI()
TARGET_BASE = "http://127.0.0.1:9222" # Chrome DevTools HTTP 地址
TARGET_WS_BASE = "ws://127.0.0.1:9222" # Chrome DevTools WebSocket 地址
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"])
async def proxy(request: Request, path: str):
url = f"{TARGET_BASE}/{path}"
headers = dict(request.headers)
headers["host"] = "127.0.0.1" # 强制修改 Host 头
body = await request.body()
async with httpx.AsyncClient(follow_redirects=True) as client:
resp = await client.request(
request.method,
url,
headers=headers,
content=body,
params=request.query_params
)
return Response(
content=resp.content,
status_code=resp.status_code,
headers=dict(resp.headers)
)
@app.websocket("/{path:path}")
async def websocket_proxy(websocket: WebSocket, path: str):
await websocket.accept()
target_url = f"{TARGET_WS_BASE}/{path}"
logger.info(f"Forwarding WebSocket to: {target_url}")
try:
# 创建自定义连接
async def create_connection():
return await websockets.connect(
target_url,
# extra_headers={"Host": "127.0.0.1"},
ping_interval=20,
ping_timeout=30
)
target_ws = await create_connection()
async def forward_client_to_server():
try:
while True:
# 明确处理文本和二进制消息
message = await websocket.receive()
if message["type"] == "websocket.receive.text":
await target_ws.send(message["text"])
logger.info(f"Sent text: {message['text'][:100]}")
elif message["type"] == "websocket.receive.bytes":
await target_ws.send(message["bytes"])
logger.info(f"Sent bytes: {message['bytes'][:100]}")
except Exception as e:
logger.error(f"Client->Server error: {e}")
raise
async def forward_server_to_client():
try:
while True:
message = await target_ws.recv()
if isinstance(message, str):
await websocket.send_text(message)
logger.info(f"Received text: {message[:100]}")
elif isinstance(message, bytes):
await websocket.send_bytes(message)
logger.info(f"Received bytes: {message[:100]}")
except Exception as e:
logger.error(f"Server->Client error: {e}")
raise
await asyncio.gather(
forward_client_to_server(),
forward_server_to_client()
)
except WebSocketDisconnect:
logger.info("Client disconnected")
except Exception as e:
logger.error(f"WebSocket error: {str(e)}")
await websocket.close()
if __name__ == "__main__":
uvicorn.run("fun:app", host="0.0.0.0", port=8000, reload=True) |