Spaces:
BG5
/
Running

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)