Compare commits

...

2 Commits

Author SHA1 Message Date
8d2d76256f 18.1.1
Some checks failed
Default (tags) / security (push) Successful in 40s
Default (tags) / test (push) Failing after 1h12m40s
Default (tags) / release (push) Has been cancelled
Default (tags) / metadata (push) Has been cancelled
2025-05-15 20:08:18 +00:00
1a038f001f fix(network-proxy/websocket): Improve WebSocket connection closure and update router integration 2025-05-15 20:08:18 +00:00
6 changed files with 34 additions and 8 deletions

View File

@ -1,5 +1,12 @@
# Changelog
## 2025-05-15 - 18.1.1 - fix(network-proxy/websocket)
Improve WebSocket connection closure and update router integration
- Wrap WS close logic in try-catch blocks to ensure valid close codes are used for both incoming and outgoing WebSocket connections
- Use explicit numeric close codes (defaulting to 1000 when unavailable) to prevent improper socket termination
- Update NetworkProxy updateRoutes to also refresh the WebSocket handler routes for consistent configuration
## 2025-05-15 - 18.1.0 - feat(nftables)
Add NFTables integration for kernel-level forwarding and update documentation, tests, and helper functions

View File

@ -1,6 +1,6 @@
{
"name": "@push.rocks/smartproxy",
"version": "18.1.0",
"version": "18.1.1",
"private": false,
"description": "A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.",
"main": "dist_ts/index.js",

View File

@ -238,6 +238,10 @@ tap.test('should start the proxy server', async () => {
},
tls: {
mode: 'terminate'
},
websocket: {
enabled: true,
subprotocols: ['echo-protocol']
}
}
}

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartproxy',
version: '18.1.0',
version: '18.1.1',
description: 'A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.'
}

View File

@ -500,6 +500,9 @@ export class NetworkProxy implements IMetricsTracker {
this.logger.warn('Router has no recognized configuration method');
}
// Update WebSocket handler with new routes
this.webSocketHandler.setRoutes(routes);
this.logger.info(`Route configuration updated with ${routes.length} routes and ${legacyConfigs.length} proxy configs`);
}

View File

@ -419,9 +419,15 @@ export class WebSocketHandler {
wsIncoming.on('close', (code, reason) => {
this.logger.debug(`WebSocket client connection closed: ${code} ${reason}`);
if (wsOutgoing.readyState === wsOutgoing.OPEN) {
const validCode = code || 1000;
const reasonString = toBuffer(reason).toString();
wsOutgoing.close(validCode, reasonString);
// Ensure code is a valid WebSocket close code number
const validCode = typeof code === 'number' && code >= 1000 && code <= 4999 ? code : 1000;
try {
const reasonString = reason ? toBuffer(reason).toString() : '';
wsOutgoing.close(validCode, reasonString);
} catch (err) {
this.logger.error('Error closing wsOutgoing:', err);
wsOutgoing.close(validCode);
}
}
// Clean up timers
@ -432,9 +438,15 @@ export class WebSocketHandler {
wsOutgoing.on('close', (code, reason) => {
this.logger.debug(`WebSocket target connection closed: ${code} ${reason}`);
if (wsIncoming.readyState === wsIncoming.OPEN) {
const validCode = code || 1000;
const reasonString = toBuffer(reason).toString();
wsIncoming.close(validCode, reasonString);
// Ensure code is a valid WebSocket close code number
const validCode = typeof code === 'number' && code >= 1000 && code <= 4999 ? code : 1000;
try {
const reasonString = reason ? toBuffer(reason).toString() : '';
wsIncoming.close(validCode, reasonString);
} catch (err) {
this.logger.error('Error closing wsIncoming:', err);
wsIncoming.close(validCode);
}
}
// Clean up timers