import {ProxyError} from './policy'; import {renderRelayEndpoint, type RenderConfig} from './render'; // Browser sessions authenticate at the Worker. Only the Worker sends the private // relay header; browser cookies and arbitrary client headers never reach Render. export async function renderWispUpgrade(request: Request, env: RenderConfig): Promise { if(request.method!=='GET'||request.headers.get('upgrade')?.toLowerCase()!=='websocket') throw new ProxyError(426,'WEBSOCKET_REQUIRED','Wisp requires a WebSocket connection.'); const endpoint=renderRelayEndpoint(env); if(!endpoint)throw new ProxyError(503,'RENDER_CONFIG','Configure the private Render relay first.'); endpoint.pathname='/wisp/'; const headers=new Headers({Upgrade:'websocket','x-relay-token':env.RELAY_SHARED_SECRET!}); const protocol=request.headers.get('sec-websocket-protocol'); if(protocol)headers.set('sec-websocket-protocol',protocol); const response=await fetch(endpoint,{headers,redirect:'manual'}); if(response.status!==101){ await response.body?.cancel(); throw new ProxyError(502,'WISP_UNAVAILABLE','The hosted Wisp relay did not accept the connection.'); } return response; }