@push.rocks/smartproxy 19.5.10 → 19.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import * as plugins from '../../plugins.js';
2
2
  import { ForwardingHandler } from './base-handler.js';
3
3
  import type { IForwardConfig } from '../config/forwarding-types.js';
4
4
  import { ForwardingHandlerEvents } from '../config/forwarding-types.js';
5
- import { createIndependentSocketHandlers, setupSocketHandlers } from '../../core/utils/socket-utils.js';
5
+ import { createIndependentSocketHandlers, setupSocketHandlers, createSocketWithErrorHandler } from '../../core/utils/socket-utils.js';
6
6
 
7
7
  /**
8
8
  * Handler for HTTPS passthrough (SNI forwarding without termination)
@@ -48,91 +48,122 @@ export class HttpsPassthroughHandler extends ForwardingHandler {
48
48
  target: `${target.host}:${target.port}`
49
49
  });
50
50
 
51
- // Create a connection to the target server
52
- const serverSocket = plugins.net.connect(target.port, target.host);
53
-
54
51
  // Track data transfer for logging
55
52
  let bytesSent = 0;
56
53
  let bytesReceived = 0;
54
+ let serverSocket: plugins.net.Socket | null = null;
55
+ let cleanupClient: ((reason: string) => Promise<void>) | null = null;
56
+ let cleanupServer: ((reason: string) => Promise<void>) | null = null;
57
57
 
58
- // Create independent handlers for half-open connection support
59
- const { cleanupClient, cleanupServer } = createIndependentSocketHandlers(
60
- clientSocket,
61
- serverSocket,
62
- (reason) => {
58
+ // Create a connection to the target server with immediate error handling
59
+ serverSocket = createSocketWithErrorHandler({
60
+ port: target.port,
61
+ host: target.host,
62
+ onError: async (error) => {
63
+ // Server connection failed - clean up client socket immediately
64
+ this.emit(ForwardingHandlerEvents.ERROR, {
65
+ error: error.message,
66
+ code: (error as any).code || 'UNKNOWN',
67
+ remoteAddress,
68
+ target: `${target.host}:${target.port}`
69
+ });
70
+
71
+ // Clean up the client socket since we can't forward
72
+ if (!clientSocket.destroyed) {
73
+ clientSocket.destroy();
74
+ }
75
+
63
76
  this.emit(ForwardingHandlerEvents.DISCONNECTED, {
64
77
  remoteAddress,
65
- bytesSent,
66
- bytesReceived,
67
- reason
78
+ bytesSent: 0,
79
+ bytesReceived: 0,
80
+ reason: `server_connection_failed: ${error.message}`
68
81
  });
69
- }
70
- );
71
-
72
- // Setup handlers with custom timeout handling that doesn't close connections
73
- const timeout = this.getTimeout();
74
-
75
- setupSocketHandlers(clientSocket, cleanupClient, (socket) => {
76
- // Just reset timeout, don't close
77
- socket.setTimeout(timeout);
78
- }, 'client');
79
-
80
- setupSocketHandlers(serverSocket, cleanupServer, (socket) => {
81
- // Just reset timeout, don't close
82
- socket.setTimeout(timeout);
83
- }, 'server');
84
-
85
- // Forward data from client to server
86
- clientSocket.on('data', (data) => {
87
- bytesSent += data.length;
88
-
89
- // Check if server socket is writable
90
- if (serverSocket.writable) {
91
- const flushed = serverSocket.write(data);
82
+ },
83
+ onConnect: () => {
84
+ // Connection successful - set up forwarding handlers
85
+ const handlers = createIndependentSocketHandlers(
86
+ clientSocket,
87
+ serverSocket!,
88
+ (reason) => {
89
+ this.emit(ForwardingHandlerEvents.DISCONNECTED, {
90
+ remoteAddress,
91
+ bytesSent,
92
+ bytesReceived,
93
+ reason
94
+ });
95
+ }
96
+ );
97
+
98
+ cleanupClient = handlers.cleanupClient;
99
+ cleanupServer = handlers.cleanupServer;
92
100
 
93
- // Handle backpressure
94
- if (!flushed) {
95
- clientSocket.pause();
96
- serverSocket.once('drain', () => {
97
- clientSocket.resume();
101
+ // Setup handlers with custom timeout handling that doesn't close connections
102
+ const timeout = this.getTimeout();
103
+
104
+ setupSocketHandlers(clientSocket, cleanupClient, (socket) => {
105
+ // Just reset timeout, don't close
106
+ socket.setTimeout(timeout);
107
+ }, 'client');
108
+
109
+ setupSocketHandlers(serverSocket!, cleanupServer, (socket) => {
110
+ // Just reset timeout, don't close
111
+ socket.setTimeout(timeout);
112
+ }, 'server');
113
+
114
+ // Forward data from client to server
115
+ clientSocket.on('data', (data) => {
116
+ bytesSent += data.length;
117
+
118
+ // Check if server socket is writable
119
+ if (serverSocket && serverSocket.writable) {
120
+ const flushed = serverSocket.write(data);
121
+
122
+ // Handle backpressure
123
+ if (!flushed) {
124
+ clientSocket.pause();
125
+ serverSocket.once('drain', () => {
126
+ clientSocket.resume();
127
+ });
128
+ }
129
+ }
130
+
131
+ this.emit(ForwardingHandlerEvents.DATA_FORWARDED, {
132
+ direction: 'outbound',
133
+ bytes: data.length,
134
+ total: bytesSent
98
135
  });
99
- }
100
- }
101
-
102
- this.emit(ForwardingHandlerEvents.DATA_FORWARDED, {
103
- direction: 'outbound',
104
- bytes: data.length,
105
- total: bytesSent
106
- });
107
- });
108
-
109
- // Forward data from server to client
110
- serverSocket.on('data', (data) => {
111
- bytesReceived += data.length;
112
-
113
- // Check if client socket is writable
114
- if (clientSocket.writable) {
115
- const flushed = clientSocket.write(data);
136
+ });
116
137
 
117
- // Handle backpressure
118
- if (!flushed) {
119
- serverSocket.pause();
120
- clientSocket.once('drain', () => {
121
- serverSocket.resume();
138
+ // Forward data from server to client
139
+ serverSocket!.on('data', (data) => {
140
+ bytesReceived += data.length;
141
+
142
+ // Check if client socket is writable
143
+ if (clientSocket.writable) {
144
+ const flushed = clientSocket.write(data);
145
+
146
+ // Handle backpressure
147
+ if (!flushed) {
148
+ serverSocket!.pause();
149
+ clientSocket.once('drain', () => {
150
+ serverSocket!.resume();
151
+ });
152
+ }
153
+ }
154
+
155
+ this.emit(ForwardingHandlerEvents.DATA_FORWARDED, {
156
+ direction: 'inbound',
157
+ bytes: data.length,
158
+ total: bytesReceived
122
159
  });
123
- }
160
+ });
161
+
162
+ // Set initial timeouts - they will be reset on each timeout event
163
+ clientSocket.setTimeout(timeout);
164
+ serverSocket!.setTimeout(timeout);
124
165
  }
125
-
126
- this.emit(ForwardingHandlerEvents.DATA_FORWARDED, {
127
- direction: 'inbound',
128
- bytes: data.length,
129
- total: bytesReceived
130
- });
131
166
  });
132
-
133
- // Set initial timeouts - they will be reset on each timeout event
134
- clientSocket.setTimeout(timeout);
135
- serverSocket.setTimeout(timeout);
136
167
  }
137
168
 
138
169
  /**
@@ -2,7 +2,7 @@ import * as plugins from '../../plugins.js';
2
2
  import { ForwardingHandler } from './base-handler.js';
3
3
  import type { IForwardConfig } from '../config/forwarding-types.js';
4
4
  import { ForwardingHandlerEvents } from '../config/forwarding-types.js';
5
- import { createSocketCleanupHandler, setupSocketHandlers } from '../../core/utils/socket-utils.js';
5
+ import { createSocketCleanupHandler, setupSocketHandlers, createSocketWithErrorHandler } from '../../core/utils/socket-utils.js';
6
6
 
7
7
  /**
8
8
  * Handler for HTTPS termination with HTTP backend
@@ -141,19 +141,41 @@ export class HttpsTerminateToHttpHandler extends ForwardingHandler {
141
141
  if (dataBuffer.includes(Buffer.from('\r\n\r\n')) && !connectionEstablished) {
142
142
  const target = this.getTargetFromConfig();
143
143
 
144
- // Create backend connection
145
- backendSocket = plugins.net.connect(target.port, target.host, () => {
146
- connectionEstablished = true;
147
-
148
- // Send buffered data
149
- if (dataBuffer.length > 0) {
150
- backendSocket!.write(dataBuffer);
151
- dataBuffer = Buffer.alloc(0);
144
+ // Create backend connection with immediate error handling
145
+ backendSocket = createSocketWithErrorHandler({
146
+ port: target.port,
147
+ host: target.host,
148
+ onError: (error) => {
149
+ this.emit(ForwardingHandlerEvents.ERROR, {
150
+ error: error.message,
151
+ code: (error as any).code || 'UNKNOWN',
152
+ remoteAddress,
153
+ target: `${target.host}:${target.port}`
154
+ });
155
+
156
+ // Clean up the TLS socket since we can't forward
157
+ if (!tlsSocket.destroyed) {
158
+ tlsSocket.destroy();
159
+ }
160
+
161
+ this.emit(ForwardingHandlerEvents.DISCONNECTED, {
162
+ remoteAddress,
163
+ reason: `backend_connection_failed: ${error.message}`
164
+ });
165
+ },
166
+ onConnect: () => {
167
+ connectionEstablished = true;
168
+
169
+ // Send buffered data
170
+ if (dataBuffer.length > 0) {
171
+ backendSocket!.write(dataBuffer);
172
+ dataBuffer = Buffer.alloc(0);
173
+ }
174
+
175
+ // Set up bidirectional data flow
176
+ tlsSocket.pipe(backendSocket!);
177
+ backendSocket!.pipe(tlsSocket);
152
178
  }
153
-
154
- // Set up bidirectional data flow
155
- tlsSocket.pipe(backendSocket!);
156
- backendSocket!.pipe(tlsSocket);
157
179
  });
158
180
 
159
181
  // Update the cleanup handler with the backend socket
@@ -2,7 +2,7 @@ import * as plugins from '../../plugins.js';
2
2
  import { ForwardingHandler } from './base-handler.js';
3
3
  import type { IForwardConfig } from '../config/forwarding-types.js';
4
4
  import { ForwardingHandlerEvents } from '../config/forwarding-types.js';
5
- import { createSocketCleanupHandler, setupSocketHandlers } from '../../core/utils/socket-utils.js';
5
+ import { createSocketCleanupHandler, setupSocketHandlers, createSocketWithErrorHandler } from '../../core/utils/socket-utils.js';
6
6
 
7
7
  /**
8
8
  * Handler for HTTPS termination with HTTPS backend