@push.rocks/smartproxy 23.0.0 → 23.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 (161) hide show
  1. package/changelog.md +10 -0
  2. package/dist_rust/{rustproxy → rustproxy_linux_amd64} +0 -0
  3. package/dist_rust/rustproxy_linux_arm64 +0 -0
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/plugins.d.ts +2 -1
  6. package/dist_ts/plugins.js +3 -2
  7. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.d.ts +9 -21
  8. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +83 -212
  9. package/dist_ts/proxies/smart-proxy/smart-proxy.js +2 -3
  10. package/npmextra.json +3 -0
  11. package/package.json +13 -11
  12. package/readme.md +41 -11
  13. package/ts/00_commitinfo_data.ts +1 -1
  14. package/ts/plugins.ts +2 -0
  15. package/ts/proxies/smart-proxy/rust-proxy-bridge.ts +102 -233
  16. package/ts/proxies/smart-proxy/smart-proxy.ts +1 -2
  17. package/dist_ts/common/eventUtils.d.ts +0 -14
  18. package/dist_ts/common/eventUtils.js +0 -20
  19. package/dist_ts/common/types.d.ts +0 -82
  20. package/dist_ts/common/types.js +0 -15
  21. package/dist_ts/core/utils/event-system.d.ts +0 -200
  22. package/dist_ts/core/utils/event-system.js +0 -224
  23. package/dist_ts/core/utils/event-utils.d.ts +0 -15
  24. package/dist_ts/core/utils/event-utils.js +0 -11
  25. package/dist_ts/core/utils/route-manager.d.ts +0 -88
  26. package/dist_ts/core/utils/route-manager.js +0 -342
  27. package/dist_ts/core/utils/route-utils.d.ts +0 -28
  28. package/dist_ts/core/utils/route-utils.js +0 -67
  29. package/dist_ts/detection/detectors/http-detector-v2.d.ts +0 -33
  30. package/dist_ts/detection/detectors/http-detector-v2.js +0 -87
  31. package/dist_ts/detection/detectors/tls-detector-v2.d.ts +0 -33
  32. package/dist_ts/detection/detectors/tls-detector-v2.js +0 -80
  33. package/dist_ts/detection/protocol-detector-v2.d.ts +0 -46
  34. package/dist_ts/detection/protocol-detector-v2.js +0 -116
  35. package/dist_ts/forwarding/config/forwarding-types.d.ts +0 -42
  36. package/dist_ts/forwarding/config/forwarding-types.js +0 -18
  37. package/dist_ts/forwarding/config/index.d.ts +0 -9
  38. package/dist_ts/forwarding/config/index.js +0 -10
  39. package/dist_ts/forwarding/factory/forwarding-factory.d.ts +0 -25
  40. package/dist_ts/forwarding/factory/forwarding-factory.js +0 -172
  41. package/dist_ts/forwarding/factory/index.d.ts +0 -4
  42. package/dist_ts/forwarding/factory/index.js +0 -5
  43. package/dist_ts/forwarding/handlers/base-handler.d.ts +0 -62
  44. package/dist_ts/forwarding/handlers/base-handler.js +0 -121
  45. package/dist_ts/forwarding/handlers/http-handler.d.ts +0 -30
  46. package/dist_ts/forwarding/handlers/http-handler.js +0 -143
  47. package/dist_ts/forwarding/handlers/https-passthrough-handler.d.ts +0 -29
  48. package/dist_ts/forwarding/handlers/https-passthrough-handler.js +0 -156
  49. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.d.ts +0 -36
  50. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.js +0 -276
  51. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.d.ts +0 -35
  52. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.js +0 -261
  53. package/dist_ts/forwarding/handlers/index.d.ts +0 -8
  54. package/dist_ts/forwarding/handlers/index.js +0 -9
  55. package/dist_ts/forwarding/index.d.ts +0 -13
  56. package/dist_ts/forwarding/index.js +0 -16
  57. package/dist_ts/http/index.d.ts +0 -5
  58. package/dist_ts/http/index.js +0 -8
  59. package/dist_ts/http/models/http-types.d.ts +0 -6
  60. package/dist_ts/http/models/http-types.js +0 -7
  61. package/dist_ts/http/router/index.d.ts +0 -8
  62. package/dist_ts/http/router/index.js +0 -7
  63. package/dist_ts/http/router/proxy-router.d.ts +0 -115
  64. package/dist_ts/http/router/proxy-router.js +0 -325
  65. package/dist_ts/http/router/route-router.d.ts +0 -108
  66. package/dist_ts/http/router/route-router.js +0 -393
  67. package/dist_ts/protocols/tls/constants.d.ts +0 -122
  68. package/dist_ts/protocols/tls/constants.js +0 -135
  69. package/dist_ts/protocols/tls/parser.d.ts +0 -53
  70. package/dist_ts/protocols/tls/parser.js +0 -294
  71. package/dist_ts/protocols/tls/types.d.ts +0 -65
  72. package/dist_ts/protocols/tls/types.js +0 -5
  73. package/dist_ts/proxies/http-proxy/certificate-manager.d.ts +0 -95
  74. package/dist_ts/proxies/http-proxy/certificate-manager.js +0 -214
  75. package/dist_ts/proxies/http-proxy/connection-pool.d.ts +0 -47
  76. package/dist_ts/proxies/http-proxy/connection-pool.js +0 -195
  77. package/dist_ts/proxies/http-proxy/context-creator.d.ts +0 -34
  78. package/dist_ts/proxies/http-proxy/context-creator.js +0 -108
  79. package/dist_ts/proxies/http-proxy/default-certificates.d.ts +0 -54
  80. package/dist_ts/proxies/http-proxy/default-certificates.js +0 -127
  81. package/dist_ts/proxies/http-proxy/function-cache.d.ts +0 -95
  82. package/dist_ts/proxies/http-proxy/function-cache.js +0 -215
  83. package/dist_ts/proxies/http-proxy/handlers/index.d.ts +0 -4
  84. package/dist_ts/proxies/http-proxy/handlers/index.js +0 -6
  85. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.d.ts +0 -18
  86. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.js +0 -78
  87. package/dist_ts/proxies/http-proxy/handlers/static-handler.d.ts +0 -19
  88. package/dist_ts/proxies/http-proxy/handlers/static-handler.js +0 -211
  89. package/dist_ts/proxies/http-proxy/http-proxy.d.ts +0 -117
  90. package/dist_ts/proxies/http-proxy/http-proxy.js +0 -521
  91. package/dist_ts/proxies/http-proxy/http-request-handler.d.ts +0 -40
  92. package/dist_ts/proxies/http-proxy/http-request-handler.js +0 -257
  93. package/dist_ts/proxies/http-proxy/http2-request-handler.d.ts +0 -24
  94. package/dist_ts/proxies/http-proxy/http2-request-handler.js +0 -201
  95. package/dist_ts/proxies/http-proxy/index.d.ts +0 -14
  96. package/dist_ts/proxies/http-proxy/index.js +0 -16
  97. package/dist_ts/proxies/http-proxy/models/http-types.d.ts +0 -117
  98. package/dist_ts/proxies/http-proxy/models/http-types.js +0 -92
  99. package/dist_ts/proxies/http-proxy/models/index.d.ts +0 -5
  100. package/dist_ts/proxies/http-proxy/models/index.js +0 -6
  101. package/dist_ts/proxies/http-proxy/models/types.d.ts +0 -75
  102. package/dist_ts/proxies/http-proxy/models/types.js +0 -35
  103. package/dist_ts/proxies/http-proxy/request-handler.d.ts +0 -97
  104. package/dist_ts/proxies/http-proxy/request-handler.js +0 -737
  105. package/dist_ts/proxies/http-proxy/security-manager.d.ts +0 -98
  106. package/dist_ts/proxies/http-proxy/security-manager.js +0 -341
  107. package/dist_ts/proxies/http-proxy/websocket-handler.d.ts +0 -50
  108. package/dist_ts/proxies/http-proxy/websocket-handler.js +0 -505
  109. package/dist_ts/proxies/smart-proxy/acme-state-manager.d.ts +0 -42
  110. package/dist_ts/proxies/smart-proxy/acme-state-manager.js +0 -101
  111. package/dist_ts/proxies/smart-proxy/cert-store.d.ts +0 -10
  112. package/dist_ts/proxies/smart-proxy/cert-store.js +0 -72
  113. package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +0 -164
  114. package/dist_ts/proxies/smart-proxy/certificate-manager.js +0 -745
  115. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +0 -128
  116. package/dist_ts/proxies/smart-proxy/connection-manager.js +0 -689
  117. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +0 -43
  118. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +0 -180
  119. package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +0 -98
  120. package/dist_ts/proxies/smart-proxy/metrics-collector.js +0 -355
  121. package/dist_ts/proxies/smart-proxy/nftables-manager.d.ts +0 -82
  122. package/dist_ts/proxies/smart-proxy/nftables-manager.js +0 -237
  123. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +0 -117
  124. package/dist_ts/proxies/smart-proxy/port-manager.js +0 -318
  125. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +0 -60
  126. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +0 -1407
  127. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +0 -112
  128. package/dist_ts/proxies/smart-proxy/route-manager.js +0 -453
  129. package/dist_ts/proxies/smart-proxy/route-orchestrator.d.ts +0 -56
  130. package/dist_ts/proxies/smart-proxy/route-orchestrator.js +0 -204
  131. package/dist_ts/proxies/smart-proxy/rust-binary-locator.d.ts +0 -23
  132. package/dist_ts/proxies/smart-proxy/rust-binary-locator.js +0 -104
  133. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +0 -74
  134. package/dist_ts/proxies/smart-proxy/security-manager.js +0 -227
  135. package/dist_ts/proxies/smart-proxy/throughput-tracker.d.ts +0 -36
  136. package/dist_ts/proxies/smart-proxy/throughput-tracker.js +0 -115
  137. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +0 -48
  138. package/dist_ts/proxies/smart-proxy/timeout-manager.js +0 -158
  139. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +0 -50
  140. package/dist_ts/proxies/smart-proxy/tls-manager.js +0 -110
  141. package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +0 -161
  142. package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +0 -282
  143. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +0 -73
  144. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +0 -259
  145. package/dist_ts/routing/router/proxy-router.d.ts +0 -115
  146. package/dist_ts/routing/router/proxy-router.js +0 -325
  147. package/dist_ts/routing/router/route-router.d.ts +0 -108
  148. package/dist_ts/routing/router/route-router.js +0 -393
  149. package/dist_ts/tls/alerts/index.d.ts +0 -4
  150. package/dist_ts/tls/alerts/index.js +0 -5
  151. package/dist_ts/tls/alerts/tls-alert.d.ts +0 -150
  152. package/dist_ts/tls/alerts/tls-alert.js +0 -226
  153. package/dist_ts/tls/sni/client-hello-parser.d.ts +0 -100
  154. package/dist_ts/tls/sni/client-hello-parser.js +0 -464
  155. package/dist_ts/tls/sni/sni-extraction.d.ts +0 -58
  156. package/dist_ts/tls/sni/sni-extraction.js +0 -275
  157. package/dist_ts/tls/utils/index.d.ts +0 -4
  158. package/dist_ts/tls/utils/index.js +0 -5
  159. package/dist_ts/tls/utils/tls-utils.d.ts +0 -49
  160. package/dist_ts/tls/utils/tls-utils.js +0 -75
  161. package/ts/proxies/smart-proxy/rust-binary-locator.ts +0 -112
