fix(phase3): fix filebrowser tab url, implement nabil session.create/prompt.submit rpc, and fix dsh websocket same-origin bridge
This commit is contained in:
+27
-13
@@ -1,5 +1,6 @@
|
||||
import httpx
|
||||
import re
|
||||
import socket
|
||||
import asyncio
|
||||
from typing import AsyncGenerator, Dict, Any, Optional, List, Tuple
|
||||
from fastapi import Request, Response, WebSocket, WebSocketDisconnect
|
||||
@@ -30,7 +31,9 @@ WS_HOP_BY_HOP_HEADERS = {
|
||||
"sec-websocket-extensions",
|
||||
"sec-websocket-accept",
|
||||
"host",
|
||||
"origin"
|
||||
"origin",
|
||||
"sec-fetch-site",
|
||||
"sec-fetch-mode"
|
||||
}
|
||||
|
||||
_http_transport: Optional[httpx.AsyncHTTPTransport] = None
|
||||
@@ -98,14 +101,15 @@ async def proxy_request(
|
||||
k_str = raw_k.decode("latin-1").lower()
|
||||
if k_str in HOP_BY_HOP_HEADERS or k_str == "host":
|
||||
continue
|
||||
if is_dsh and k_str == "origin":
|
||||
if is_dsh and k_str in ("origin", "sec-fetch-site"):
|
||||
continue
|
||||
req_headers.append((raw_k, raw_v))
|
||||
|
||||
# If DSH backend, replicate localhost:3080 Host/Origin for internal origin check
|
||||
# If DSH backend, replicate localhost:3080 Host/Origin and same-origin site
|
||||
if is_dsh:
|
||||
req_headers.append((b"host", b"localhost:3080"))
|
||||
req_headers.append((b"origin", b"http://localhost:3080"))
|
||||
req_headers.append((b"sec-fetch-site", b"same-origin"))
|
||||
else:
|
||||
req_headers.append((b"x-forwarded-host", request.headers.get("host", "").encode("latin-1")))
|
||||
|
||||
@@ -180,13 +184,7 @@ async def proxy_websocket(
|
||||
path: str,
|
||||
universe_id: Optional[str] = None
|
||||
):
|
||||
ws_base = backend_url.replace("https://", "wss://").replace("http://", "ws://").rstrip("/")
|
||||
sub_path = path.lstrip("/")
|
||||
upstream_url = f"{ws_base}/{sub_path}" if sub_path else ws_base
|
||||
|
||||
if client_ws.url.query:
|
||||
upstream_url = f"{upstream_url}?{client_ws.url.query}"
|
||||
|
||||
is_dsh = "dsh-vps:3080" in backend_url or universe_id == "dsh"
|
||||
|
||||
upstream_headers = {}
|
||||
@@ -194,10 +192,27 @@ async def proxy_websocket(
|
||||
if k.lower() not in WS_HOP_BY_HOP_HEADERS:
|
||||
upstream_headers[k] = v
|
||||
|
||||
subprotocols_raw = client_ws.headers.get("sec-websocket-protocol", "")
|
||||
subprotocols = [s.strip() for s in subprotocols_raw.split(",") if s.strip()] or None
|
||||
|
||||
sock = None
|
||||
if is_dsh:
|
||||
upstream_headers["host"] = "localhost:3080"
|
||||
# DSH requires exact Host: localhost:3080, Origin: http://localhost:3080 and Sec-Fetch-Site: same-origin
|
||||
upstream_headers["Sec-Fetch-Site"] = "same-origin"
|
||||
upstream_url = f"ws://localhost:3080/{sub_path}" if sub_path else "ws://localhost:3080"
|
||||
if client_ws.url.query:
|
||||
upstream_url = f"{upstream_url}?{client_ws.url.query}"
|
||||
|
||||
# Connect raw socket directly to dsh-vps:3080
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect(("dsh-vps", 3080))
|
||||
sock.setblocking(False)
|
||||
origin_val = "http://localhost:3080"
|
||||
else:
|
||||
ws_base = backend_url.replace("https://", "wss://").replace("http://", "ws://").rstrip("/")
|
||||
upstream_url = f"{ws_base}/{sub_path}" if sub_path else ws_base
|
||||
if client_ws.url.query:
|
||||
upstream_url = f"{upstream_url}?{client_ws.url.query}"
|
||||
upstream_headers["x-forwarded-host"] = client_ws.headers.get("host", "")
|
||||
upstream_headers["x-forwarded-proto"] = client_ws.url.scheme or "http"
|
||||
origin_val = None
|
||||
@@ -205,9 +220,6 @@ async def proxy_websocket(
|
||||
if client_ws.client:
|
||||
upstream_headers["x-forwarded-for"] = client_ws.client.host
|
||||
|
||||
subprotocols_raw = client_ws.headers.get("sec-websocket-protocol", "")
|
||||
subprotocols = [s.strip() for s in subprotocols_raw.split(",") if s.strip()] or None
|
||||
|
||||
try:
|
||||
connect_kwargs = {
|
||||
"additional_headers": upstream_headers,
|
||||
@@ -216,6 +228,8 @@ async def proxy_websocket(
|
||||
"ping_timeout": 20,
|
||||
"max_size": 10 * 1024 * 1024
|
||||
}
|
||||
if sock:
|
||||
connect_kwargs["sock"] = sock
|
||||
if origin_val:
|
||||
connect_kwargs["origin"] = origin_val
|
||||
|
||||
|
||||
Reference in New Issue
Block a user