feat(socket-utils): implement socket cleanup utilities and enhance socket handling in forwarding handlers
This commit is contained in:
96
ts/core/utils/socket-utils.ts
Normal file
96
ts/core/utils/socket-utils.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import * as plugins from '../../plugins.js';
|
||||
|
||||
/**
|
||||
* Safely cleanup a socket by removing all listeners and destroying it
|
||||
* @param socket The socket to cleanup
|
||||
* @param socketName Optional name for logging
|
||||
*/
|
||||
export function cleanupSocket(socket: plugins.net.Socket | plugins.tls.TLSSocket | null, socketName?: string): void {
|
||||
if (!socket) return;
|
||||
|
||||
try {
|
||||
// Remove all event listeners
|
||||
socket.removeAllListeners();
|
||||
|
||||
// Unpipe any streams
|
||||
socket.unpipe();
|
||||
|
||||
// Destroy if not already destroyed
|
||||
if (!socket.destroyed) {
|
||||
socket.destroy();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Error cleaning up socket${socketName ? ` (${socketName})` : ''}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a cleanup handler for paired sockets (client and server)
|
||||
* @param clientSocket The client socket
|
||||
* @param serverSocket The server socket (optional)
|
||||
* @param onCleanup Optional callback when cleanup is done
|
||||
* @returns A cleanup function that can be called multiple times safely
|
||||
*/
|
||||
export function createSocketCleanupHandler(
|
||||
clientSocket: plugins.net.Socket | plugins.tls.TLSSocket,
|
||||
serverSocket?: plugins.net.Socket | plugins.tls.TLSSocket | null,
|
||||
onCleanup?: (reason: string) => void
|
||||
): (reason: string) => void {
|
||||
let cleanedUp = false;
|
||||
|
||||
return (reason: string) => {
|
||||
if (cleanedUp) return;
|
||||
cleanedUp = true;
|
||||
|
||||
// Cleanup both sockets
|
||||
cleanupSocket(clientSocket, 'client');
|
||||
if (serverSocket) {
|
||||
cleanupSocket(serverSocket, 'server');
|
||||
}
|
||||
|
||||
// Call cleanup callback if provided
|
||||
if (onCleanup) {
|
||||
onCleanup(reason);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup socket error and close handlers with proper cleanup
|
||||
* @param socket The socket to setup handlers for
|
||||
* @param handleClose The cleanup function to call
|
||||
* @param errorPrefix Optional prefix for error messages
|
||||
*/
|
||||
export function setupSocketHandlers(
|
||||
socket: plugins.net.Socket | plugins.tls.TLSSocket,
|
||||
handleClose: (reason: string) => void,
|
||||
errorPrefix?: string
|
||||
): void {
|
||||
socket.on('error', (error) => {
|
||||
const prefix = errorPrefix || 'Socket';
|
||||
handleClose(`${prefix}_error: ${error.message}`);
|
||||
});
|
||||
|
||||
socket.on('close', () => {
|
||||
const prefix = errorPrefix || 'socket';
|
||||
handleClose(`${prefix}_closed`);
|
||||
});
|
||||
|
||||
socket.on('timeout', () => {
|
||||
const prefix = errorPrefix || 'socket';
|
||||
handleClose(`${prefix}_timeout`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Pipe two sockets together with proper cleanup on either end
|
||||
* @param socket1 First socket
|
||||
* @param socket2 Second socket
|
||||
*/
|
||||
export function pipeSockets(
|
||||
socket1: plugins.net.Socket | plugins.tls.TLSSocket,
|
||||
socket2: plugins.net.Socket | plugins.tls.TLSSocket
|
||||
): void {
|
||||
socket1.pipe(socket2);
|
||||
socket2.pipe(socket1);
|
||||
}
|
Reference in New Issue
Block a user