@push.rocks/smartproxy 25.17.9 → 26.0.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 (179) hide show
  1. package/changelog.md +16 -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/socket-handler-server.js +6 -1
  18. package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.d.ts +0 -7
  19. package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.js +50 -51
  20. package/dist_ts/routing/index.d.ts +0 -1
  21. package/dist_ts/routing/index.js +1 -3
  22. package/package.json +1 -1
  23. package/ts/00_commitinfo_data.ts +1 -1
  24. package/ts/core/index.ts +0 -1
  25. package/ts/core/models/index.ts +0 -1
  26. package/ts/core/utils/index.ts +0 -12
  27. package/ts/index.ts +1 -7
  28. package/ts/protocols/http/index.ts +1 -2
  29. package/ts/protocols/index.ts +0 -7
  30. package/ts/proxies/smart-proxy/socket-handler-server.ts +6 -0
  31. package/ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.ts +60 -59
  32. package/ts/routing/index.ts +0 -3
  33. package/dist_ts/core/events/index.d.ts +0 -4
  34. package/dist_ts/core/events/index.js +0 -5
  35. package/dist_ts/core/models/socket-augmentation.d.ts +0 -15
  36. package/dist_ts/core/models/socket-augmentation.js +0 -18
  37. package/dist_ts/core/utils/async-utils.d.ts +0 -81
  38. package/dist_ts/core/utils/async-utils.js +0 -216
  39. package/dist_ts/core/utils/binary-heap.d.ts +0 -73
  40. package/dist_ts/core/utils/binary-heap.js +0 -193
  41. package/dist_ts/core/utils/enhanced-connection-pool.d.ts +0 -110
  42. package/dist_ts/core/utils/enhanced-connection-pool.js +0 -325
  43. package/dist_ts/core/utils/fs-utils.d.ts +0 -144
  44. package/dist_ts/core/utils/fs-utils.js +0 -252
  45. package/dist_ts/core/utils/ip-utils.d.ts +0 -69
  46. package/dist_ts/core/utils/ip-utils.js +0 -270
  47. package/dist_ts/core/utils/lifecycle-component.d.ts +0 -59
  48. package/dist_ts/core/utils/lifecycle-component.js +0 -211
  49. package/dist_ts/core/utils/log-deduplicator.d.ts +0 -39
  50. package/dist_ts/core/utils/log-deduplicator.js +0 -305
  51. package/dist_ts/core/utils/security-utils.d.ts +0 -111
  52. package/dist_ts/core/utils/security-utils.js +0 -212
  53. package/dist_ts/core/utils/shared-security-manager.d.ts +0 -128
  54. package/dist_ts/core/utils/shared-security-manager.js +0 -362
  55. package/dist_ts/core/utils/socket-utils.d.ts +0 -63
  56. package/dist_ts/core/utils/socket-utils.js +0 -249
  57. package/dist_ts/core/utils/template-utils.d.ts +0 -37
  58. package/dist_ts/core/utils/template-utils.js +0 -104
  59. package/dist_ts/core/utils/validation-utils.d.ts +0 -61
  60. package/dist_ts/core/utils/validation-utils.js +0 -149
  61. package/dist_ts/core/utils/websocket-utils.d.ts +0 -22
  62. package/dist_ts/core/utils/websocket-utils.js +0 -30
  63. package/dist_ts/detection/detectors/http-detector.d.ts +0 -33
  64. package/dist_ts/detection/detectors/http-detector.js +0 -101
  65. package/dist_ts/detection/detectors/quick-detector.d.ts +0 -28
  66. package/dist_ts/detection/detectors/quick-detector.js +0 -131
  67. package/dist_ts/detection/detectors/routing-extractor.d.ts +0 -28
  68. package/dist_ts/detection/detectors/routing-extractor.js +0 -122
  69. package/dist_ts/detection/detectors/tls-detector.d.ts +0 -47
  70. package/dist_ts/detection/detectors/tls-detector.js +0 -183
  71. package/dist_ts/detection/index.d.ts +0 -17
  72. package/dist_ts/detection/index.js +0 -22
  73. package/dist_ts/detection/models/detection-types.d.ts +0 -87
  74. package/dist_ts/detection/models/detection-types.js +0 -5
  75. package/dist_ts/detection/models/interfaces.d.ts +0 -97
  76. package/dist_ts/detection/models/interfaces.js +0 -5
  77. package/dist_ts/detection/protocol-detector.d.ts +0 -79
  78. package/dist_ts/detection/protocol-detector.js +0 -253
  79. package/dist_ts/detection/utils/buffer-utils.d.ts +0 -61
  80. package/dist_ts/detection/utils/buffer-utils.js +0 -127
  81. package/dist_ts/detection/utils/fragment-manager.d.ts +0 -31
  82. package/dist_ts/detection/utils/fragment-manager.js +0 -53
  83. package/dist_ts/detection/utils/parser-utils.d.ts +0 -42
  84. package/dist_ts/detection/utils/parser-utils.js +0 -63
  85. package/dist_ts/protocols/common/fragment-handler.d.ts +0 -73
  86. package/dist_ts/protocols/common/fragment-handler.js +0 -121
  87. package/dist_ts/protocols/common/index.d.ts +0 -7
  88. package/dist_ts/protocols/common/index.js +0 -8
  89. package/dist_ts/protocols/common/types.d.ts +0 -68
  90. package/dist_ts/protocols/common/types.js +0 -7
  91. package/dist_ts/protocols/http/parser.d.ts +0 -58
  92. package/dist_ts/protocols/http/parser.js +0 -184
  93. package/dist_ts/protocols/proxy/index.d.ts +0 -5
  94. package/dist_ts/protocols/proxy/index.js +0 -6
  95. package/dist_ts/protocols/proxy/types.d.ts +0 -47
  96. package/dist_ts/protocols/proxy/types.js +0 -6
  97. package/dist_ts/protocols/tls/alerts/index.d.ts +0 -4
  98. package/dist_ts/protocols/tls/alerts/index.js +0 -5
  99. package/dist_ts/protocols/tls/alerts/tls-alert.d.ts +0 -150
  100. package/dist_ts/protocols/tls/alerts/tls-alert.js +0 -226
  101. package/dist_ts/protocols/tls/index.d.ts +0 -12
  102. package/dist_ts/protocols/tls/index.js +0 -27
  103. package/dist_ts/protocols/tls/sni/client-hello-parser.d.ts +0 -100
  104. package/dist_ts/protocols/tls/sni/client-hello-parser.js +0 -463
  105. package/dist_ts/protocols/tls/sni/index.d.ts +0 -5
  106. package/dist_ts/protocols/tls/sni/index.js +0 -6
  107. package/dist_ts/protocols/tls/sni/sni-extraction.d.ts +0 -58
  108. package/dist_ts/protocols/tls/sni/sni-extraction.js +0 -275
  109. package/dist_ts/protocols/tls/utils/index.d.ts +0 -4
  110. package/dist_ts/protocols/tls/utils/index.js +0 -5
  111. package/dist_ts/protocols/tls/utils/tls-utils.d.ts +0 -158
  112. package/dist_ts/protocols/tls/utils/tls-utils.js +0 -187
  113. package/dist_ts/protocols/websocket/constants.d.ts +0 -55
  114. package/dist_ts/protocols/websocket/constants.js +0 -58
  115. package/dist_ts/protocols/websocket/index.d.ts +0 -7
  116. package/dist_ts/protocols/websocket/index.js +0 -8
  117. package/dist_ts/protocols/websocket/types.d.ts +0 -47
  118. package/dist_ts/protocols/websocket/types.js +0 -5
  119. package/dist_ts/protocols/websocket/utils.d.ts +0 -25
  120. package/dist_ts/protocols/websocket/utils.js +0 -103
  121. package/dist_ts/routing/router/http-router.d.ts +0 -89
  122. package/dist_ts/routing/router/http-router.js +0 -205
  123. package/dist_ts/routing/router/index.d.ts +0 -5
  124. package/dist_ts/routing/router/index.js +0 -6
  125. package/dist_ts/tls/index.d.ts +0 -16
  126. package/dist_ts/tls/index.js +0 -24
  127. package/dist_ts/tls/sni/index.d.ts +0 -4
  128. package/dist_ts/tls/sni/index.js +0 -5
  129. package/dist_ts/tls/sni/sni-handler.d.ts +0 -154
  130. package/dist_ts/tls/sni/sni-handler.js +0 -191
  131. package/ts/core/events/index.ts +0 -3
  132. package/ts/core/models/socket-augmentation.ts +0 -38
  133. package/ts/core/utils/async-utils.ts +0 -275
  134. package/ts/core/utils/binary-heap.ts +0 -225
  135. package/ts/core/utils/enhanced-connection-pool.ts +0 -425
  136. package/ts/core/utils/fs-utils.ts +0 -270
  137. package/ts/core/utils/ip-utils.ts +0 -303
  138. package/ts/core/utils/lifecycle-component.ts +0 -251
  139. package/ts/core/utils/log-deduplicator.ts +0 -370
  140. package/ts/core/utils/security-utils.ts +0 -305
  141. package/ts/core/utils/shared-security-manager.ts +0 -470
  142. package/ts/core/utils/socket-utils.ts +0 -322
  143. package/ts/core/utils/template-utils.ts +0 -124
  144. package/ts/core/utils/validation-utils.ts +0 -177
  145. package/ts/core/utils/websocket-utils.ts +0 -33
  146. package/ts/detection/detectors/http-detector.ts +0 -127
  147. package/ts/detection/detectors/quick-detector.ts +0 -148
  148. package/ts/detection/detectors/routing-extractor.ts +0 -147
  149. package/ts/detection/detectors/tls-detector.ts +0 -223
  150. package/ts/detection/index.ts +0 -25
  151. package/ts/detection/models/detection-types.ts +0 -102
  152. package/ts/detection/models/interfaces.ts +0 -115
  153. package/ts/detection/protocol-detector.ts +0 -319
  154. package/ts/detection/utils/buffer-utils.ts +0 -141
  155. package/ts/detection/utils/fragment-manager.ts +0 -64
  156. package/ts/detection/utils/parser-utils.ts +0 -77
  157. package/ts/protocols/common/fragment-handler.ts +0 -167
  158. package/ts/protocols/common/index.ts +0 -8
  159. package/ts/protocols/common/types.ts +0 -76
  160. package/ts/protocols/http/parser.ts +0 -219
  161. package/ts/protocols/proxy/index.ts +0 -6
  162. package/ts/protocols/proxy/types.ts +0 -53
  163. package/ts/protocols/tls/alerts/index.ts +0 -3
  164. package/ts/protocols/tls/alerts/tls-alert.ts +0 -259
  165. package/ts/protocols/tls/index.ts +0 -37
  166. package/ts/protocols/tls/sni/client-hello-parser.ts +0 -629
  167. package/ts/protocols/tls/sni/index.ts +0 -6
  168. package/ts/protocols/tls/sni/sni-extraction.ts +0 -353
  169. package/ts/protocols/tls/utils/index.ts +0 -3
  170. package/ts/protocols/tls/utils/tls-utils.ts +0 -201
  171. package/ts/protocols/websocket/constants.ts +0 -60
  172. package/ts/protocols/websocket/index.ts +0 -8
  173. package/ts/protocols/websocket/types.ts +0 -53
  174. package/ts/protocols/websocket/utils.ts +0 -98
  175. package/ts/routing/router/http-router.ts +0 -266
  176. package/ts/routing/router/index.ts +0 -7
  177. package/ts/tls/index.ts +0 -29
  178. package/ts/tls/sni/index.ts +0 -3
  179. 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
- }