fix(proxy): close connection buildup vectors in HTTP idle, WebSocket, socket relay, and TLS forwarding paths
- Add HTTP keep-alive idle timeout (60s default) with periodic watchdog that skips active requests (panic-safe via RAII ActiveRequestGuard) - Make WebSocket inactivity/max-lifetime timeouts configurable from ConnectionConfig instead of hardcoded 1h/24h - Replace bare copy_bidirectional in socket handler relay with timeout+cancel-aware split forwarding (inactivity, max lifetime, graceful shutdown) - Add CancellationToken to forward_bidirectional_split_with_timeouts so TLS-terminated TCP connections respond to graceful shutdown - Fix graceful_stop to actually abort listener tasks that exceed the shutdown deadline (previously they detached and ran forever) - Add 10s metadata parsing timeout on TS socket-handler-server to prevent stuck sockets
This commit is contained in:
@@ -92,6 +92,16 @@ export class SocketHandlerServer {
|
||||
let metadataBuffer = '';
|
||||
let metadataParsed = false;
|
||||
|
||||
// 10s timeout for metadata parsing phase — if Rust connects but never
|
||||
// sends the JSON metadata line, don't hold the socket open indefinitely.
|
||||
socket.setTimeout(10_000);
|
||||
socket.on('timeout', () => {
|
||||
if (!metadataParsed) {
|
||||
logger.log('warn', 'Socket handler metadata timeout, closing', { component: 'socket-handler-server' });
|
||||
socket.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
const onData = (chunk: Buffer) => {
|
||||
if (metadataParsed) return;
|
||||
|
||||
@@ -108,6 +118,7 @@ export class SocketHandlerServer {
|
||||
}
|
||||
|
||||
metadataParsed = true;
|
||||
socket.setTimeout(0); // Clear metadata timeout
|
||||
socket.removeListener('data', onData);
|
||||
socket.pause(); // Prevent data loss between handler removal and pipe setup
|
||||
|
||||
|
||||
Reference in New Issue
Block a user