@@ -1,521 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import { createLogger, } from './models/types.js';
3
- import { SharedRouteManager as RouteManager } from '../../core/routing/route-manager.js';
4
- import { createBaseRouteContext } from '../../core/models/route-context.js';
5
- import { DefaultCertificateProvider } from './default-certificates.js';
6
- import { ConnectionPool } from './connection-pool.js';
7
- import { RequestHandler } from './request-handler.js';
8
- import { WebSocketHandler } from './websocket-handler.js';
9
- import { HttpRouter } from '../../routing/router/index.js';
10
- import { cleanupSocket } from '../../core/utils/socket-utils.js';
11
- import { FunctionCache } from './function-cache.js';
12
- import { SecurityManager } from './security-manager.js';
13
- import { connectionLogDeduplicator } from '../../core/utils/log-deduplicator.js';
14
- /**
15
- * HttpProxy provides a reverse proxy with TLS termination, WebSocket support,
16
- * automatic certificate management, and high-performance connection pooling.
17
- * Handles all HTTP/HTTPS traffic including redirects, ACME challenges, and static routes.
18
- */
19
- export class HttpProxy {
20
- // Provide a minimal JSON representation to avoid circular references during deep equality checks
21
- toJSON() {
22
- return {};
23
- }
24
- /**
25
- * Creates a new HttpProxy instance
26
- */
27
- constructor(optionsArg) {
28
- this.routes = [];
29
- this.router = new HttpRouter(); // Unified HTTP router
30
- // State tracking
31
- this.socketMap = new plugins.lik.ObjectMap();
32
- this.activeContexts = new Set();
33
- this.connectedClients = 0;
34
- this.startTime = 0;
35
- this.requestsServed = 0;
36
- this.failedRequests = 0;
37
- // Tracking for SmartProxy integration
38
- this.portProxyConnections = 0;
39
- this.tlsTerminatedConnections = 0;
40
- // Set default options
41
- this.options = {
42
- port: optionsArg.port,
43
- maxConnections: optionsArg.maxConnections || 10000,
44
- keepAliveTimeout: optionsArg.keepAliveTimeout || 120000, // 2 minutes
45
- headersTimeout: optionsArg.headersTimeout || 60000, // 1 minute
46
- logLevel: optionsArg.logLevel || 'info',
47
- cors: optionsArg.cors || {
48
- allowOrigin: '*',
49
- allowMethods: 'GET, POST, PUT, DELETE, OPTIONS',
50
- allowHeaders: 'Content-Type, Authorization',
51
- maxAge: 86400
52
- },
53
- // Defaults for SmartProxy integration
54
- connectionPoolSize: optionsArg.connectionPoolSize || 50,
55
- portProxyIntegration: optionsArg.portProxyIntegration || false,
56
- // Backend protocol (http1 or http2)
57
- backendProtocol: optionsArg.backendProtocol || 'http1',
58
- // Default ACME options
59
- acme: {
60
- enabled: optionsArg.acme?.enabled || false,
61
- port: optionsArg.acme?.port || 80,
62
- accountEmail: optionsArg.acme?.accountEmail || 'admin@example.com',
63
- useProduction: optionsArg.acme?.useProduction || false, // Default to staging for safety
64
- renewThresholdDays: optionsArg.acme?.renewThresholdDays || 30,
65
- autoRenew: optionsArg.acme?.autoRenew !== false, // Default to true
66
- certificateStore: optionsArg.acme?.certificateStore || './certs',
67
- skipConfiguredCerts: optionsArg.acme?.skipConfiguredCerts || false
68
- }
69
- };
70
- // Initialize logger
71
- this.logger = createLogger(this.options.logLevel);
72
- // Initialize route manager
73
- this.routeManager = new RouteManager({
74
- logger: this.logger,
75
- enableDetailedLogging: this.options.logLevel === 'debug',
76
- routes: []
77
- });
78
- // Initialize function cache
79
- this.functionCache = new FunctionCache(this.logger, {
80
- maxCacheSize: this.options.functionCacheSize || 1000,
81
- defaultTtl: this.options.functionCacheTtl || 5000
82
- });
83
- // Initialize security manager
84
- this.securityManager = new SecurityManager(this.logger, [], this.options.maxConnectionsPerIP || 100, this.options.connectionRateLimitPerMinute || 300);
85
- // Initialize other components
86
- this.defaultCertProvider = new DefaultCertificateProvider(this.logger);
87
- this.connectionPool = new ConnectionPool(this.options);
88
- this.requestHandler = new RequestHandler(this.options, this.connectionPool, this.routeManager, this.functionCache, this.router);
89
- this.webSocketHandler = new WebSocketHandler(this.options, this.connectionPool, this.routes // Pass current routes to WebSocketHandler
90
- );
91
- // Connect request handler to this metrics tracker
92
- this.requestHandler.setMetricsTracker(this);
93
- // Initialize with any provided routes
94
- if (this.options.routes && this.options.routes.length > 0) {
95
- this.updateRouteConfigs(this.options.routes);
96
- }
97
- }
98
- /**
99
- * Implements IMetricsTracker interface to increment request counters
100
- */
101
- incrementRequestsServed() {
102
- this.requestsServed++;
103
- }
104
- /**
105
- * Implements IMetricsTracker interface to increment failed request counters
106
- */
107
- incrementFailedRequests() {
108
- this.failedRequests++;
109
- }
110
- /**
111
- * Returns the port number this HttpProxy is listening on
112
- * Useful for SmartProxy to determine where to forward connections
113
- */
114
- getListeningPort() {
115
- // If the server is running, get the actual listening port
116
- if (this.httpsServer && this.httpsServer.address()) {
117
- const address = this.httpsServer.address();
118
- if (address && typeof address === 'object' && 'port' in address) {
119
- return address.port;
120
- }
121
- }
122
- // Fallback to configured port
123
- return this.options.port;
124
- }
125
- /**
126
- * Updates the server capacity settings
127
- * @param maxConnections Maximum number of simultaneous connections
128
- * @param keepAliveTimeout Keep-alive timeout in milliseconds
129
- * @param connectionPoolSize Size of the connection pool per backend
130
- */
131
- updateCapacity(maxConnections, keepAliveTimeout, connectionPoolSize) {
132
- if (maxConnections !== undefined) {
133
- this.options.maxConnections = maxConnections;
134
- this.logger.info(`Updated max connections to ${maxConnections}`);
135
- }
136
- if (keepAliveTimeout !== undefined) {
137
- this.options.keepAliveTimeout = keepAliveTimeout;
138
- if (this.httpsServer) {
139
- // HTTP/2 servers have setTimeout method for timeout management
140
- this.httpsServer.setTimeout(keepAliveTimeout);
141
- this.logger.info(`Updated server timeout to ${keepAliveTimeout}ms`);
142
- }
143
- }
144
- if (connectionPoolSize !== undefined) {
145
- this.options.connectionPoolSize = connectionPoolSize;
146
- this.logger.info(`Updated connection pool size to ${connectionPoolSize}`);
147
- // Clean up excess connections in the pool
148
- this.connectionPool.cleanupConnectionPool();
149
- }
150
- }
151
- /**
152
- * Returns current server metrics
153
- * Useful for SmartProxy to determine which HttpProxy to use for load balancing
154
- */
155
- getMetrics() {
156
- return {
157
- activeConnections: this.connectedClients,
158
- totalRequests: this.requestsServed,
159
- failedRequests: this.failedRequests,
160
- portProxyConnections: this.portProxyConnections,
161
- tlsTerminatedConnections: this.tlsTerminatedConnections,
162
- connectionPoolSize: this.connectionPool.getPoolStatus(),
163
- uptime: Math.floor((Date.now() - this.startTime) / 1000),
164
- memoryUsage: process.memoryUsage(),
165
- activeWebSockets: this.webSocketHandler.getConnectionInfo().activeConnections,
166
- functionCache: this.functionCache.getStats()
167
- };
168
- }
169
- /**
170
- * Starts the proxy server
171
- */
172
- async start() {
173
- this.startTime = Date.now();
174
- // Create HTTP/2 server with HTTP/1 fallback
175
- const defaultCerts = this.defaultCertProvider.getDefaultCertificates();
176
- this.httpsServer = plugins.http2.createSecureServer({
177
- key: defaultCerts.key,
178
- cert: defaultCerts.cert,
179
- allowHTTP1: true,
180
- ALPNProtocols: ['h2', 'http/1.1']
181
- });
182
- // Track raw TCP connections for metrics and limits
183
- this.setupConnectionTracking();
184
- // Handle incoming HTTP/2 streams
185
- this.httpsServer.on('stream', (stream, headers) => {
186
- this.requestHandler.handleHttp2(stream, headers);
187
- });
188
- // Handle HTTP/1.x fallback requests
189
- this.httpsServer.on('request', (req, res) => {
190
- this.requestHandler.handleRequest(req, res);
191
- });
192
- // Setup WebSocket support on HTTP/1 fallback
193
- this.webSocketHandler.initialize(this.httpsServer);
194
- // Start metrics logging
195
- this.setupMetricsCollection();
196
- // Start periodic connection pool cleanup
197
- this.connectionPoolCleanupInterval = this.connectionPool.setupPeriodicCleanup();
198
- // Start the server
199
- return new Promise((resolve) => {
200
- this.httpsServer.listen(this.options.port, () => {
201
- this.logger.info(`HttpProxy started on port ${this.options.port}`);
202
- resolve();
203
- });
204
- });
205
- }
206
- /**
207
- * Check if an address is a loopback address (IPv4 or IPv6)
208
- */
209
- isLoopback(addr) {
210
- if (!addr)
211
- return false;
212
- // Check for IPv6 loopback
213
- if (addr === '::1')
214
- return true;
215
- // Handle IPv6-mapped IPv4 addresses
216
- if (addr.startsWith('::ffff:')) {
217
- addr = addr.substring(7);
218
- }
219
- // Check for IPv4 loopback range (127.0.0.0/8)
220
- return addr.startsWith('127.');
221
- }
222
- /**
223
- * Sets up tracking of TCP connections
224
- */
225
- setupConnectionTracking() {
226
- this.httpsServer.on('connection', (connection) => {
227
- let remoteIP = connection.remoteAddress || '';
228
- const connectionId = Math.random().toString(36).substring(2, 15);
229
- const isFromSmartProxy = this.options.portProxyIntegration && this.isLoopback(connection.remoteAddress);
230
- // For SmartProxy connections, wait for CLIENT_IP header
231
- if (isFromSmartProxy) {
232
- const MAX_PREFACE = 256; // bytes - prevent DoS
233
- const HEADER_TIMEOUT_MS = 2000; // timeout for header parsing (increased for slow networks)
234
- let headerTimer;
235
- let buffered = Buffer.alloc(0);
236
- const onData = (chunk) => {
237
- buffered = Buffer.concat([buffered, chunk]);
238
- // Prevent unbounded growth
239
- if (buffered.length > MAX_PREFACE) {
240
- connection.removeListener('data', onData);
241
- if (headerTimer)
242
- clearTimeout(headerTimer);
243
- this.logger.warn('Header preface too large, closing connection');
244
- connection.destroy();
245
- return;
246
- }
247
- const idx = buffered.indexOf('\r\n');
248
- if (idx !== -1) {
249
- const headerLine = buffered.slice(0, idx).toString('utf8');
250
- if (headerLine.startsWith('CLIENT_IP:')) {
251
- remoteIP = headerLine.substring(10).trim();
252
- this.logger.debug(`Extracted client IP from SmartProxy: ${remoteIP}`);
253
- }
254
- // Clean up listener and timer
255
- connection.removeListener('data', onData);
256
- if (headerTimer)
257
- clearTimeout(headerTimer);
258
- // Put remaining data back onto the stream
259
- const remaining = buffered.slice(idx + 2);
260
- if (remaining.length > 0) {
261
- connection.unshift(remaining);
262
- }
263
- // Store the real IP on the connection
264
- connection._realRemoteIP = remoteIP;
265
- // Validate the real IP
266
- const ipValidation = this.securityManager.validateIP(remoteIP);
267
- if (!ipValidation.allowed) {
268
- connectionLogDeduplicator.log('ip-rejected', 'warn', `HttpProxy connection rejected (via SmartProxy)`, { remoteIP, reason: ipValidation.reason, component: 'http-proxy' }, remoteIP);
269
- connection.destroy();
270
- return;
271
- }
272
- // Track connection by real IP
273
- this.securityManager.trackConnectionByIP(remoteIP, connectionId);
274
- }
275
- };
276
- // Set timeout for header parsing
277
- headerTimer = setTimeout(() => {
278
- connection.removeListener('data', onData);
279
- this.logger.warn('Header parsing timeout, closing connection');
280
- connection.destroy();
281
- }, HEADER_TIMEOUT_MS);
282
- // Unref the timer so it doesn't keep the process alive
283
- if (headerTimer.unref)
284
- headerTimer.unref();
285
- // Use prependListener to get data first
286
- connection.prependListener('data', onData);
287
- }
288
- else {
289
- // Direct connection - validate immediately
290
- const ipValidation = this.securityManager.validateIP(remoteIP);
291
- if (!ipValidation.allowed) {
292
- connectionLogDeduplicator.log('ip-rejected', 'warn', `HttpProxy connection rejected`, { remoteIP, reason: ipValidation.reason, component: 'http-proxy' }, remoteIP);
293
- connection.destroy();
294
- return;
295
- }
296
- // Track connection by IP
297
- this.securityManager.trackConnectionByIP(remoteIP, connectionId);
298
- }
299
- // Then check global max connections
300
- if (this.socketMap.getArray().length >= this.options.maxConnections) {
301
- connectionLogDeduplicator.log('connection-rejected', 'warn', 'HttpProxy max connections reached', {
302
- reason: 'global-limit',
303
- currentConnections: this.socketMap.getArray().length,
304
- maxConnections: this.options.maxConnections,
305
- component: 'http-proxy'
306
- }, 'http-proxy-global-limit');
307
- connection.destroy();
308
- return;
309
- }
310
- // Add connection to tracking with metadata
311
- connection._connectionId = connectionId;
312
- connection._remoteIP = remoteIP;
313
- this.socketMap.add(connection);
314
- this.connectedClients = this.socketMap.getArray().length;
315
- // Check for connection from SmartProxy by inspecting the source port
316
- const localPort = connection.localPort || 0;
317
- const remotePort = connection.remotePort || 0;
318
- // If this connection is from a SmartProxy
319
- if (isFromSmartProxy) {
320
- this.portProxyConnections++;
321
- this.logger.debug(`New connection from SmartProxy for client ${remoteIP} (local: ${localPort}, remote: ${remotePort})`);
322
- }
323
- else {
324
- this.logger.debug(`New direct connection from ${remoteIP} (local: ${localPort}, remote: ${remotePort})`);
325
- }
326
- // Setup connection cleanup handlers
327
- const cleanupConnection = () => {
328
- if (this.socketMap.checkForObject(connection)) {
329
- this.socketMap.remove(connection);
330
- this.connectedClients = this.socketMap.getArray().length;
331
- // Remove IP tracking
332
- const connId = connection._connectionId;
333
- const connIP = connection._realRemoteIP || connection._remoteIP;
334
- if (connId && connIP) {
335
- this.securityManager.removeConnectionByIP(connIP, connId);
336
- }
337
- // If this was a SmartProxy connection, decrement the counter
338
- if (this.options.portProxyIntegration && connection.remoteAddress?.includes('127.0.0.1')) {
339
- this.portProxyConnections--;
340
- }
341
- this.logger.debug(`Connection closed from ${connIP || 'unknown'}. ${this.connectedClients} connections remaining`);
342
- }
343
- };
344
- connection.on('close', cleanupConnection);
345
- connection.on('error', (err) => {
346
- this.logger.debug('Connection error', err);
347
- cleanupConnection();
348
- });
349
- connection.on('end', cleanupConnection);
350
- });
351
- // Track TLS handshake completions
352
- this.httpsServer.on('secureConnection', (tlsSocket) => {
353
- this.tlsTerminatedConnections++;
354
- this.logger.debug('TLS handshake completed, connection secured');
355
- });
356
- }
357
- /**
358
- * Sets up metrics collection
359
- */
360
- setupMetricsCollection() {
361
- this.metricsInterval = setInterval(() => {
362
- const uptime = Math.floor((Date.now() - this.startTime) / 1000);
363
- const metrics = {
364
- uptime,
365
- activeConnections: this.connectedClients,
366
- totalRequests: this.requestsServed,
367
- failedRequests: this.failedRequests,
368
- portProxyConnections: this.portProxyConnections,
369
- tlsTerminatedConnections: this.tlsTerminatedConnections,
370
- activeWebSockets: this.webSocketHandler.getConnectionInfo().activeConnections,
371
- memoryUsage: process.memoryUsage(),
372
- activeContexts: Array.from(this.activeContexts),
373
- connectionPool: this.connectionPool.getPoolStatus()
374
- };
375
- this.logger.debug('Proxy metrics', metrics);
376
- }, 60000); // Log metrics every minute
377
- // Don't keep process alive just for metrics
378
- if (this.metricsInterval.unref) {
379
- this.metricsInterval.unref();
380
- }
381
- }
382
- /**
383
- * Updates the route configurations - this is the primary method for configuring HttpProxy
384
- * @param routes The new route configurations to use
385
- */
386
- async updateRouteConfigs(routes) {
387
- this.logger.info(`Updating route configurations (${routes.length} routes)`);
388
- // Update routes in RouteManager, modern router, WebSocketHandler, and SecurityManager
389
- this.routeManager.updateRoutes(routes);
390
- this.router.setRoutes(routes);
391
- this.webSocketHandler.setRoutes(routes);
392
- this.requestHandler.securityManager.setRoutes(routes);
393
- this.routes = routes;
394
- // Collect all domains and certificates for configuration
395
- const currentHostnames = new Set();
396
- const certificateUpdates = new Map();
397
- // Process each route to extract domain and certificate information
398
- for (const route of routes) {
399
- // Skip non-forward routes or routes without domains
400
- if (route.action.type !== 'forward' || !route.match.domains) {
401
- continue;
402
- }
403
- // Get domains from route
404
- const domains = Array.isArray(route.match.domains)
405
- ? route.match.domains
406
- : [route.match.domains];
407
- // Process each domain
408
- for (const domain of domains) {
409
- // Skip wildcard domains for direct host configuration
410
- if (domain.includes('*')) {
411
- continue;
412
- }
413
- currentHostnames.add(domain);
414
- // Check if we have a static certificate for this domain
415
- if (route.action.tls?.certificate && route.action.tls.certificate !== 'auto') {
416
- certificateUpdates.set(domain, {
417
- cert: route.action.tls.certificate.cert,
418
- key: route.action.tls.certificate.key
419
- });
420
- }
421
- }
422
- }
423
- // Update certificate cache with any static certificates
424
- for (const [domain, certData] of certificateUpdates.entries()) {
425
- try {
426
- this.defaultCertProvider.updateCertificate(domain, certData.cert, certData.key);
427
- this.activeContexts.add(domain);
428
- }
429
- catch (error) {
430
- this.logger.error(`Failed to add SSL context for ${domain}`, error);
431
- }
432
- }
433
- // Clean up removed contexts
434
- for (const hostname of this.activeContexts) {
435
- if (!currentHostnames.has(hostname)) {
436
- this.logger.info(`Hostname ${hostname} removed from configuration`);
437
- this.activeContexts.delete(hostname);
438
- }
439
- }
440
- // Update the router with new routes
441
- this.router.setRoutes(routes);
442
- // Update WebSocket handler with new routes
443
- this.webSocketHandler.setRoutes(routes);
444
- this.logger.info(`Route configuration updated with ${routes.length} routes`);
445
- }
446
- // Legacy methods have been removed.
447
- // Please use updateRouteConfigs() directly with modern route-based configuration.
448
- /**
449
- * Adds default headers to be included in all responses
450
- */
451
- async addDefaultHeaders(headersArg) {
452
- this.logger.info('Adding default headers', headersArg);
453
- this.requestHandler.setDefaultHeaders(headersArg);
454
- }
455
- /**
456
- * Stops the proxy server
457
- */
458
- async stop() {
459
- this.logger.info('Stopping HttpProxy server');
460
- // Clear intervals
461
- if (this.metricsInterval) {
462
- clearInterval(this.metricsInterval);
463
- }
464
- if (this.connectionPoolCleanupInterval) {
465
- clearInterval(this.connectionPoolCleanupInterval);
466
- }
467
- // Stop WebSocket handler
468
- this.webSocketHandler.shutdown();
469
- // Destroy request handler (cleans up intervals and caches)
470
- if (this.requestHandler && typeof this.requestHandler.destroy === 'function') {
471
- this.requestHandler.destroy();
472
- }
473
- // Close all tracked sockets
474
- const socketCleanupPromises = this.socketMap.getArray().map(socket => cleanupSocket(socket, 'http-proxy-stop', { immediate: true }));
475
- await Promise.all(socketCleanupPromises);
476
- // Close all connection pool connections
477
- this.connectionPool.closeAllConnections();
478
- // Certificate management cleanup is handled by SmartCertManager
479
- // Flush any pending deduplicated logs
480
- connectionLogDeduplicator.flushAll();
481
- // Close the HTTPS server
482
- return new Promise((resolve) => {
483
- this.httpsServer.close(() => {
484
- this.logger.info('HttpProxy server stopped successfully');
485
- resolve();
486
- });
487
- });
488
- }
489
- /**
490
- * Requests a new certificate for a domain
491
- * This can be used to manually trigger certificate issuance
492
- * @param domain The domain to request a certificate for
493
- * @returns A promise that resolves when the request is submitted (not when the certificate is issued)
494
- */
495
- async requestCertificate(domain) {
496
- this.logger.warn('requestCertificate is deprecated - use SmartCertManager instead');
497
- return false;
498
- }
499
- /**
500
- * Update certificate for a domain
501
- *
502
- * This method allows direct updates of certificates from external sources
503
- * like Port80Handler or custom certificate providers.
504
- *
505
- * @param domain The domain to update certificate for
506
- * @param certificate The new certificate (public key)
507
- * @param privateKey The new private key
508
- * @param expiryDate Optional expiry date
509
- */
510
- updateCertificate(domain, certificate, privateKey, expiryDate) {
511
- this.logger.info(`Updating certificate for ${domain}`);
512
- this.defaultCertProvider.updateCertificate(domain, certificate, privateKey);
513
- }
514
- /**
515
- * Gets all route configurations currently in use
516
- */
517
- getRouteConfigs() {
518
- return this.routeManager.getRoutes();
519
- }
520
- }
521
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1wcm94eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3hpZXMvaHR0cC1wcm94eS9odHRwLXByb3h5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUNMLFlBQVksR0FDYixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxrQkFBa0IsSUFBSSxZQUFZLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQU96RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN2RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGNBQWMsRUFBd0IsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDeEQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFFakY7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyxTQUFTO0lBQ3BCLGlHQUFpRztJQUMxRixNQUFNO1FBQ1gsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBcUNEOztPQUVHO0lBQ0gsWUFBWSxVQUE2QjtRQXJDbEMsV0FBTSxHQUFtQixFQUFFLENBQUM7UUFVM0IsV0FBTSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQyxzQkFBc0I7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
@@ -1,40 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import '../../core/models/socket-augmentation.js';
3
- import type { IHttpRouteContext } from '../../core/models/route-context.js';
4
- import type { ILogger } from './models/types.js';
5
- import type { IMetricsTracker } from './request-handler.js';
6
- import type { IRouteConfig } from '../smart-proxy/models/route-types.js';
7
- /**
8
- * HTTP Request Handler Helper - handles requests with specific destinations
9
- * This is a helper class for the main RequestHandler
10
- */
11
- export declare class HttpRequestHandler {
12
- /**
13
- * Handle HTTP request with a specific destination
14
- */
15
- static handleHttpRequestWithDestination(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse, destination: {
16
- host: string;
17
- port: number;
18
- }, routeContext: IHttpRouteContext, startTime: number, logger: ILogger, metricsTracker?: IMetricsTracker | null, route?: IRouteConfig): Promise<void>;
19
- /**
20
- * Apply URL rewriting based on route configuration
21
- * Implements Phase 5.2: URL rewriting using route context
22
- *
23
- * @param req The request with the URL to rewrite
24
- * @param route The route configuration containing rewrite rules
25
- * @param routeContext Context for template variable resolution
26
- * @param logger Logger for debugging information
27
- * @returns True if URL was rewritten, false otherwise
28
- */
29
- private static applyUrlRewriting;
30
- /**
31
- * Apply header modifications from route configuration to request headers
32
- * Implements Phase 5.1: Route-based header manipulation for requests
33
- */
34
- private static applyRouteHeaderModifications;
35
- /**
36
- * Apply header modifications from route configuration to response headers
37
- * Implements Phase 5.1: Route-based header manipulation for responses
38
- */
39
- private static applyResponseHeaderModifications;
40
- }