@push.rocks/smartproxy 25.17.10 → 26.1.0

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.
Files changed (184) hide show
  1. package/changelog.md +15 -0
  2. package/dist_rust/rustproxy_linux_amd64 +0 -0
  3. package/dist_rust/rustproxy_linux_arm64 +0 -0
  4. package/dist_ts/00_commitinfo_data.js +2 -2
  5. package/dist_ts/core/index.d.ts +0 -1
  6. package/dist_ts/core/index.js +1 -2
  7. package/dist_ts/core/models/index.d.ts +0 -1
  8. package/dist_ts/core/models/index.js +1 -2
  9. package/dist_ts/core/utils/index.d.ts +0 -12
  10. package/dist_ts/core/utils/index.js +1 -13
  11. package/dist_ts/index.d.ts +0 -3
  12. package/dist_ts/index.js +2 -7
  13. package/dist_ts/protocols/http/index.d.ts +0 -1
  14. package/dist_ts/protocols/http/index.js +1 -2
  15. package/dist_ts/protocols/index.d.ts +0 -7
  16. package/dist_ts/protocols/index.js +1 -8
  17. package/dist_ts/proxies/smart-proxy/models/metrics-types.d.ts +20 -0
  18. package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.d.ts +2 -1
  19. package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.js +4 -1
  20. package/dist_ts/proxies/smart-proxy/socket-handler-server.js +6 -1
  21. package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.d.ts +0 -7
  22. package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.js +50 -51
  23. package/dist_ts/routing/index.d.ts +0 -1
  24. package/dist_ts/routing/index.js +1 -3
  25. package/package.json +1 -1
  26. package/ts/00_commitinfo_data.ts +1 -1
  27. package/ts/core/index.ts +0 -1
  28. package/ts/core/models/index.ts +0 -1
  29. package/ts/core/utils/index.ts +0 -12
  30. package/ts/index.ts +1 -7
  31. package/ts/protocols/http/index.ts +1 -2
  32. package/ts/protocols/index.ts +0 -7
  33. package/ts/proxies/smart-proxy/models/metrics-types.ts +21 -0
  34. package/ts/proxies/smart-proxy/rust-metrics-adapter.ts +4 -1
  35. package/ts/proxies/smart-proxy/socket-handler-server.ts +6 -0
  36. package/ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.ts +60 -59
  37. package/ts/routing/index.ts +0 -3
  38. package/dist_ts/core/events/index.d.ts +0 -4
  39. package/dist_ts/core/events/index.js +0 -5
  40. package/dist_ts/core/models/socket-augmentation.d.ts +0 -15
  41. package/dist_ts/core/models/socket-augmentation.js +0 -18
  42. package/dist_ts/core/utils/async-utils.d.ts +0 -81
  43. package/dist_ts/core/utils/async-utils.js +0 -216
  44. package/dist_ts/core/utils/binary-heap.d.ts +0 -73
  45. package/dist_ts/core/utils/binary-heap.js +0 -193
  46. package/dist_ts/core/utils/enhanced-connection-pool.d.ts +0 -110
  47. package/dist_ts/core/utils/enhanced-connection-pool.js +0 -325
  48. package/dist_ts/core/utils/fs-utils.d.ts +0 -144
  49. package/dist_ts/core/utils/fs-utils.js +0 -252
  50. package/dist_ts/core/utils/ip-utils.d.ts +0 -69
  51. package/dist_ts/core/utils/ip-utils.js +0 -270
  52. package/dist_ts/core/utils/lifecycle-component.d.ts +0 -59
  53. package/dist_ts/core/utils/lifecycle-component.js +0 -211
  54. package/dist_ts/core/utils/log-deduplicator.d.ts +0 -39
  55. package/dist_ts/core/utils/log-deduplicator.js +0 -305
  56. package/dist_ts/core/utils/security-utils.d.ts +0 -111
  57. package/dist_ts/core/utils/security-utils.js +0 -212
  58. package/dist_ts/core/utils/shared-security-manager.d.ts +0 -128
  59. package/dist_ts/core/utils/shared-security-manager.js +0 -362
  60. package/dist_ts/core/utils/socket-utils.d.ts +0 -63
  61. package/dist_ts/core/utils/socket-utils.js +0 -249
  62. package/dist_ts/core/utils/template-utils.d.ts +0 -37
  63. package/dist_ts/core/utils/template-utils.js +0 -104
  64. package/dist_ts/core/utils/validation-utils.d.ts +0 -61
  65. package/dist_ts/core/utils/validation-utils.js +0 -149
  66. package/dist_ts/core/utils/websocket-utils.d.ts +0 -22
  67. package/dist_ts/core/utils/websocket-utils.js +0 -30
  68. package/dist_ts/detection/detectors/http-detector.d.ts +0 -33
  69. package/dist_ts/detection/detectors/http-detector.js +0 -101
  70. package/dist_ts/detection/detectors/quick-detector.d.ts +0 -28
  71. package/dist_ts/detection/detectors/quick-detector.js +0 -131
  72. package/dist_ts/detection/detectors/routing-extractor.d.ts +0 -28
  73. package/dist_ts/detection/detectors/routing-extractor.js +0 -122
  74. package/dist_ts/detection/detectors/tls-detector.d.ts +0 -47
  75. package/dist_ts/detection/detectors/tls-detector.js +0 -183
  76. package/dist_ts/detection/index.d.ts +0 -17
  77. package/dist_ts/detection/index.js +0 -22
  78. package/dist_ts/detection/models/detection-types.d.ts +0 -87
  79. package/dist_ts/detection/models/detection-types.js +0 -5
  80. package/dist_ts/detection/models/interfaces.d.ts +0 -97
  81. package/dist_ts/detection/models/interfaces.js +0 -5
  82. package/dist_ts/detection/protocol-detector.d.ts +0 -79
  83. package/dist_ts/detection/protocol-detector.js +0 -253
  84. package/dist_ts/detection/utils/buffer-utils.d.ts +0 -61
  85. package/dist_ts/detection/utils/buffer-utils.js +0 -127
  86. package/dist_ts/detection/utils/fragment-manager.d.ts +0 -31
  87. package/dist_ts/detection/utils/fragment-manager.js +0 -53
  88. package/dist_ts/detection/utils/parser-utils.d.ts +0 -42
  89. package/dist_ts/detection/utils/parser-utils.js +0 -63
  90. package/dist_ts/protocols/common/fragment-handler.d.ts +0 -73
  91. package/dist_ts/protocols/common/fragment-handler.js +0 -121
  92. package/dist_ts/protocols/common/index.d.ts +0 -7
  93. package/dist_ts/protocols/common/index.js +0 -8
  94. package/dist_ts/protocols/common/types.d.ts +0 -68
  95. package/dist_ts/protocols/common/types.js +0 -7
  96. package/dist_ts/protocols/http/parser.d.ts +0 -58
  97. package/dist_ts/protocols/http/parser.js +0 -184
  98. package/dist_ts/protocols/proxy/index.d.ts +0 -5
  99. package/dist_ts/protocols/proxy/index.js +0 -6
  100. package/dist_ts/protocols/proxy/types.d.ts +0 -47
  101. package/dist_ts/protocols/proxy/types.js +0 -6
  102. package/dist_ts/protocols/tls/alerts/index.d.ts +0 -4
  103. package/dist_ts/protocols/tls/alerts/index.js +0 -5
  104. package/dist_ts/protocols/tls/alerts/tls-alert.d.ts +0 -150
  105. package/dist_ts/protocols/tls/alerts/tls-alert.js +0 -226
  106. package/dist_ts/protocols/tls/index.d.ts +0 -12
  107. package/dist_ts/protocols/tls/index.js +0 -27
  108. package/dist_ts/protocols/tls/sni/client-hello-parser.d.ts +0 -100
  109. package/dist_ts/protocols/tls/sni/client-hello-parser.js +0 -463
  110. package/dist_ts/protocols/tls/sni/index.d.ts +0 -5
  111. package/dist_ts/protocols/tls/sni/index.js +0 -6
  112. package/dist_ts/protocols/tls/sni/sni-extraction.d.ts +0 -58
  113. package/dist_ts/protocols/tls/sni/sni-extraction.js +0 -275
  114. package/dist_ts/protocols/tls/utils/index.d.ts +0 -4
  115. package/dist_ts/protocols/tls/utils/index.js +0 -5
  116. package/dist_ts/protocols/tls/utils/tls-utils.d.ts +0 -158
  117. package/dist_ts/protocols/tls/utils/tls-utils.js +0 -187
  118. package/dist_ts/protocols/websocket/constants.d.ts +0 -55
  119. package/dist_ts/protocols/websocket/constants.js +0 -58
  120. package/dist_ts/protocols/websocket/index.d.ts +0 -7
  121. package/dist_ts/protocols/websocket/index.js +0 -8
  122. package/dist_ts/protocols/websocket/types.d.ts +0 -47
  123. package/dist_ts/protocols/websocket/types.js +0 -5
  124. package/dist_ts/protocols/websocket/utils.d.ts +0 -25
  125. package/dist_ts/protocols/websocket/utils.js +0 -103
  126. package/dist_ts/routing/router/http-router.d.ts +0 -89
  127. package/dist_ts/routing/router/http-router.js +0 -205
  128. package/dist_ts/routing/router/index.d.ts +0 -5
  129. package/dist_ts/routing/router/index.js +0 -6
  130. package/dist_ts/tls/index.d.ts +0 -16
  131. package/dist_ts/tls/index.js +0 -24
  132. package/dist_ts/tls/sni/index.d.ts +0 -4
  133. package/dist_ts/tls/sni/index.js +0 -5
  134. package/dist_ts/tls/sni/sni-handler.d.ts +0 -154
  135. package/dist_ts/tls/sni/sni-handler.js +0 -191
  136. package/ts/core/events/index.ts +0 -3
  137. package/ts/core/models/socket-augmentation.ts +0 -38
  138. package/ts/core/utils/async-utils.ts +0 -275
  139. package/ts/core/utils/binary-heap.ts +0 -225
  140. package/ts/core/utils/enhanced-connection-pool.ts +0 -425
  141. package/ts/core/utils/fs-utils.ts +0 -270
  142. package/ts/core/utils/ip-utils.ts +0 -303
  143. package/ts/core/utils/lifecycle-component.ts +0 -251
  144. package/ts/core/utils/log-deduplicator.ts +0 -370
  145. package/ts/core/utils/security-utils.ts +0 -305
  146. package/ts/core/utils/shared-security-manager.ts +0 -470
  147. package/ts/core/utils/socket-utils.ts +0 -322
  148. package/ts/core/utils/template-utils.ts +0 -124
  149. package/ts/core/utils/validation-utils.ts +0 -177
  150. package/ts/core/utils/websocket-utils.ts +0 -33
  151. package/ts/detection/detectors/http-detector.ts +0 -127
  152. package/ts/detection/detectors/quick-detector.ts +0 -148
  153. package/ts/detection/detectors/routing-extractor.ts +0 -147
  154. package/ts/detection/detectors/tls-detector.ts +0 -223
  155. package/ts/detection/index.ts +0 -25
  156. package/ts/detection/models/detection-types.ts +0 -102
  157. package/ts/detection/models/interfaces.ts +0 -115
  158. package/ts/detection/protocol-detector.ts +0 -319
  159. package/ts/detection/utils/buffer-utils.ts +0 -141
  160. package/ts/detection/utils/fragment-manager.ts +0 -64
  161. package/ts/detection/utils/parser-utils.ts +0 -77
  162. package/ts/protocols/common/fragment-handler.ts +0 -167
  163. package/ts/protocols/common/index.ts +0 -8
  164. package/ts/protocols/common/types.ts +0 -76
  165. package/ts/protocols/http/parser.ts +0 -219
  166. package/ts/protocols/proxy/index.ts +0 -6
  167. package/ts/protocols/proxy/types.ts +0 -53
  168. package/ts/protocols/tls/alerts/index.ts +0 -3
  169. package/ts/protocols/tls/alerts/tls-alert.ts +0 -259
  170. package/ts/protocols/tls/index.ts +0 -37
  171. package/ts/protocols/tls/sni/client-hello-parser.ts +0 -629
  172. package/ts/protocols/tls/sni/index.ts +0 -6
  173. package/ts/protocols/tls/sni/sni-extraction.ts +0 -353
  174. package/ts/protocols/tls/utils/index.ts +0 -3
  175. package/ts/protocols/tls/utils/tls-utils.ts +0 -201
  176. package/ts/protocols/websocket/constants.ts +0 -60
  177. package/ts/protocols/websocket/index.ts +0 -8
  178. package/ts/protocols/websocket/types.ts +0 -53
  179. package/ts/protocols/websocket/utils.ts +0 -98
  180. package/ts/routing/router/http-router.ts +0 -266
  181. package/ts/routing/router/index.ts +0 -7
  182. package/ts/tls/index.ts +0 -29
  183. package/ts/tls/sni/index.ts +0 -3
  184. package/ts/tls/sni/sni-handler.ts +0 -264
