@push.rocks/smartproxy 22.6.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 (196) hide show
  1. package/changelog.md +18 -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/index.d.ts +0 -1
  6. package/dist_ts/index.js +1 -3
  7. package/dist_ts/plugins.d.ts +2 -1
  8. package/dist_ts/plugins.js +3 -2
  9. package/dist_ts/proxies/index.d.ts +0 -1
  10. package/dist_ts/proxies/index.js +1 -3
  11. package/dist_ts/proxies/smart-proxy/models/route-types.js +1 -1
  12. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.d.ts +9 -21
  13. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +83 -212
  14. package/dist_ts/proxies/smart-proxy/smart-proxy.js +2 -3
  15. package/npmextra.json +3 -0
  16. package/package.json +13 -11
  17. package/readme.md +35 -31
  18. package/ts/00_commitinfo_data.ts +1 -1
  19. package/ts/index.ts +0 -3
  20. package/ts/plugins.ts +2 -0
  21. package/ts/proxies/index.ts +0 -3
  22. package/ts/proxies/smart-proxy/models/route-types.ts +0 -2
  23. package/ts/proxies/smart-proxy/rust-proxy-bridge.ts +102 -233
  24. package/ts/proxies/smart-proxy/smart-proxy.ts +1 -2
  25. package/dist_ts/common/eventUtils.d.ts +0 -14
  26. package/dist_ts/common/eventUtils.js +0 -20
  27. package/dist_ts/common/types.d.ts +0 -82
  28. package/dist_ts/common/types.js +0 -15
  29. package/dist_ts/core/utils/event-system.d.ts +0 -200
  30. package/dist_ts/core/utils/event-system.js +0 -224
  31. package/dist_ts/core/utils/event-utils.d.ts +0 -15
  32. package/dist_ts/core/utils/event-utils.js +0 -11
  33. package/dist_ts/core/utils/route-manager.d.ts +0 -88
  34. package/dist_ts/core/utils/route-manager.js +0 -342
  35. package/dist_ts/core/utils/route-utils.d.ts +0 -28
  36. package/dist_ts/core/utils/route-utils.js +0 -67
  37. package/dist_ts/detection/detectors/http-detector-v2.d.ts +0 -33
  38. package/dist_ts/detection/detectors/http-detector-v2.js +0 -87
  39. package/dist_ts/detection/detectors/tls-detector-v2.d.ts +0 -33
  40. package/dist_ts/detection/detectors/tls-detector-v2.js +0 -80
  41. package/dist_ts/detection/protocol-detector-v2.d.ts +0 -46
  42. package/dist_ts/detection/protocol-detector-v2.js +0 -116
  43. package/dist_ts/forwarding/config/forwarding-types.d.ts +0 -42
  44. package/dist_ts/forwarding/config/forwarding-types.js +0 -18
  45. package/dist_ts/forwarding/config/index.d.ts +0 -9
  46. package/dist_ts/forwarding/config/index.js +0 -10
  47. package/dist_ts/forwarding/factory/forwarding-factory.d.ts +0 -25
  48. package/dist_ts/forwarding/factory/forwarding-factory.js +0 -172
  49. package/dist_ts/forwarding/factory/index.d.ts +0 -4
  50. package/dist_ts/forwarding/factory/index.js +0 -5
  51. package/dist_ts/forwarding/handlers/base-handler.d.ts +0 -62
  52. package/dist_ts/forwarding/handlers/base-handler.js +0 -121
  53. package/dist_ts/forwarding/handlers/http-handler.d.ts +0 -30
  54. package/dist_ts/forwarding/handlers/http-handler.js +0 -143
  55. package/dist_ts/forwarding/handlers/https-passthrough-handler.d.ts +0 -29
  56. package/dist_ts/forwarding/handlers/https-passthrough-handler.js +0 -156
  57. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.d.ts +0 -36
  58. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.js +0 -276
  59. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.d.ts +0 -35
  60. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.js +0 -261
  61. package/dist_ts/forwarding/handlers/index.d.ts +0 -8
  62. package/dist_ts/forwarding/handlers/index.js +0 -9
  63. package/dist_ts/forwarding/index.d.ts +0 -13
  64. package/dist_ts/forwarding/index.js +0 -16
  65. package/dist_ts/http/index.d.ts +0 -5
  66. package/dist_ts/http/index.js +0 -8
  67. package/dist_ts/http/models/http-types.d.ts +0 -6
  68. package/dist_ts/http/models/http-types.js +0 -7
  69. package/dist_ts/http/router/index.d.ts +0 -8
  70. package/dist_ts/http/router/index.js +0 -7
  71. package/dist_ts/http/router/proxy-router.d.ts +0 -115
  72. package/dist_ts/http/router/proxy-router.js +0 -325
  73. package/dist_ts/http/router/route-router.d.ts +0 -108
  74. package/dist_ts/http/router/route-router.js +0 -393
  75. package/dist_ts/protocols/tls/constants.d.ts +0 -122
  76. package/dist_ts/protocols/tls/constants.js +0 -135
  77. package/dist_ts/protocols/tls/parser.d.ts +0 -53
  78. package/dist_ts/protocols/tls/parser.js +0 -294
  79. package/dist_ts/protocols/tls/types.d.ts +0 -65
  80. package/dist_ts/protocols/tls/types.js +0 -5
  81. package/dist_ts/proxies/http-proxy/certificate-manager.d.ts +0 -95
  82. package/dist_ts/proxies/http-proxy/certificate-manager.js +0 -214
  83. package/dist_ts/proxies/http-proxy/connection-pool.d.ts +0 -47
  84. package/dist_ts/proxies/http-proxy/connection-pool.js +0 -195
  85. package/dist_ts/proxies/http-proxy/context-creator.d.ts +0 -34
  86. package/dist_ts/proxies/http-proxy/context-creator.js +0 -108
  87. package/dist_ts/proxies/http-proxy/default-certificates.d.ts +0 -54
  88. package/dist_ts/proxies/http-proxy/default-certificates.js +0 -127
  89. package/dist_ts/proxies/http-proxy/function-cache.d.ts +0 -95
  90. package/dist_ts/proxies/http-proxy/function-cache.js +0 -215
  91. package/dist_ts/proxies/http-proxy/handlers/index.d.ts +0 -4
  92. package/dist_ts/proxies/http-proxy/handlers/index.js +0 -6
  93. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.d.ts +0 -18
  94. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.js +0 -78
  95. package/dist_ts/proxies/http-proxy/handlers/static-handler.d.ts +0 -19
  96. package/dist_ts/proxies/http-proxy/handlers/static-handler.js +0 -211
  97. package/dist_ts/proxies/http-proxy/http-proxy.d.ts +0 -117
  98. package/dist_ts/proxies/http-proxy/http-proxy.js +0 -521
  99. package/dist_ts/proxies/http-proxy/http-request-handler.d.ts +0 -40
  100. package/dist_ts/proxies/http-proxy/http-request-handler.js +0 -257
  101. package/dist_ts/proxies/http-proxy/http2-request-handler.d.ts +0 -24
  102. package/dist_ts/proxies/http-proxy/http2-request-handler.js +0 -201
  103. package/dist_ts/proxies/http-proxy/index.d.ts +0 -14
  104. package/dist_ts/proxies/http-proxy/index.js +0 -16
  105. package/dist_ts/proxies/http-proxy/models/http-types.d.ts +0 -117
  106. package/dist_ts/proxies/http-proxy/models/http-types.js +0 -92
  107. package/dist_ts/proxies/http-proxy/models/index.d.ts +0 -5
  108. package/dist_ts/proxies/http-proxy/models/index.js +0 -6
  109. package/dist_ts/proxies/http-proxy/models/types.d.ts +0 -75
  110. package/dist_ts/proxies/http-proxy/models/types.js +0 -35
  111. package/dist_ts/proxies/http-proxy/request-handler.d.ts +0 -97
  112. package/dist_ts/proxies/http-proxy/request-handler.js +0 -737
  113. package/dist_ts/proxies/http-proxy/security-manager.d.ts +0 -98
  114. package/dist_ts/proxies/http-proxy/security-manager.js +0 -341
  115. package/dist_ts/proxies/http-proxy/websocket-handler.d.ts +0 -50
  116. package/dist_ts/proxies/http-proxy/websocket-handler.js +0 -505
  117. package/dist_ts/proxies/nftables-proxy/index.d.ts +0 -6
  118. package/dist_ts/proxies/nftables-proxy/index.js +0 -7
  119. package/dist_ts/proxies/nftables-proxy/models/errors.d.ts +0 -15
  120. package/dist_ts/proxies/nftables-proxy/models/errors.js +0 -28
  121. package/dist_ts/proxies/nftables-proxy/models/index.d.ts +0 -5
  122. package/dist_ts/proxies/nftables-proxy/models/index.js +0 -6
  123. package/dist_ts/proxies/nftables-proxy/models/interfaces.d.ts +0 -75
  124. package/dist_ts/proxies/nftables-proxy/models/interfaces.js +0 -5
  125. package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +0 -124
  126. package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +0 -1374
  127. package/dist_ts/proxies/nftables-proxy/utils/index.d.ts +0 -9
  128. package/dist_ts/proxies/nftables-proxy/utils/index.js +0 -12
  129. package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.d.ts +0 -66
  130. package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.js +0 -131
  131. package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.d.ts +0 -39
  132. package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.js +0 -112
  133. package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.d.ts +0 -59
  134. package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.js +0 -130
  135. package/dist_ts/proxies/smart-proxy/acme-state-manager.d.ts +0 -42
  136. package/dist_ts/proxies/smart-proxy/acme-state-manager.js +0 -101
  137. package/dist_ts/proxies/smart-proxy/cert-store.d.ts +0 -10
  138. package/dist_ts/proxies/smart-proxy/cert-store.js +0 -72
  139. package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +0 -164
  140. package/dist_ts/proxies/smart-proxy/certificate-manager.js +0 -745
  141. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +0 -128
  142. package/dist_ts/proxies/smart-proxy/connection-manager.js +0 -689
  143. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +0 -43
  144. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +0 -180
  145. package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +0 -98
  146. package/dist_ts/proxies/smart-proxy/metrics-collector.js +0 -355
  147. package/dist_ts/proxies/smart-proxy/nftables-manager.d.ts +0 -82
  148. package/dist_ts/proxies/smart-proxy/nftables-manager.js +0 -237
  149. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +0 -117
  150. package/dist_ts/proxies/smart-proxy/port-manager.js +0 -318
  151. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +0 -60
  152. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +0 -1407
  153. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +0 -112
  154. package/dist_ts/proxies/smart-proxy/route-manager.js +0 -453
  155. package/dist_ts/proxies/smart-proxy/route-orchestrator.d.ts +0 -56
  156. package/dist_ts/proxies/smart-proxy/route-orchestrator.js +0 -204
  157. package/dist_ts/proxies/smart-proxy/rust-binary-locator.d.ts +0 -23
  158. package/dist_ts/proxies/smart-proxy/rust-binary-locator.js +0 -104
  159. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +0 -74
  160. package/dist_ts/proxies/smart-proxy/security-manager.js +0 -227
  161. package/dist_ts/proxies/smart-proxy/throughput-tracker.d.ts +0 -36
  162. package/dist_ts/proxies/smart-proxy/throughput-tracker.js +0 -115
  163. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +0 -48
  164. package/dist_ts/proxies/smart-proxy/timeout-manager.js +0 -158
  165. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +0 -50
  166. package/dist_ts/proxies/smart-proxy/tls-manager.js +0 -110
  167. package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +0 -161
  168. package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +0 -282
  169. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +0 -73
  170. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +0 -259
  171. package/dist_ts/routing/router/proxy-router.d.ts +0 -115
  172. package/dist_ts/routing/router/proxy-router.js +0 -325
  173. package/dist_ts/routing/router/route-router.d.ts +0 -108
  174. package/dist_ts/routing/router/route-router.js +0 -393
  175. package/dist_ts/tls/alerts/index.d.ts +0 -4
  176. package/dist_ts/tls/alerts/index.js +0 -5
  177. package/dist_ts/tls/alerts/tls-alert.d.ts +0 -150
  178. package/dist_ts/tls/alerts/tls-alert.js +0 -226
  179. package/dist_ts/tls/sni/client-hello-parser.d.ts +0 -100
  180. package/dist_ts/tls/sni/client-hello-parser.js +0 -464
  181. package/dist_ts/tls/sni/sni-extraction.d.ts +0 -58
  182. package/dist_ts/tls/sni/sni-extraction.js +0 -275
  183. package/dist_ts/tls/utils/index.d.ts +0 -4
  184. package/dist_ts/tls/utils/index.js +0 -5
  185. package/dist_ts/tls/utils/tls-utils.d.ts +0 -49
  186. package/dist_ts/tls/utils/tls-utils.js +0 -75
  187. package/ts/proxies/nftables-proxy/index.ts +0 -6
  188. package/ts/proxies/nftables-proxy/models/errors.ts +0 -30
  189. package/ts/proxies/nftables-proxy/models/index.ts +0 -5
  190. package/ts/proxies/nftables-proxy/models/interfaces.ts +0 -94
  191. package/ts/proxies/nftables-proxy/nftables-proxy.ts +0 -1754
  192. package/ts/proxies/nftables-proxy/utils/index.ts +0 -38
  193. package/ts/proxies/nftables-proxy/utils/nft-command-executor.ts +0 -162
  194. package/ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.ts +0 -125
  195. package/ts/proxies/nftables-proxy/utils/nft-rule-validator.ts +0 -156
  196. 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
- }