UNPKG

bunnel-server

Version:
98 lines (97 loc) 4.37 kB
export class LocalProxyServer { constructor(securePort, insecurePort) { this.securePort = securePort; this.insecurePort = insecurePort; } start() { // Allow self-signed certificates process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; return Bun.serve({ port: this.insecurePort, fetch: async (req, server) => { try { const url = new URL(req.url); // Check if this is a WebSocket upgrade request const upgradeHeader = req.headers.get('upgrade'); if (upgradeHeader?.toLowerCase() === 'websocket') { // Upgrade the connection and store the URL const success = server.upgrade(req, { data: { url: req.url } }); return success ? new Response() : new Response('WebSocket upgrade failed', { status: 500 }); } // Forward HTTP requests const secureUrl = new URL(`https://localhost:${this.securePort}${url.pathname}${url.search}`); const response = await fetch(secureUrl, { method: req.method, headers: req.headers, body: req.body, //@ts-ignore secure: false, redirect: 'follow' }); return new Response(response.body, { status: response.status, statusText: response.statusText, headers: response.headers }); } catch (err) { console.error('Error in proxy server:', err); return new Response('Proxy server error', { status: 500 }); } }, websocket: { open: (ws) => { try { // Create WebSocket connection to secure server with same path const url = new URL(ws.data.url || ''); const secureWs = new WebSocket(`wss://localhost:${this.securePort}${url.pathname}${url.search}`); // Wait for secure connection to be established secureWs.onopen = () => { // Forward messages from secure server to client secureWs.onmessage = (event) => { if (ws.readyState === WebSocket.OPEN) { ws.send(event.data); } }; // Store secure WebSocket in data ws.data.secureWs = secureWs; }; // Handle connection errors secureWs.onerror = (error) => { console.error('Secure WebSocket connection error:', error); ws.close(); }; } catch (err) { console.error('Error establishing secure WebSocket connection:', err); ws.close(); } }, message: (ws, message) => { try { // Forward messages from client to secure server const secureWs = ws.data.secureWs; if (secureWs?.readyState === WebSocket.OPEN) { secureWs.send(message); } } catch (err) { console.error('Error forwarding message:', err); ws.close(); } }, close: (ws) => { try { // Close secure WebSocket when client disconnects ws.data.secureWs?.close(); } catch (err) { console.error('Error closing secure WebSocket:', err); } } } }); } }