From 8207b78b36ecf36eb969da6d8265b24be8115000 Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Fri, 13 Mar 2026 23:28:54 -0400 Subject: [PATCH] fix: hijack upgrade event before WsAdapter can consume the socket WsAdapter registered its upgrade handler first and destroyed sockets for non-matching paths. Now we remove all existing upgrade listeners, install ours first, and forward non-terminal/sftp upgrades to the original WsAdapter handlers for RDP. Co-Authored-By: Claude Opus 4.6 --- backend/src/main.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/backend/src/main.ts b/backend/src/main.ts index d34f544..ebc80f1 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -18,7 +18,6 @@ async function bootstrap() { await app.listen(3000); console.log('Wraith backend running on port 3000'); - // Manual WebSocket handling — bypasses NestJS WsAdapter entirely const server = app.getHttpServer(); const terminalGateway = app.get(TerminalGateway); const sftpGateway = app.get(SftpGateway); @@ -27,30 +26,39 @@ async function bootstrap() { const sftpWss = new WebSocketServer({ noServer: true }); terminalWss.on('connection', (ws, req) => { - console.log(`[WS] Terminal connection from ${req.url}`); + console.log(`[WS] Terminal connection established`); terminalGateway.handleConnection(ws, req); }); sftpWss.on('connection', (ws, req) => { - console.log(`[WS] SFTP connection from ${req.url}`); + console.log(`[WS] SFTP connection established`); sftpGateway.handleConnection(ws, req); }); + // Remove ALL existing upgrade listeners (WsAdapter's) so we handle upgrades first + const existingListeners = server.listeners('upgrade'); + server.removeAllListeners('upgrade'); + + // Our handler runs first — routes terminal/sftp, passes everything else to WsAdapter server.on('upgrade', (req: any, socket: any, head: any) => { const pathname = req.url?.split('?')[0]; - console.log(`[HTTP-UPGRADE] path=${pathname}`); + console.log(`[HTTP-UPGRADE] path=${pathname} socket.destroyed=${socket.destroyed}`); if (pathname === '/api/ws/terminal') { terminalWss.handleUpgrade(req, socket, head, (ws) => { + console.log(`[WS] Terminal upgrade complete`); terminalWss.emit('connection', ws, req); }); } else if (pathname === '/api/ws/sftp') { sftpWss.handleUpgrade(req, socket, head, (ws) => { + console.log(`[WS] SFTP upgrade complete`); sftpWss.emit('connection', ws, req); }); } else { - console.log(`[HTTP-UPGRADE] Unknown WS path: ${pathname}, destroying socket`); - socket.destroy(); + // Pass to WsAdapter's original handlers (for RDP etc) + for (const listener of existingListeners) { + listener.call(server, req, socket, head); + } } }); }