@push.rocks/smartproxy 16.0.2 → 16.0.4

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 (115) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/core/models/index.d.ts +2 -0
  3. package/dist_ts/core/models/index.js +3 -1
  4. package/dist_ts/core/models/route-context.d.ts +62 -0
  5. package/dist_ts/core/models/route-context.js +43 -0
  6. package/dist_ts/core/models/socket-augmentation.d.ts +12 -0
  7. package/dist_ts/core/models/socket-augmentation.js +18 -0
  8. package/dist_ts/core/utils/event-system.d.ts +200 -0
  9. package/dist_ts/core/utils/event-system.js +224 -0
  10. package/dist_ts/core/utils/index.d.ts +7 -0
  11. package/dist_ts/core/utils/index.js +8 -1
  12. package/dist_ts/core/utils/route-manager.d.ts +118 -0
  13. package/dist_ts/core/utils/route-manager.js +383 -0
  14. package/dist_ts/core/utils/route-utils.d.ts +94 -0
  15. package/dist_ts/core/utils/route-utils.js +264 -0
  16. package/dist_ts/core/utils/security-utils.d.ts +111 -0
  17. package/dist_ts/core/utils/security-utils.js +212 -0
  18. package/dist_ts/core/utils/shared-security-manager.d.ts +110 -0
  19. package/dist_ts/core/utils/shared-security-manager.js +252 -0
  20. package/dist_ts/core/utils/template-utils.d.ts +37 -0
  21. package/dist_ts/core/utils/template-utils.js +104 -0
  22. package/dist_ts/core/utils/websocket-utils.d.ts +23 -0
  23. package/dist_ts/core/utils/websocket-utils.js +86 -0
  24. package/dist_ts/http/router/index.d.ts +5 -1
  25. package/dist_ts/http/router/index.js +4 -2
  26. package/dist_ts/http/router/route-router.d.ts +108 -0
  27. package/dist_ts/http/router/route-router.js +393 -0
  28. package/dist_ts/index.d.ts +8 -2
  29. package/dist_ts/index.js +10 -3
  30. package/dist_ts/proxies/index.d.ts +7 -2
  31. package/dist_ts/proxies/index.js +10 -4
  32. package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +21 -0
  33. package/dist_ts/proxies/network-proxy/certificate-manager.js +92 -1
  34. package/dist_ts/proxies/network-proxy/context-creator.d.ts +34 -0
  35. package/dist_ts/proxies/network-proxy/context-creator.js +108 -0
  36. package/dist_ts/proxies/network-proxy/function-cache.d.ts +90 -0
  37. package/dist_ts/proxies/network-proxy/function-cache.js +198 -0
  38. package/dist_ts/proxies/network-proxy/http-request-handler.d.ts +40 -0
  39. package/dist_ts/proxies/network-proxy/http-request-handler.js +256 -0
  40. package/dist_ts/proxies/network-proxy/http2-request-handler.d.ts +24 -0
  41. package/dist_ts/proxies/network-proxy/http2-request-handler.js +201 -0
  42. package/dist_ts/proxies/network-proxy/models/types.d.ts +73 -1
  43. package/dist_ts/proxies/network-proxy/models/types.js +242 -1
  44. package/dist_ts/proxies/network-proxy/network-proxy.d.ts +23 -20
  45. package/dist_ts/proxies/network-proxy/network-proxy.js +149 -60
  46. package/dist_ts/proxies/network-proxy/request-handler.d.ts +38 -5
  47. package/dist_ts/proxies/network-proxy/request-handler.js +584 -198
  48. package/dist_ts/proxies/network-proxy/security-manager.d.ts +65 -0
  49. package/dist_ts/proxies/network-proxy/security-manager.js +255 -0
  50. package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +13 -2
  51. package/dist_ts/proxies/network-proxy/websocket-handler.js +238 -20
  52. package/dist_ts/proxies/smart-proxy/index.d.ts +1 -1
  53. package/dist_ts/proxies/smart-proxy/index.js +3 -3
  54. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +3 -5
  55. package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +56 -4
  56. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +4 -57
  57. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +19 -228
  58. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +81 -0
  59. package/dist_ts/proxies/smart-proxy/port-manager.js +166 -0
  60. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +5 -0
  61. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +131 -15
  62. package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +3 -1
  63. package/dist_ts/proxies/smart-proxy/route-helpers/index.js +5 -3
  64. package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +5 -178
  65. package/dist_ts/proxies/smart-proxy/route-helpers.js +8 -296
  66. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +11 -2
  67. package/dist_ts/proxies/smart-proxy/route-manager.js +79 -10
  68. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +29 -2
  69. package/dist_ts/proxies/smart-proxy/smart-proxy.js +48 -43
  70. package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +67 -1
  71. package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +120 -1
  72. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +3 -3
  73. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +27 -5
  74. package/package.json +1 -1
  75. package/readme.md +102 -14
  76. package/readme.plan.md +103 -168
  77. package/ts/00_commitinfo_data.ts +1 -1
  78. package/ts/core/models/index.ts +2 -0
  79. package/ts/core/models/route-context.ts +113 -0
  80. package/ts/core/models/socket-augmentation.ts +33 -0
  81. package/ts/core/utils/event-system.ts +376 -0
  82. package/ts/core/utils/index.ts +7 -0
  83. package/ts/core/utils/route-manager.ts +489 -0
  84. package/ts/core/utils/route-utils.ts +312 -0
  85. package/ts/core/utils/security-utils.ts +309 -0
  86. package/ts/core/utils/shared-security-manager.ts +333 -0
  87. package/ts/core/utils/template-utils.ts +124 -0
  88. package/ts/core/utils/websocket-utils.ts +81 -0
  89. package/ts/http/router/index.ts +8 -1
  90. package/ts/http/router/route-router.ts +482 -0
  91. package/ts/index.ts +14 -2
  92. package/ts/proxies/index.ts +12 -3
  93. package/ts/proxies/network-proxy/certificate-manager.ts +114 -10
  94. package/ts/proxies/network-proxy/context-creator.ts +145 -0
  95. package/ts/proxies/network-proxy/function-cache.ts +259 -0
  96. package/ts/proxies/network-proxy/http-request-handler.ts +330 -0
  97. package/ts/proxies/network-proxy/http2-request-handler.ts +255 -0
  98. package/ts/proxies/network-proxy/models/types.ts +312 -1
  99. package/ts/proxies/network-proxy/network-proxy.ts +197 -85
  100. package/ts/proxies/network-proxy/request-handler.ts +698 -246
  101. package/ts/proxies/network-proxy/security-manager.ts +298 -0
  102. package/ts/proxies/network-proxy/websocket-handler.ts +276 -33
  103. package/ts/proxies/smart-proxy/index.ts +2 -12
  104. package/ts/proxies/smart-proxy/models/interfaces.ts +7 -4
  105. package/ts/proxies/smart-proxy/models/route-types.ts +77 -10
  106. package/ts/proxies/smart-proxy/network-proxy-bridge.ts +20 -257
  107. package/ts/proxies/smart-proxy/port-manager.ts +195 -0
  108. package/ts/proxies/smart-proxy/route-connection-handler.ts +156 -21
  109. package/ts/proxies/smart-proxy/route-manager.ts +98 -14
  110. package/ts/proxies/smart-proxy/smart-proxy.ts +56 -55
  111. package/ts/proxies/smart-proxy/utils/route-helpers.ts +167 -1
  112. package/ts/proxies/smart-proxy/utils/route-validators.ts +24 -5
  113. package/ts/proxies/smart-proxy/domain-config-manager.ts.bak +0 -441
  114. package/ts/proxies/smart-proxy/route-helpers/index.ts +0 -9
  115. package/ts/proxies/smart-proxy/route-helpers.ts +0 -498