@@ -1,322 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
-
3
- export interface CleanupOptions {
4
- immediate?: boolean; // Force immediate destruction
5
- allowDrain?: boolean; // Allow write buffer to drain
6
- gracePeriod?: number; // Ms to wait before force close
7
- }
8
-
9
- export interface SafeSocketOptions {
10
- port: number;
11
- host: string;
12
- onError?: (error: Error) => void;
13
- onConnect?: () => void;
14
- timeout?: number;
15
- }
16
-
17
- /**
18
- * Safely cleanup a socket by removing all listeners and destroying it
19
- * @param socket The socket to cleanup
20
- * @param socketName Optional name for logging
21
- * @param options Cleanup options
22
- */
23
- export function cleanupSocket(
24
- socket: plugins.net.Socket | plugins.tls.TLSSocket | null,
25
- socketName?: string,
26
- options: CleanupOptions = {}
27
- ): Promise<void> {
28
- if (!socket || socket.destroyed) return Promise.resolve();
29
-
30
- return new Promise<void>((resolve) => {
31
- const cleanup = () => {
32
- try {
33
- // Remove all event listeners
34
- socket.removeAllListeners();
35
-
36
- // Destroy if not already destroyed
37
- if (!socket.destroyed) {
38
- socket.destroy();
39
- }
40
- } catch (err) {
41
- console.error(`Error cleaning up socket${socketName ? ` (${socketName})` : ''}: ${err}`);
42
- }
43
- resolve();
44
- };
45
-
46
- if (options.immediate) {
47
- // Immediate cleanup (old behavior)
48
- socket.unpipe();
49
- cleanup();
50
- } else if (options.allowDrain && socket.writable) {
51
- // Allow pending writes to complete
52
- socket.end(() => cleanup());
53
-
54
- // Force cleanup after grace period
55
- if (options.gracePeriod) {
56
- setTimeout(() => {
57
- if (!socket.destroyed) {
58
- cleanup();
59
- }
60
- }, options.gracePeriod);
61
- }
62
- } else {
63
- // Default: immediate cleanup
64
- socket.unpipe();
65
- cleanup();
66
- }
67
- });
68
- }
69
-
70
-
71
- /**
72
- * Create independent cleanup handlers for paired sockets that support half-open connections
73
- * @param clientSocket The client socket
74
- * @param serverSocket The server socket
75
- * @param onBothClosed Callback when both sockets are closed
76
- * @returns Independent cleanup functions for each socket
77
- */
78
- export function createIndependentSocketHandlers(
79
- clientSocket: plugins.net.Socket | plugins.tls.TLSSocket,
80
- serverSocket: plugins.net.Socket | plugins.tls.TLSSocket,
81
- onBothClosed: (reason: string) => void,
82
- options: { enableHalfOpen?: boolean } = {}
83
- ): { cleanupClient: (reason: string) => Promise<void>, cleanupServer: (reason: string) => Promise<void> } {
84
- let clientClosed = false;
85
- let serverClosed = false;
86
- let clientReason = '';
87
- let serverReason = '';
88
-
89
- const checkBothClosed = () => {
90
- if (clientClosed && serverClosed) {
91
- onBothClosed(`client: ${clientReason}, server: ${serverReason}`);
92
- }
93
- };
94
-
95
- const cleanupClient = async (reason: string) => {
96
- if (clientClosed) return;
97
- clientClosed = true;
98
- clientReason = reason;
99
-
100
- // Default behavior: close both sockets when one closes (required for proxy chains)
101
- if (!serverClosed && !options.enableHalfOpen) {
102
- serverSocket.destroy();
103
- }
104
-
105
- // Half-open support (opt-in only)
106
- if (!serverClosed && serverSocket.writable && options.enableHalfOpen) {
107
- // Half-close: stop reading from client, let server finish
108
- clientSocket.pause();
109
- clientSocket.unpipe(serverSocket);
110
- await cleanupSocket(clientSocket, 'client', { allowDrain: true, gracePeriod: 5000 });
111
- } else {
112
- await cleanupSocket(clientSocket, 'client', { immediate: true });
113
- }
114
-
115
- checkBothClosed();
116
- };
117
-
118
- const cleanupServer = async (reason: string) => {
119
- if (serverClosed) return;
120
- serverClosed = true;
121
- serverReason = reason;
122
-
123
- // Default behavior: close both sockets when one closes (required for proxy chains)
124
- if (!clientClosed && !options.enableHalfOpen) {
125
- clientSocket.destroy();
126
- }
127
-
128
- // Half-open support (opt-in only)
129
- if (!clientClosed && clientSocket.writable && options.enableHalfOpen) {
130
- // Half-close: stop reading from server, let client finish
131
- serverSocket.pause();
132
- serverSocket.unpipe(clientSocket);
133
- await cleanupSocket(serverSocket, 'server', { allowDrain: true, gracePeriod: 5000 });
134
- } else {
135
- await cleanupSocket(serverSocket, 'server', { immediate: true });
136
- }
137
-
138
- checkBothClosed();
139
- };
140
-
141
- return { cleanupClient, cleanupServer };
142
- }
143
-
144
- /**
145
- * Setup socket error and close handlers with proper cleanup
146
- * @param socket The socket to setup handlers for
147
- * @param handleClose The cleanup function to call
148
- * @param handleTimeout Optional custom timeout handler
149
- * @param errorPrefix Optional prefix for error messages
150
- */
151
- export function setupSocketHandlers(
152
- socket: plugins.net.Socket | plugins.tls.TLSSocket,
153
- handleClose: (reason: string) => void,
154
- handleTimeout?: (socket: plugins.net.Socket | plugins.tls.TLSSocket) => void,
155
- errorPrefix?: string
156
- ): void {
157
- socket.on('error', (error) => {
158
- const prefix = errorPrefix || 'Socket';
159
- handleClose(`${prefix}_error: ${error.message}`);
160
- });
161
-
162
- socket.on('close', () => {
163
- const prefix = errorPrefix || 'socket';
164
- handleClose(`${prefix}_closed`);
165
- });
166
-
167
- socket.on('timeout', () => {
168
- if (handleTimeout) {
169
- handleTimeout(socket); // Custom timeout handling
170
- } else {
171
- // Default: just log, don't close
172
- console.warn(`Socket timeout: ${errorPrefix || 'socket'}`);
173
- }
174
- });
175
- }
176
-
177
- /**
178
- * Setup bidirectional data forwarding between two sockets with proper cleanup
179
- * @param clientSocket The client/incoming socket
180
- * @param serverSocket The server/outgoing socket
181
- * @param handlers Object containing optional handlers for data and cleanup
182
- * @returns Cleanup functions for both sockets
183
- */
184
- export function setupBidirectionalForwarding(
185
- clientSocket: plugins.net.Socket | plugins.tls.TLSSocket,
186
- serverSocket: plugins.net.Socket | plugins.tls.TLSSocket,
187
- handlers: {
188
- onClientData?: (chunk: Buffer) => void;
189
- onServerData?: (chunk: Buffer) => void;
190
- onCleanup: (reason: string) => void;
191
- enableHalfOpen?: boolean;
192
- }
193
- ): { cleanupClient: (reason: string) => Promise<void>, cleanupServer: (reason: string) => Promise<void> } {
194
- // Set up cleanup handlers
195
- const { cleanupClient, cleanupServer } = createIndependentSocketHandlers(
196
- clientSocket,
197
- serverSocket,
198
- handlers.onCleanup,
199
- { enableHalfOpen: handlers.enableHalfOpen }
200
- );
201
-
202
- // Set up error and close handlers
203
- setupSocketHandlers(clientSocket, cleanupClient, undefined, 'client');
204
- setupSocketHandlers(serverSocket, cleanupServer, undefined, 'server');
205
-
206
- // Set up data forwarding with backpressure handling
207
- clientSocket.on('data', (chunk: Buffer) => {
208
- if (handlers.onClientData) {
209
- handlers.onClientData(chunk);
210
- }
211
-
212
- if (serverSocket.writable) {
213
- const flushed = serverSocket.write(chunk);
214
-
215
- // Handle backpressure
216
- if (!flushed) {
217
- clientSocket.pause();
218
- serverSocket.once('drain', () => {
219
- if (!clientSocket.destroyed) {
220
- clientSocket.resume();
221
- }
222
- });
223
- }
224
- }
225
- });
226
-
227
- serverSocket.on('data', (chunk: Buffer) => {
228
- if (handlers.onServerData) {
229
- handlers.onServerData(chunk);
230
- }
231
-
232
- if (clientSocket.writable) {
233
- const flushed = clientSocket.write(chunk);
234
-
235
- // Handle backpressure
236
- if (!flushed) {
237
- serverSocket.pause();
238
- clientSocket.once('drain', () => {
239
- if (!serverSocket.destroyed) {
240
- serverSocket.resume();
241
- }
242
- });
243
- }
244
- }
245
- });
246
-
247
- return { cleanupClient, cleanupServer };
248
- }
249
-
250
- /**
251
- * Create a socket with immediate error handling to prevent crashes
252
- * @param options Socket creation options
253
- * @returns The created socket
254
- */
255
- export function createSocketWithErrorHandler(options: SafeSocketOptions): plugins.net.Socket {
256
- const { port, host, onError, onConnect, timeout } = options;
257
-
258
- // Create socket with immediate error handler attachment
259
- const socket = new plugins.net.Socket();
260
-
261
- // Track if connected
262
- let connected = false;
263
- let connectionTimeout: NodeJS.Timeout | null = null;
264
-
265
- // Attach error handler BEFORE connecting to catch immediate errors
266
- socket.on('error', (error) => {
267
- console.error(`Socket connection error to ${host}:${port}: ${error.message}`);
268
- // Clear the connection timeout if it exists
269
- if (connectionTimeout) {
270
- clearTimeout(connectionTimeout);
271
- connectionTimeout = null;
272
- }
273
- if (onError) {
274
- onError(error);
275
- }
276
- });
277
-
278
- // Attach connect handler
279
- const handleConnect = () => {
280
- connected = true;
281
- // Clear the connection timeout
282
- if (connectionTimeout) {
283
- clearTimeout(connectionTimeout);
284
- connectionTimeout = null;
285
- }
286
- // Set inactivity timeout if provided (after connection is established)
287
- if (timeout) {
288
- socket.setTimeout(timeout);
289
- }
290
- if (onConnect) {
291
- onConnect();
292
- }
293
- };
294
-
295
- socket.on('connect', handleConnect);
296
-
297
- // Implement connection establishment timeout
298
- if (timeout) {
299
- connectionTimeout = setTimeout(() => {
300
- if (!connected && !socket.destroyed) {
301
- // Connection timed out - destroy the socket
302
- const error = new Error(`Connection timeout after ${timeout}ms to ${host}:${port}`);
303
- (error as any).code = 'ETIMEDOUT';
304
-
305
- console.error(`Socket connection timeout to ${host}:${port} after ${timeout}ms`);
306
-
307
- // Destroy the socket
308
- socket.destroy();
309
-
310
- // Call error handler
311
- if (onError) {
312
- onError(error);
313
- }
314
- }
315
- }, timeout);
316
- }
317
-
318
- // Now attempt to connect - any immediate errors will be caught
319
- socket.connect(port, host);
320
-
321
- return socket;
322
- }
@@ -1,124 +0,0 @@
1
- import type { IRouteContext } from '../models/route-context.js';
2
-
3
- /**
4
- * Utility class for resolving template variables in strings
5
- */
6
- export class TemplateUtils {
7
- /**
8
- * Resolve template variables in a string using the route context
9
- * Supports variables like {domain}, {path}, {clientIp}, etc.
10
- *
11
- * @param template The template string with {variables}
12
- * @param context The route context with values
13
- * @returns The resolved string
14
- */
15
- public static resolveTemplateVariables(template: string, context: IRouteContext): string {
16
- if (!template) {
17
- return template;
18
- }
19
-
20
- // Replace variables with values from context
21
- return template.replace(/\{([a-zA-Z0-9_\.]+)\}/g, (match, varName) => {
22
- // Handle nested properties with dot notation (e.g., {headers.host})
23
- if (varName.includes('.')) {
24
- const parts = varName.split('.');
25
- let current: any = context;
26
-
27
- // Traverse nested object structure
28
- for (const part of parts) {
29
- if (current === undefined || current === null) {
30
- return match; // Return original if path doesn't exist
31
- }
32
- current = current[part];
33
- }
34
-
35
- // Return the resolved value if it exists
36
- if (current !== undefined && current !== null) {
37
- return TemplateUtils.convertToString(current);
38
- }
39
-
40
- return match;
41
- }
42
-
43
- // Direct property access
44
- const value = context[varName as keyof IRouteContext];
45
- if (value === undefined) {
46
- return match; // Keep the original {variable} if not found
47
- }
48
-
49
- // Convert value to string
50
- return TemplateUtils.convertToString(value);
51
- });
52
- }
53
-
54
- /**
55
- * Safely convert a value to a string
56
- *
57
- * @param value Any value to convert to string
58
- * @returns String representation or original match for complex objects
59
- */
60
- private static convertToString(value: any): string {
61
- if (value === null || value === undefined) {
62
- return '';
63
- }
64
-
65
- if (typeof value === 'string') {
66
- return value;
67
- }
68
-
69
- if (typeof value === 'number' || typeof value === 'boolean') {
70
- return value.toString();
71
- }
72
-
73
- if (Array.isArray(value)) {
74
- return value.join(',');
75
- }
76
-
77
- if (typeof value === 'object') {
78
- try {
79
- return JSON.stringify(value);
80
- } catch (e) {
81
- return '[Object]';
82
- }
83
- }
84
-
85
- return String(value);
86
- }
87
-
88
- /**
89
- * Resolve template variables in header values
90
- *
91
- * @param headers Header object with potential template variables
92
- * @param context Route context for variable resolution
93
- * @returns New header object with resolved values
94
- */
95
- public static resolveHeaderTemplates(
96
- headers: Record<string, string>,
97
- context: IRouteContext
98
- ): Record<string, string> {
99
- const result: Record<string, string> = {};
100
-
101
- for (const [key, value] of Object.entries(headers)) {
102
- // Skip special directive headers (starting with !)
103
- if (value.startsWith('!')) {
104
- result[key] = value;
105
- continue;
106
- }
107
-
108
- // Resolve template variables in the header value
109
- result[key] = TemplateUtils.resolveTemplateVariables(value, context);
110
- }
111
-
112
- return result;
113
- }
114
-
115
- /**
116
- * Check if a string contains template variables
117
- *
118
- * @param str String to check for template variables
119
- * @returns True if string contains template variables
120
- */
121
- public static containsTemplateVariables(str: string): boolean {
122
- return !!str && /\{([a-zA-Z0-9_\.]+)\}/g.test(str);
123
- }
124
- }
@@ -1,177 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import type { IDomainOptions, IAcmeOptions } from '../models/common-types.js';
3
-
4
- /**
5
- * Collection of validation utilities for configuration and domain options
6
- */
7
- export class ValidationUtils {
8
- /**
9
- * Validates domain configuration options
10
- *
11
- * @param domainOptions The domain options to validate
12
- * @returns An object with validation result and error message if invalid
13
- */
14
- public static validateDomainOptions(domainOptions: IDomainOptions): { isValid: boolean; error?: string } {
15
- if (!domainOptions) {
16
- return { isValid: false, error: 'Domain options cannot be null or undefined' };
17
- }
18
-
19
- if (!domainOptions.domainName) {
20
- return { isValid: false, error: 'Domain name is required' };
21
- }
22
-
23
- // Check domain pattern
24
- if (!this.isValidDomainName(domainOptions.domainName)) {
25
- return { isValid: false, error: `Invalid domain name: ${domainOptions.domainName}` };
26
- }
27
-
28
- // Validate forward config if provided
29
- if (domainOptions.forward) {
30
- if (!domainOptions.forward.ip) {
31
- return { isValid: false, error: 'Forward IP is required when forward is specified' };
32
- }
33
-
34
- if (!domainOptions.forward.port) {
35
- return { isValid: false, error: 'Forward port is required when forward is specified' };
36
- }
37
-
38
- if (!this.isValidPort(domainOptions.forward.port)) {
39
- return { isValid: false, error: `Invalid forward port: ${domainOptions.forward.port}` };
40
- }
41
- }
42
-
43
- // Validate ACME forward config if provided
44
- if (domainOptions.acmeForward) {
45
- if (!domainOptions.acmeForward.ip) {
46
- return { isValid: false, error: 'ACME forward IP is required when acmeForward is specified' };
47
- }
48
-
49
- if (!domainOptions.acmeForward.port) {
50
- return { isValid: false, error: 'ACME forward port is required when acmeForward is specified' };
51
- }
52
-
53
- if (!this.isValidPort(domainOptions.acmeForward.port)) {
54
- return { isValid: false, error: `Invalid ACME forward port: ${domainOptions.acmeForward.port}` };
55
- }
56
- }
57
-
58
- return { isValid: true };
59
- }
60
-
61
- /**
62
- * Validates ACME configuration options
63
- *
64
- * @param acmeOptions The ACME options to validate
65
- * @returns An object with validation result and error message if invalid
66
- */
67
- public static validateAcmeOptions(acmeOptions: IAcmeOptions): { isValid: boolean; error?: string } {
68
- if (!acmeOptions) {
69
- return { isValid: false, error: 'ACME options cannot be null or undefined' };
70
- }
71
-
72
- if (acmeOptions.enabled) {
73
- if (!acmeOptions.accountEmail) {
74
- return { isValid: false, error: 'Account email is required when ACME is enabled' };
75
- }
76
-
77
- if (!this.isValidEmail(acmeOptions.accountEmail)) {
78
- return { isValid: false, error: `Invalid email: ${acmeOptions.accountEmail}` };
79
- }
80
-
81
- if (acmeOptions.port && !this.isValidPort(acmeOptions.port)) {
82
- return { isValid: false, error: `Invalid ACME port: ${acmeOptions.port}` };
83
- }
84
-
85
- if (acmeOptions.httpsRedirectPort && !this.isValidPort(acmeOptions.httpsRedirectPort)) {
86
- return { isValid: false, error: `Invalid HTTPS redirect port: ${acmeOptions.httpsRedirectPort}` };
87
- }
88
-
89
- if (acmeOptions.renewThresholdDays && acmeOptions.renewThresholdDays < 1) {
90
- return { isValid: false, error: 'Renew threshold days must be greater than 0' };
91
- }
92
-
93
- if (acmeOptions.renewCheckIntervalHours && acmeOptions.renewCheckIntervalHours < 1) {
94
- return { isValid: false, error: 'Renew check interval hours must be greater than 0' };
95
- }
96
- }
97
-
98
- return { isValid: true };
99
- }
100
-
101
- /**
102
- * Validates a port number
103
- *
104
- * @param port The port to validate
105
- * @returns true if the port is valid, false otherwise
106
- */
107
- public static isValidPort(port: number): boolean {
108
- return typeof port === 'number' && port > 0 && port <= 65535 && Number.isInteger(port);
109
- }
110
-
111
- /**
112
- * Validates a domain name
113
- *
114
- * @param domain The domain name to validate
115
- * @returns true if the domain name is valid, false otherwise
116
- */
117
- public static isValidDomainName(domain: string): boolean {
118
- if (!domain || typeof domain !== 'string') {
119
- return false;
120
- }
121
-
122
- // Wildcard domain check (*.example.com)
123
- if (domain.startsWith('*.')) {
124
- domain = domain.substring(2);
125
- }
126
-
127
- // Simple domain validation pattern
128
- const domainPattern = /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
129
- return domainPattern.test(domain);
130
- }
131
-
132
- /**
133
- * Validates an email address
134
- *
135
- * @param email The email to validate
136
- * @returns true if the email is valid, false otherwise
137
- */
138
- public static isValidEmail(email: string): boolean {
139
- if (!email || typeof email !== 'string') {
140
- return false;
141
- }
142
-
143
- // Basic email validation pattern
144
- const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
145
- return emailPattern.test(email);
146
- }
147
-
148
- /**
149
- * Validates a certificate format (PEM)
150
- *
151
- * @param cert The certificate content to validate
152
- * @returns true if the certificate appears to be in PEM format, false otherwise
153
- */
154
- public static isValidCertificate(cert: string): boolean {
155
- if (!cert || typeof cert !== 'string') {
156
- return false;
157
- }
158
-
159
- return cert.includes('-----BEGIN CERTIFICATE-----') &&
160
- cert.includes('-----END CERTIFICATE-----');
161
- }
162
-
163
- /**
164
- * Validates a private key format (PEM)
165
- *
166
- * @param key The private key content to validate
167
- * @returns true if the key appears to be in PEM format, false otherwise
168
- */
169
- public static isValidPrivateKey(key: string): boolean {
170
- if (!key || typeof key !== 'string') {
171
- return false;
172
- }
173
-
174
- return key.includes('-----BEGIN PRIVATE KEY-----') &&
175
- key.includes('-----END PRIVATE KEY-----');
176
- }
177
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * WebSocket utility functions
3
- *
4
- * This module provides smartproxy-specific WebSocket utilities
5
- * and re-exports protocol utilities from the protocols module
6
- */
7
-
8
- // Import and re-export from protocols
9
- import { getMessageSize as protocolGetMessageSize, toBuffer as protocolToBuffer } from '../../protocols/websocket/index.js';
10
- export type { RawData } from '../../protocols/websocket/index.js';
11
-
12
- /**
13
- * Get the length of a WebSocket message regardless of its type
14
- * (handles all possible WebSocket message data types)
15
- *
16
- * @param data - The data message from WebSocket (could be any RawData type)
17
- * @returns The length of the data in bytes
18
- */
19
- export function getMessageSize(data: import('../../protocols/websocket/index.js').RawData): number {
20
- // Delegate to protocol implementation
21
- return protocolGetMessageSize(data);
22
- }
23
-
24
- /**
25
- * Convert any raw WebSocket data to Buffer for consistent handling
26
- *
27
- * @param data - The data message from WebSocket (could be any RawData type)
28
- * @returns A Buffer containing the data
29
- */
30
- export function toBuffer(data: import('../../protocols/websocket/index.js').RawData): Buffer {
31
- // Delegate to protocol implementation
32
- return protocolToBuffer(data);
33
- }