|
from fastapi import FastAPI, Request, Response, WebSocket, WebSocketDisconnect |
|
import httpx |
|
import uvicorn |
|
import asyncio |
|
import websockets |
|
import logging |
|
import json |
|
|
|
app = FastAPI() |
|
|
|
TARGET_BASE = "http://127.0.0.1:9222" |
|
TARGET_WS_BASE = "ws://127.0.0.1:9222" |
|
|
|
|
|
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" |
|
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 to: {target_url}") |
|
|
|
try: |
|
async with websockets.connect(target_url) as target_ws: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def forward_client_to_server(): |
|
try: |
|
while True: |
|
data = await websocket.receive_text() |
|
logger.info(f"CLIENT->CHROME: {data[:200]}") |
|
await target_ws.send(data) |
|
except WebSocketDisconnect: |
|
logger.info("Client disconnected") |
|
|
|
async def forward_server_to_client(): |
|
try: |
|
while True: |
|
response = await target_ws.recv() |
|
logger.info(f"CHROME->CLIENT: {response[:200]}") |
|
await websocket.send_text(response) |
|
except websockets.exceptions.ConnectionClosed: |
|
logger.info("Browser disconnected") |
|
|
|
await asyncio.gather( |
|
forward_client_to_server(), |
|
forward_server_to_client() |
|
) |
|
except Exception as e: |
|
logger.error(f"Error: {e}") |
|
finally: |
|
await websocket.close() |
|
|
|
|
|
if __name__ == "__main__": |
|
uvicorn.run("fun:app", host="0.0.0.0", port=8000, reload=True) |