@@ -1,14 +1,13 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import { NetworkProxy } from '../network-proxy/index.js';
3
3
  import { Port80Handler } from '../../http/port80/port80-handler.js';
4
- import { Port80HandlerEvents } from '../../core/models/common-types.js';
5
4
  import { subscribeToPort80Handler } from '../../core/utils/event-utils.js';
6
5
  /**
7
6
  * Manages NetworkProxy integration for TLS termination
8
7
  *
9
8
  * NetworkProxyBridge connects SmartProxy with NetworkProxy to handle TLS termination.
10
- * It directly maps route configurations to NetworkProxy configuration format and manages
11
- * certificate provisioning through Port80Handler when ACME is enabled.
9
+ * It directly passes route configurations to NetworkProxy and manages the physical
10
+ * connection piping between SmartProxy and NetworkProxy for TLS termination.
12
11
  *
13
12
  * It is used by SmartProxy for routes that have:
14
13
  * - TLS mode of 'terminate' or 'terminate-and-reencrypt'
@@ -41,7 +40,7 @@ export class NetworkProxyBridge {
41
40
  */
42
41
  async initialize() {
43
42
  if (!this.networkProxy && this.settings.useNetworkProxy && this.settings.useNetworkProxy.length > 0) {
44
- // Configure NetworkProxy options based on PortProxy settings
43
+ // Configure NetworkProxy options based on SmartProxy settings
45
44
  const networkProxyOptions = {
46
45
  port: this.settings.networkProxyPort,
47
46
  portProxyIntegration: true,
@@ -65,29 +64,8 @@ export class NetworkProxyBridge {
65
64
  if (!this.networkProxy)
66
65
  return;
67
66
  console.log(`Received certificate for ${data.domain} from Port80Handler, updating NetworkProxy`);
68
- try {
69
- // Find existing config for this domain
70
- const existingConfigs = this.networkProxy.getProxyConfigs()
71
- .filter(config => config.hostName === data.domain);
72
- if (existingConfigs.length > 0) {
73
- // Update existing configs with new certificate
74
- for (const config of existingConfigs) {
75
- config.privateKey = data.privateKey;
76
- config.publicKey = data.certificate;
77
- }
78
- // Apply updated configs
79
- this.networkProxy.updateProxyConfigs(existingConfigs)
80
- .then(() => console.log(`Updated certificate for ${data.domain} in NetworkProxy`))
81
- .catch(err => console.log(`Error updating certificate in NetworkProxy: ${err}`));
82
- }
83
- else {
84
- // Create a new config for this domain
85
- console.log(`No existing config found for ${data.domain}, creating new config in NetworkProxy`);
86
- }
87
- }
88
- catch (err) {
89
- console.log(`Error handling certificate event: ${err}`);
90
- }
67
+ // Apply certificate directly to NetworkProxy
68
+ this.networkProxy.updateCertificate(data.domain, data.certificate, data.privateKey);
91
69
  }
92
70
  /**
93
71
  * Apply an external (static) certificate into NetworkProxy
@@ -97,7 +75,8 @@ export class NetworkProxyBridge {
97
75
  console.log(`NetworkProxy not initialized: cannot apply external certificate for ${data.domain}`);
98
76
  return;
99
77
  }
100
- this.handleCertificateEvent(data);
78
+ // Apply certificate directly to NetworkProxy
79
+ this.networkProxy.updateCertificate(data.domain, data.certificate, data.privateKey);
101
80
  }
102
81
  /**
103
82
  * Get the NetworkProxy instance
@@ -135,83 +114,6 @@ export class NetworkProxyBridge {
135
114
  }
136
115
  }
137
116
  }
138
- /**
139
- * Register domains from routes with Port80Handler for certificate management
140
- *
141
- * Extracts domains from routes that require TLS termination and registers them
142
- * with the Port80Handler for certificate issuance and renewal.
143
- *
144
- * @param routes The route configurations to extract domains from
145
- */
146
- registerDomainsWithPort80Handler(routes) {
147
- if (!this.port80Handler) {
148
- console.log('Cannot register domains - Port80Handler not initialized');
149
- return;
150
- }
151
- // Extract domains from routes that require TLS termination
152
- const domainsToRegister = new Set();
153
- for (const route of routes) {
154
- // Skip routes without domains or TLS configuration
155
- if (!route.match.domains || !route.action.tls)
156
- continue;
157
- // Only register domains for routes that terminate TLS
158
- if (route.action.tls.mode !== 'terminate' && route.action.tls.mode !== 'terminate-and-reencrypt')
159
- continue;
160
- // Extract domains from route
161
- const domains = Array.isArray(route.match.domains)
162
- ? route.match.domains
163
- : [route.match.domains];
164
- // Add each domain to the set (avoiding duplicates)
165
- for (const domain of domains) {
166
- // Skip wildcards
167
- if (domain.includes('*')) {
168
- console.log(`Skipping wildcard domain for ACME: ${domain}`);
169
- continue;
170
- }
171
- domainsToRegister.add(domain);
172
- }
173
- }
174
- // Register each unique domain with Port80Handler
175
- for (const domain of domainsToRegister) {
176
- try {
177
- this.port80Handler.addDomain({
178
- domainName: domain,
179
- sslRedirect: true,
180
- acmeMaintenance: true,
181
- // Include route reference if we can find it
182
- routeReference: this.findRouteReferenceForDomain(domain, routes)
183
- });
184
- console.log(`Registered domain with Port80Handler: ${domain}`);
185
- }
186
- catch (err) {
187
- console.log(`Error registering domain ${domain} with Port80Handler: ${err}`);
188
- }
189
- }
190
- }
191
- /**
192
- * Finds the route reference for a given domain
193
- *
194
- * @param domain The domain to find a route reference for
195
- * @param routes The routes to search
196
- * @returns The route reference if found, undefined otherwise
197
- */
198
- findRouteReferenceForDomain(domain, routes) {
199
- // Find the first route that matches this domain
200
- for (const route of routes) {
201
- if (!route.match.domains)
202
- continue;
203
- const domains = Array.isArray(route.match.domains)
204
- ? route.match.domains
205
- : [route.match.domains];
206
- if (domains.includes(domain)) {
207
- return {
208
- routeId: undefined, // No explicit IDs in our current routes
209
- routeName: route.name
210
- };
211
- }
212
- }
213
- return undefined;
214
- }
215
117
  /**
216
118
  * Forwards a TLS connection to a NetworkProxy for handling
217
119
  */
@@ -256,7 +158,6 @@ export class NetworkProxyBridge {
256
158
  // Now set up bidirectional piping between client and NetworkProxy
257
159
  socket.pipe(proxySocket);
258
160
  proxySocket.pipe(socket);
259
- // Update activity on data transfer (caller should handle this)
260
161
  if (this.settings.enableDetailedLogging) {
261
162
  console.log(`[${connectionId}] TLS connection successfully forwarded to NetworkProxy`);
262
163
  }
@@ -265,13 +166,8 @@ export class NetworkProxyBridge {
265
166
  /**
266
167
  * Synchronizes routes to NetworkProxy
267
168
  *
268
- * This method directly maps route configurations to NetworkProxy format and updates
269
- * the NetworkProxy with these configurations. It handles:
270
- *
271
- * - Extracting domain, target, and certificate information from routes
272
- * - Converting TLS mode settings to NetworkProxy configuration
273
- * - Applying security and advanced settings
274
- * - Registering domains for ACME certificate provisioning when needed
169
+ * This method directly passes route configurations to NetworkProxy without any
170
+ * intermediate conversion. NetworkProxy natively understands route configurations.
275
171
  *
276
172
  * @param routes The route configurations to sync to NetworkProxy
277
173
  */
@@ -281,118 +177,20 @@ export class NetworkProxyBridge {
281
177
  return;
282
178
  }
283
179
  try {
284
- // Get SSL certificates from assets
285
- // Import fs directly since it's not in plugins
286
- const fs = await import('fs');
287
- let defaultCertPair;
288
- try {
289
- defaultCertPair = {
290
- key: fs.readFileSync('assets/certs/key.pem', 'utf8'),
291
- cert: fs.readFileSync('assets/certs/cert.pem', 'utf8'),
292
- };
293
- }
294
- catch (certError) {
295
- console.log(`Warning: Could not read default certificates: ${certError}`);
296
- console.log('Using empty certificate placeholders - ACME will generate proper certificates if enabled');
297
- // Use empty placeholders - NetworkProxy will use its internal defaults
298
- // or ACME will generate proper ones if enabled
299
- defaultCertPair = {
300
- key: '',
301
- cert: '',
302
- };
303
- }
304
- // Map routes directly to NetworkProxy configs
305
- const proxyConfigs = this.mapRoutesToNetworkProxyConfigs(routes, defaultCertPair);
306
- // Update the proxy configs
307
- await this.networkProxy.updateProxyConfigs(proxyConfigs);
308
- console.log(`Synced ${proxyConfigs.length} configurations to NetworkProxy`);
309
- // Register domains with Port80Handler for certificate issuance
310
- if (this.port80Handler) {
311
- this.registerDomainsWithPort80Handler(routes);
312
- }
180
+ // Filter only routes that are applicable to NetworkProxy (TLS termination)
181
+ const networkProxyRoutes = routes.filter(route => {
182
+ return (route.action.type === 'forward' &&
183
+ route.action.tls &&
184
+ (route.action.tls.mode === 'terminate' || route.action.tls.mode === 'terminate-and-reencrypt'));
185
+ });
186
+ // Pass routes directly to NetworkProxy
187
+ await this.networkProxy.updateRouteConfigs(networkProxyRoutes);
188
+ console.log(`Synced ${networkProxyRoutes.length} routes directly to NetworkProxy`);
313
189
  }
314
190
  catch (err) {
315
191
  console.log(`Error syncing routes to NetworkProxy: ${err}`);
316
192
  }
317
193
  }
318
- /**
319
- * Map routes directly to NetworkProxy configuration format
320
- *
321
- * This method directly maps route configurations to NetworkProxy's format
322
- * without any intermediate domain-based representation. It processes each route
323
- * and creates appropriate NetworkProxy configs for domains that require TLS termination.
324
- *
325
- * @param routes Array of route configurations to map
326
- * @param defaultCertPair Default certificate to use if no custom certificate is specified
327
- * @returns Array of NetworkProxy configurations
328
- */
329
- mapRoutesToNetworkProxyConfigs(routes, defaultCertPair) {
330
- const configs = [];
331
- for (const route of routes) {
332
- // Skip routes without domains
333
- if (!route.match.domains)
334
- continue;
335
- // Skip non-forward routes
336
- if (route.action.type !== 'forward')
337
- continue;
338
- // Skip routes without TLS configuration
339
- if (!route.action.tls || !route.action.target)
340
- continue;
341
- // Skip routes that don't require TLS termination
342
- if (route.action.tls.mode !== 'terminate' && route.action.tls.mode !== 'terminate-and-reencrypt')
343
- continue;
344
- // Get domains from route
345
- const domains = Array.isArray(route.match.domains)
346
- ? route.match.domains
347
- : [route.match.domains];
348
- // Create a config for each domain
349
- for (const domain of domains) {
350
- // Get certificate
351
- let certKey = defaultCertPair.key;
352
- let certCert = defaultCertPair.cert;
353
- // Use custom certificate if specified
354
- if (route.action.tls.certificate !== 'auto' && typeof route.action.tls.certificate === 'object') {
355
- certKey = route.action.tls.certificate.key;
356
- certCert = route.action.tls.certificate.cert;
357
- }
358
- // Determine target hosts and ports
359
- const targetHosts = Array.isArray(route.action.target.host)
360
- ? route.action.target.host
361
- : [route.action.target.host];
362
- const targetPort = route.action.target.port;
363
- // Create the NetworkProxy config
364
- const config = {
365
- hostName: domain,
366
- privateKey: certKey,
367
- publicKey: certCert,
368
- destinationIps: targetHosts,
369
- destinationPorts: [targetPort]
370
- // Note: We can't include additional metadata as it's not supported in the interface
371
- };
372
- configs.push(config);
373
- }
374
- }
375
- return configs;
376
- }
377
- /**
378
- * @deprecated This method is kept for backward compatibility.
379
- * Use mapRoutesToNetworkProxyConfigs() instead.
380
- */
381
- convertRoutesToNetworkProxyConfigs(routes, defaultCertPair) {
382
- return this.mapRoutesToNetworkProxyConfigs(routes, defaultCertPair);
383
- }
384
- /**
385
- * @deprecated This method is deprecated and will be removed in a future version.
386
- * Use syncRoutesToNetworkProxy() instead.
387
- *
388
- * This legacy method exists only for backward compatibility and
389
- * simply forwards to syncRoutesToNetworkProxy().
390
- */
391
- async syncDomainConfigsToNetworkProxy() {
392
- console.log('DEPRECATED: Method syncDomainConfigsToNetworkProxy will be removed in a future version.');
393
- console.log('Please use syncRoutesToNetworkProxy() instead for direct route-based configuration.');
394
- await this.syncRoutesToNetworkProxy(this.settings.routes || []);
395
- }
396
194
  /**
397
195
  * Request a certificate for a specific domain
398
196
  *
@@ -421,13 +219,6 @@ export class NetworkProxyBridge {
421
219
  routeName
422
220
  };
423
221
  }
424
- else {
425
- // Try to find a route reference from the current routes
426
- const routeReference = this.findRouteReferenceForDomain(domain, this.settings.routes || []);
427
- if (routeReference) {
428
- domainOptions.routeReference = routeReference;
429
- }
430
- }
431
222
  // Register the domain for certificate issuance
432
223
  this.port80Handler.addDomain(domainOptions);
433
224
  console.log(`Domain ${domain} registered for certificate issuance`);
@@ -463,4 +254,4 @@ export class NetworkProxyBridge {
463
254
  }
464
255
  }
465
256
  }
466
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay1wcm94eS1icmlkZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9wcm94aWVzL3NtYXJ0LXByb3h5L25ldHdvcmstcHJveHktYnJpZGdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUszRTs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLGtCQUFrQjtJQUk3QixZQUFvQixRQUE0QjtRQUE1QixhQUFRLEdBQVIsUUFBUSxDQUFvQjtRQUh4QyxpQkFBWSxHQUF3QixJQUFJLENBQUM7UUFDekMsa0JBQWEsR0FBeUIsSUFBSSxDQUFDO0lBRUEsQ0FBQztJQUVwRDs7T0FFRztJQUNJLGdCQUFnQixDQUFDLE9BQXNCO1FBQzVDLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDO1FBRTdCLGtDQUFrQztRQUNsQyx3QkFBd0IsQ0FBQyxPQUFPLEVBQUU7WUFDaEMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDM0Qsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDN0QsQ0FBQyxDQUFDO1FBRUgsd0VBQXdFO1FBQ3hFLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxZQUFZLENBQUMsd0JBQXdCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFH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
257
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay1wcm94eS1icmlkZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9wcm94aWVzL3NtYXJ0LXByb3h5L25ldHdvcmstcHJveHktYnJpZGdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUszRTs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLGtCQUFrQjtJQUk3QixZQUFvQixRQUE0QjtRQUE1QixhQUFRLEdBQVIsUUFBUSxDQUFvQjtRQUh4QyxpQkFBWSxHQUF3QixJQUFJLENBQUM7UUFDekMsa0JBQWEsR0FBeUIsSUFBSSxDQUFDO0lBRUEsQ0FBQztJQUVwRDs7T0FFRztJQUNJLGdCQUFnQixDQUFDLE9BQXNCO1FBQzVDLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDO1FBRTdCLGtDQUFrQztRQUNsQyx3QkFBd0IsQ0FBQyxPQUFPLEVBQUU7WUFDaEMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDM0Qsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDN0QsQ0FBQyxDQUFDO1FBRUgsd0VBQXdFO1FBQ3hFLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxZQUFZLENBQUMsd0JBQXdCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsK0NBQStDLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQ7O09BRUc7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
@@ -0,0 +1,81 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import type { ISmartProxyOptions } from './models/interfaces.js';
3
+ import { RouteConnectionHandler } from './route-connection-handler.js';
4
+ /**
5
+ * PortManager handles the dynamic creation and removal of port listeners
6
+ *
7
+ * This class provides methods to add and remove listening ports at runtime,
8
+ * allowing SmartProxy to adapt to configuration changes without requiring
9
+ * a full restart.
10
+ */
11
+ export declare class PortManager {
12
+ private servers;
13
+ private settings;
14
+ private routeConnectionHandler;
15
+ private isShuttingDown;
16
+ /**
17
+ * Create a new PortManager
18
+ *
19
+ * @param settings The SmartProxy settings
20
+ * @param routeConnectionHandler The handler for new connections
21
+ */
22
+ constructor(settings: ISmartProxyOptions, routeConnectionHandler: RouteConnectionHandler);
23
+ /**
24
+ * Start listening on a specific port
25
+ *
26
+ * @param port The port number to listen on
27
+ * @returns Promise that resolves when the server is listening or rejects on error
28
+ */
29
+ addPort(port: number): Promise<void>;
30
+ /**
31
+ * Stop listening on a specific port
32
+ *
33
+ * @param port The port to stop listening on
34
+ * @returns Promise that resolves when the server is closed
35
+ */
36
+ removePort(port: number): Promise<void>;
37
+ /**
38
+ * Add multiple ports at once
39
+ *
40
+ * @param ports Array of ports to add
41
+ * @returns Promise that resolves when all servers are listening
42
+ */
43
+ addPorts(ports: number[]): Promise<void>;
44
+ /**
45
+ * Remove multiple ports at once
46
+ *
47
+ * @param ports Array of ports to remove
48
+ * @returns Promise that resolves when all servers are closed
49
+ */
50
+ removePorts(ports: number[]): Promise<void>;
51
+ /**
52
+ * Update listening ports to match the provided list
53
+ *
54
+ * This will add any ports that aren't currently listening,
55
+ * and remove any ports that are no longer needed.
56
+ *
57
+ * @param ports Array of ports that should be listening
58
+ * @returns Promise that resolves when all operations are complete
59
+ */
60
+ updatePorts(ports: number[]): Promise<void>;
61
+ /**
62
+ * Get all ports that are currently listening
63
+ *
64
+ * @returns Array of port numbers
65
+ */
66
+ getListeningPorts(): number[];
67
+ /**
68
+ * Mark the port manager as shutting down
69
+ */
70
+ setShuttingDown(isShuttingDown: boolean): void;
71
+ /**
72
+ * Close all listening servers
73
+ *
74
+ * @returns Promise that resolves when all servers are closed
75
+ */
76
+ closeAll(): Promise<void>;
77
+ /**
78
+ * Get all server instances (for testing or debugging)
79
+ */
80
+ getServers(): Map<number, plugins.net.Server>;
81
+ }
@@ -0,0 +1,166 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { RouteConnectionHandler } from './route-connection-handler.js';
3
+ /**
4
+ * PortManager handles the dynamic creation and removal of port listeners
5
+ *
6
+ * This class provides methods to add and remove listening ports at runtime,
7
+ * allowing SmartProxy to adapt to configuration changes without requiring
8
+ * a full restart.
9
+ */
10
+ export class PortManager {
11
+ /**
12
+ * Create a new PortManager
13
+ *
14
+ * @param settings The SmartProxy settings
15
+ * @param routeConnectionHandler The handler for new connections
16
+ */
17
+ constructor(settings, routeConnectionHandler) {
18
+ this.servers = new Map();
19
+ this.isShuttingDown = false;
20
+ this.settings = settings;
21
+ this.routeConnectionHandler = routeConnectionHandler;
22
+ }
23
+ /**
24
+ * Start listening on a specific port
25
+ *
26
+ * @param port The port number to listen on
27
+ * @returns Promise that resolves when the server is listening or rejects on error
28
+ */
29
+ async addPort(port) {
30
+ // Check if we're already listening on this port
31
+ if (this.servers.has(port)) {
32
+ console.log(`PortManager: Already listening on port ${port}`);
33
+ return;
34
+ }
35
+ // Create a server for this port
36
+ const server = plugins.net.createServer((socket) => {
37
+ // Check if shutting down
38
+ if (this.isShuttingDown) {
39
+ socket.end();
40
+ socket.destroy();
41
+ return;
42
+ }
43
+ // Delegate to route connection handler
44
+ this.routeConnectionHandler.handleConnection(socket);
45
+ }).on('error', (err) => {
46
+ console.log(`Server Error on port ${port}: ${err.message}`);
47
+ });
48
+ // Start listening on the port
49
+ return new Promise((resolve, reject) => {
50
+ server.listen(port, () => {
51
+ const isNetworkProxyPort = this.settings.useNetworkProxy?.includes(port);
52
+ console.log(`SmartProxy -> OK: Now listening on port ${port}${isNetworkProxyPort ? ' (NetworkProxy forwarding enabled)' : ''}`);
53
+ // Store the server reference
54
+ this.servers.set(port, server);
55
+ resolve();
56
+ }).on('error', (err) => {
57
+ console.log(`Failed to listen on port ${port}: ${err.message}`);
58
+ reject(err);
59
+ });
60
+ });
61
+ }
62
+ /**
63
+ * Stop listening on a specific port
64
+ *
65
+ * @param port The port to stop listening on
66
+ * @returns Promise that resolves when the server is closed
67
+ */
68
+ async removePort(port) {
69
+ // Get the server for this port
70
+ const server = this.servers.get(port);
71
+ if (!server) {
72
+ console.log(`PortManager: Not listening on port ${port}`);
73
+ return;
74
+ }
75
+ // Close the server
76
+ return new Promise((resolve) => {
77
+ server.close((err) => {
78
+ if (err) {
79
+ console.log(`Error closing server on port ${port}: ${err.message}`);
80
+ }
81
+ else {
82
+ console.log(`SmartProxy -> Stopped listening on port ${port}`);
83
+ }
84
+ // Remove the server reference
85
+ this.servers.delete(port);
86
+ resolve();
87
+ });
88
+ });
89
+ }
90
+ /**
91
+ * Add multiple ports at once
92
+ *
93
+ * @param ports Array of ports to add
94
+ * @returns Promise that resolves when all servers are listening
95
+ */
96
+ async addPorts(ports) {
97
+ const uniquePorts = [...new Set(ports)];
98
+ await Promise.all(uniquePorts.map(port => this.addPort(port)));
99
+ }
100
+ /**
101
+ * Remove multiple ports at once
102
+ *
103
+ * @param ports Array of ports to remove
104
+ * @returns Promise that resolves when all servers are closed
105
+ */
106
+ async removePorts(ports) {
107
+ const uniquePorts = [...new Set(ports)];
108
+ await Promise.all(uniquePorts.map(port => this.removePort(port)));
109
+ }
110
+ /**
111
+ * Update listening ports to match the provided list
112
+ *
113
+ * This will add any ports that aren't currently listening,
114
+ * and remove any ports that are no longer needed.
115
+ *
116
+ * @param ports Array of ports that should be listening
117
+ * @returns Promise that resolves when all operations are complete
118
+ */
119
+ async updatePorts(ports) {
120
+ const targetPorts = new Set(ports);
121
+ const currentPorts = new Set(this.servers.keys());
122
+ // Find ports to add and remove
123
+ const portsToAdd = ports.filter(port => !currentPorts.has(port));
124
+ const portsToRemove = Array.from(currentPorts).filter(port => !targetPorts.has(port));
125
+ // Log the changes
126
+ if (portsToAdd.length > 0) {
127
+ console.log(`PortManager: Adding new listeners for ports: ${portsToAdd.join(', ')}`);
128
+ }
129
+ if (portsToRemove.length > 0) {
130
+ console.log(`PortManager: Removing listeners for ports: ${portsToRemove.join(', ')}`);
131
+ }
132
+ // Add and remove ports
133
+ await this.removePorts(portsToRemove);
134
+ await this.addPorts(portsToAdd);
135
+ }
136
+ /**
137
+ * Get all ports that are currently listening
138
+ *
139
+ * @returns Array of port numbers
140
+ */
141
+ getListeningPorts() {
142
+ return Array.from(this.servers.keys());
143
+ }
144
+ /**
145
+ * Mark the port manager as shutting down
146
+ */
147
+ setShuttingDown(isShuttingDown) {
148
+ this.isShuttingDown = isShuttingDown;
149
+ }
150
+ /**
151
+ * Close all listening servers
152
+ *
153
+ * @returns Promise that resolves when all servers are closed
154
+ */
155
+ async closeAll() {
156
+ const allPorts = Array.from(this.servers.keys());
157
+ await this.removePorts(allPorts);
158
+ }
159
+ /**
160
+ * Get all server instances (for testing or debugging)
161
+ */
162
+ getServers() {
163
+ return new Map(this.servers);
164
+ }
165
+ }
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydC1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcHJveGllcy9zbWFydC1wcm94eS9wb3J0LW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUU1QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUV2RTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sV0FBVztJQU10Qjs7Ozs7T0FLRztJQUNILFlBQ0UsUUFBNEIsRUFDNUIsc0JBQThDO1FBYnhDLFlBQU8sR0FBb0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUdyRCxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQVl0QyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsc0JBQXNCLEdBQUcsc0JBQXNCLENBQUM7SUFDdkQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFZO1FBQy9CLGdEQUFnRDtRQUNoRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDM0IsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUM5RCxPQUFPO1FBQ1QsQ0FBQztRQUVELGdDQUFnQztRQUNoQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ2pELHlCQUF5QjtZQUN6QixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDeEIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDakIsT0FBTztZQUNULENBQUM7WUFFRCx1Q0FBdUM7WUFDdkMsSUFBSSxDQUFDLHNCQUFzQixDQUFD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
@@ -17,7 +17,12 @@ export declare class RouteConnectionHandler {
17
17
  private timeoutManager;
18
18
  private routeManager;
19
19
  private settings;
20
+ private routeContextCache;
20
21
  constructor(settings: ISmartProxyOptions, connectionManager: ConnectionManager, securityManager: SecurityManager, tlsManager: TlsManager, networkProxyBridge: NetworkProxyBridge, timeoutManager: TimeoutManager, routeManager: RouteManager);
22
+ /**
23
+ * Create a route context object for port and host mapping functions
24
+ */
25
+ private createRouteContext;
21
26
  /**
22
27
  * Handle a new incoming connection
23
28
  */