@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,20 +1,46 @@
1
1
  import * as plugins from '../../plugins.js';
2
- import { createLogger } from './models/types.js';
2
+ import '../../core/models/socket-augmentation.js';
3
+ import { createLogger, RouteManager } from './models/types.js';
3
4
  import { ConnectionPool } from './connection-pool.js';
4
5
  import { ProxyRouter } from '../../http/router/index.js';
6
+ import { ContextCreator } from './context-creator.js';
7
+ import { HttpRequestHandler } from './http-request-handler.js';
8
+ import { Http2RequestHandler } from './http2-request-handler.js';
9
+ import { toBaseContext } from '../../core/models/route-context.js';
10
+ import { TemplateUtils } from '../../core/utils/template-utils.js';
11
+ import { SecurityManager } from './security-manager.js';
5
12
  /**
6
13
  * Handles HTTP request processing and proxying
7
14
  */
8
15
  export class RequestHandler {
9
- constructor(options, connectionPool, router) {
16
+ constructor(options, connectionPool, legacyRouter, // Legacy router for backward compatibility
17
+ routeManager, functionCache, // FunctionCache - using any to avoid circular dependency
18
+ router // RouteRouter - using any to avoid circular dependency
19
+ ) {
10
20
  this.options = options;
11
21
  this.connectionPool = connectionPool;
22
+ this.legacyRouter = legacyRouter;
23
+ this.routeManager = routeManager;
24
+ this.functionCache = functionCache;
12
25
  this.router = router;
13
26
  this.defaultHeaders = {};
14
27
  this.metricsTracker = null;
15
28
  // HTTP/2 client sessions for backend proxying
16
29
  this.h2Sessions = new Map();
30
+ // Context creator for route contexts
31
+ this.contextCreator = new ContextCreator();
17
32
  this.logger = createLogger(options.logLevel || 'info');
33
+ this.securityManager = new SecurityManager(this.logger);
34
+ // Schedule rate limit cleanup every minute
35
+ setInterval(() => {
36
+ this.securityManager.cleanupExpiredRateLimits();
37
+ }, 60000);
38
+ }
39
+ /**
40
+ * Set the route manager instance
41
+ */
42
+ setRouteManager(routeManager) {
43
+ this.routeManager = routeManager;
18
44
  }
19
45
  /**
20
46
  * Set the metrics tracker instance
@@ -40,31 +66,87 @@ export class RequestHandler {
40
66
  }
41
67
  /**
42
68
  * Apply CORS headers to response if configured
69
+ * Implements Phase 5.5: Context-aware CORS handling
70
+ *
71
+ * @param res The server response to apply headers to
72
+ * @param req The incoming request
73
+ * @param route Optional route config with CORS settings
43
74
  */
44
- applyCorsHeaders(res, req) {
45
- if (!this.options.cors) {
75
+ applyCorsHeaders(res, req, route) {
76
+ // Use route-specific CORS config if available, otherwise use global config
77
+ let corsConfig = null;
78
+ // Route CORS config takes precedence if enabled
79
+ if (route?.headers?.cors?.enabled) {
80
+ corsConfig = route.headers.cors;
81
+ this.logger.debug(`Using route-specific CORS config for ${route.name || 'unnamed route'}`);
82
+ }
83
+ // Fall back to global CORS config if available
84
+ else if (this.options.cors) {
85
+ corsConfig = this.options.cors;
86
+ this.logger.debug('Using global CORS config');
87
+ }
88
+ // If no CORS config available, skip
89
+ if (!corsConfig) {
46
90
  return;
47
91
  }
48
- // Apply CORS headers
49
- if (this.options.cors.allowOrigin) {
50
- res.setHeader('Access-Control-Allow-Origin', this.options.cors.allowOrigin);
92
+ // Get origin from request
93
+ const origin = req.headers.origin;
94
+ // Apply Allow-Origin (with dynamic validation if needed)
95
+ if (corsConfig.allowOrigin) {
96
+ // Handle multiple origins in array format
97
+ if (Array.isArray(corsConfig.allowOrigin)) {
98
+ if (origin && corsConfig.allowOrigin.includes(origin)) {
99
+ // Match found, set specific origin
100
+ res.setHeader('Access-Control-Allow-Origin', origin);
101
+ res.setHeader('Vary', 'Origin'); // Important for caching
102
+ }
103
+ else if (corsConfig.allowOrigin.includes('*')) {
104
+ // Wildcard match
105
+ res.setHeader('Access-Control-Allow-Origin', '*');
106
+ }
107
+ }
108
+ // Handle single origin or wildcard
109
+ else if (corsConfig.allowOrigin === '*') {
110
+ res.setHeader('Access-Control-Allow-Origin', '*');
111
+ }
112
+ // Match single origin against request
113
+ else if (origin && corsConfig.allowOrigin === origin) {
114
+ res.setHeader('Access-Control-Allow-Origin', origin);
115
+ res.setHeader('Vary', 'Origin');
116
+ }
117
+ // Use template variables if present
118
+ else if (origin && corsConfig.allowOrigin.includes('{')) {
119
+ const resolvedOrigin = TemplateUtils.resolveTemplateVariables(corsConfig.allowOrigin, { domain: req.headers.host });
120
+ if (resolvedOrigin === origin || resolvedOrigin === '*') {
121
+ res.setHeader('Access-Control-Allow-Origin', origin);
122
+ res.setHeader('Vary', 'Origin');
123
+ }
124
+ }
51
125
  }
52
- if (this.options.cors.allowMethods) {
53
- res.setHeader('Access-Control-Allow-Methods', this.options.cors.allowMethods);
126
+ // Apply other CORS headers
127
+ if (corsConfig.allowMethods) {
128
+ res.setHeader('Access-Control-Allow-Methods', corsConfig.allowMethods);
54
129
  }
55
- if (this.options.cors.allowHeaders) {
56
- res.setHeader('Access-Control-Allow-Headers', this.options.cors.allowHeaders);
130
+ if (corsConfig.allowHeaders) {
131
+ res.setHeader('Access-Control-Allow-Headers', corsConfig.allowHeaders);
57
132
  }
58
- if (this.options.cors.maxAge) {
59
- res.setHeader('Access-Control-Max-Age', this.options.cors.maxAge.toString());
133
+ if (corsConfig.allowCredentials) {
134
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
60
135
  }
61
- // Handle CORS preflight requests
62
- if (req.method === 'OPTIONS') {
136
+ if (corsConfig.exposeHeaders) {
137
+ res.setHeader('Access-Control-Expose-Headers', corsConfig.exposeHeaders);
138
+ }
139
+ if (corsConfig.maxAge) {
140
+ res.setHeader('Access-Control-Max-Age', corsConfig.maxAge.toString());
141
+ }
142
+ // Handle CORS preflight requests if enabled (default: true)
143
+ if (req.method === 'OPTIONS' && corsConfig.preflight !== false) {
63
144
  res.statusCode = 204; // No content
64
145
  res.end();
65
146
  return;
66
147
  }
67
148
  }
149
+ // First implementation of applyRouteHeaderModifications moved to the second implementation below
68
150
  /**
69
151
  * Apply default headers to response
70
152
  */
@@ -80,14 +162,147 @@ export class RequestHandler {
80
162
  res.setHeader('Server', 'NetworkProxy');
81
163
  }
82
164
  }
165
+ /**
166
+ * Apply URL rewriting based on route configuration
167
+ * Implements Phase 5.2: URL rewriting using route context
168
+ *
169
+ * @param req The request with the URL to rewrite
170
+ * @param route The route configuration containing rewrite rules
171
+ * @param routeContext Context for template variable resolution
172
+ * @returns True if URL was rewritten, false otherwise
173
+ */
174
+ applyUrlRewriting(req, route, routeContext) {
175
+ // Check if route has URL rewriting configuration
176
+ if (!route.action.advanced?.urlRewrite) {
177
+ return false;
178
+ }
179
+ const rewriteConfig = route.action.advanced.urlRewrite;
180
+ // Store original URL for logging
181
+ const originalUrl = req.url;
182
+ if (rewriteConfig.pattern && rewriteConfig.target) {
183
+ try {
184
+ // Create a RegExp from the pattern
185
+ const regex = new RegExp(rewriteConfig.pattern, rewriteConfig.flags || '');
186
+ // Apply rewriting with template variable resolution
187
+ let target = rewriteConfig.target;
188
+ // Replace template variables in target with values from context
189
+ target = TemplateUtils.resolveTemplateVariables(target, routeContext);
190
+ // If onlyRewritePath is set, split URL into path and query parts
191
+ if (rewriteConfig.onlyRewritePath && req.url) {
192
+ const [path, query] = req.url.split('?');
193
+ const rewrittenPath = path.replace(regex, target);
194
+ req.url = query ? `${rewrittenPath}?${query}` : rewrittenPath;
195
+ }
196
+ else {
197
+ // Perform the replacement on the entire URL
198
+ req.url = req.url?.replace(regex, target);
199
+ }
200
+ this.logger.debug(`URL rewritten: ${originalUrl} -> ${req.url}`);
201
+ return true;
202
+ }
203
+ catch (err) {
204
+ this.logger.error(`Error in URL rewriting: ${err}`);
205
+ return false;
206
+ }
207
+ }
208
+ return false;
209
+ }
210
+ /**
211
+ * Apply header modifications from route configuration
212
+ * Implements Phase 5.1: Route-based header manipulation
213
+ */
214
+ applyRouteHeaderModifications(route, req, res) {
215
+ // Check if route has header modifications
216
+ if (!route.headers) {
217
+ return;
218
+ }
219
+ // Apply request header modifications (these will be sent to the backend)
220
+ if (route.headers.request && req.headers) {
221
+ for (const [key, value] of Object.entries(route.headers.request)) {
222
+ // Skip if header already exists and we're not overriding
223
+ if (req.headers[key.toLowerCase()] && !value.startsWith('!')) {
224
+ continue;
225
+ }
226
+ // Handle special delete directive (!delete)
227
+ if (value === '!delete') {
228
+ delete req.headers[key.toLowerCase()];
229
+ this.logger.debug(`Deleted request header: ${key}`);
230
+ continue;
231
+ }
232
+ // Handle forced override (!value)
233
+ let finalValue;
234
+ if (value.startsWith('!') && value !== '!delete') {
235
+ // Keep the ! but resolve any templates in the rest
236
+ const templateValue = value.substring(1);
237
+ finalValue = '!' + TemplateUtils.resolveTemplateVariables(templateValue, {});
238
+ }
239
+ else {
240
+ // Resolve templates in the entire value
241
+ finalValue = TemplateUtils.resolveTemplateVariables(value, {});
242
+ }
243
+ // Set the header
244
+ req.headers[key.toLowerCase()] = finalValue;
245
+ this.logger.debug(`Modified request header: ${key}=${finalValue}`);
246
+ }
247
+ }
248
+ // Apply response header modifications (these will be stored for later use)
249
+ if (route.headers.response) {
250
+ for (const [key, value] of Object.entries(route.headers.response)) {
251
+ // Skip if header already exists and we're not overriding
252
+ if (res.hasHeader(key) && !value.startsWith('!')) {
253
+ continue;
254
+ }
255
+ // Handle special delete directive (!delete)
256
+ if (value === '!delete') {
257
+ res.removeHeader(key);
258
+ this.logger.debug(`Deleted response header: ${key}`);
259
+ continue;
260
+ }
261
+ // Handle forced override (!value)
262
+ let finalValue;
263
+ if (value.startsWith('!') && value !== '!delete') {
264
+ // Keep the ! but resolve any templates in the rest
265
+ const templateValue = value.substring(1);
266
+ finalValue = '!' + TemplateUtils.resolveTemplateVariables(templateValue, {});
267
+ }
268
+ else {
269
+ // Resolve templates in the entire value
270
+ finalValue = TemplateUtils.resolveTemplateVariables(value, {});
271
+ }
272
+ // Set the header
273
+ res.setHeader(key, finalValue);
274
+ this.logger.debug(`Modified response header: ${key}=${finalValue}`);
275
+ }
276
+ }
277
+ }
83
278
  /**
84
279
  * Handle an HTTP request
85
280
  */
86
281
  async handleRequest(req, res) {
87
282
  // Record start time for logging
88
283
  const startTime = Date.now();
89
- // Apply CORS headers if configured
90
- this.applyCorsHeaders(res, req);
284
+ // Get route before applying CORS (we might need its settings)
285
+ // Try to find a matching route using RouteManager
286
+ let matchingRoute = null;
287
+ if (this.routeManager) {
288
+ try {
289
+ // Create a connection ID for this request
290
+ const connectionId = `http-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
291
+ // Create route context for function-based targets
292
+ const routeContext = this.contextCreator.createHttpRouteContext(req, {
293
+ connectionId,
294
+ clientIp: req.socket.remoteAddress?.replace('::ffff:', '') || '0.0.0.0',
295
+ serverIp: req.socket.localAddress?.replace('::ffff:', '') || '0.0.0.0',
296
+ tlsVersion: req.socket.getTLSVersion?.() || undefined
297
+ });
298
+ matchingRoute = this.routeManager.findMatchingRoute(toBaseContext(routeContext));
299
+ }
300
+ catch (err) {
301
+ this.logger.error('Error finding matching route', err);
302
+ }
303
+ }
304
+ // Apply CORS headers with route-specific settings if available
305
+ this.applyCorsHeaders(res, req, matchingRoute);
91
306
  // If this is an OPTIONS request, the response has already been ended in applyCorsHeaders
92
307
  // so we should return early to avoid trying to set more headers
93
308
  if (req.method === 'OPTIONS') {
@@ -99,13 +314,202 @@ export class RequestHandler {
99
314
  }
100
315
  // Apply default headers
101
316
  this.applyDefaultHeaders(res);
102
- // Determine routing configuration
317
+ // We already have the connection ID and routeContext from CORS handling
318
+ const connectionId = `http-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
319
+ // Create route context for function-based targets (if we don't already have one)
320
+ const routeContext = this.contextCreator.createHttpRouteContext(req, {
321
+ connectionId,
322
+ clientIp: req.socket.remoteAddress?.replace('::ffff:', '') || '0.0.0.0',
323
+ serverIp: req.socket.localAddress?.replace('::ffff:', '') || '0.0.0.0',
324
+ tlsVersion: req.socket.getTLSVersion?.() || undefined
325
+ });
326
+ // Check security restrictions if we have a matching route
327
+ if (matchingRoute) {
328
+ // Check IP filtering and rate limiting
329
+ if (!this.securityManager.isAllowed(matchingRoute, routeContext)) {
330
+ this.logger.warn(`Access denied for ${routeContext.clientIp} to ${matchingRoute.name || 'unnamed'}`);
331
+ res.statusCode = 403;
332
+ res.end('Forbidden: Access denied by security policy');
333
+ if (this.metricsTracker)
334
+ this.metricsTracker.incrementFailedRequests();
335
+ return;
336
+ }
337
+ // Check basic auth
338
+ if (matchingRoute.security?.basicAuth?.enabled) {
339
+ const authHeader = req.headers.authorization;
340
+ if (!authHeader || !authHeader.startsWith('Basic ')) {
341
+ // No auth header provided - send 401 with WWW-Authenticate header
342
+ res.statusCode = 401;
343
+ const realm = matchingRoute.security.basicAuth.realm || 'Protected Area';
344
+ res.setHeader('WWW-Authenticate', `Basic realm="${realm}", charset="UTF-8"`);
345
+ res.end('Authentication Required');
346
+ if (this.metricsTracker)
347
+ this.metricsTracker.incrementFailedRequests();
348
+ return;
349
+ }
350
+ // Verify credentials
351
+ try {
352
+ const credentials = Buffer.from(authHeader.substring(6), 'base64').toString('utf-8');
353
+ const [username, password] = credentials.split(':');
354
+ if (!this.securityManager.checkBasicAuth(matchingRoute, username, password)) {
355
+ res.statusCode = 401;
356
+ const realm = matchingRoute.security.basicAuth.realm || 'Protected Area';
357
+ res.setHeader('WWW-Authenticate', `Basic realm="${realm}", charset="UTF-8"`);
358
+ res.end('Invalid Credentials');
359
+ if (this.metricsTracker)
360
+ this.metricsTracker.incrementFailedRequests();
361
+ return;
362
+ }
363
+ }
364
+ catch (err) {
365
+ this.logger.error(`Error verifying basic auth: ${err}`);
366
+ res.statusCode = 401;
367
+ res.end('Authentication Error');
368
+ if (this.metricsTracker)
369
+ this.metricsTracker.incrementFailedRequests();
370
+ return;
371
+ }
372
+ }
373
+ // Check JWT auth
374
+ if (matchingRoute.security?.jwtAuth?.enabled) {
375
+ const authHeader = req.headers.authorization;
376
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
377
+ // No auth header provided - send 401
378
+ res.statusCode = 401;
379
+ res.end('Authentication Required: JWT token missing');
380
+ if (this.metricsTracker)
381
+ this.metricsTracker.incrementFailedRequests();
382
+ return;
383
+ }
384
+ // Verify token
385
+ const token = authHeader.substring(7);
386
+ if (!this.securityManager.verifyJwtToken(matchingRoute, token)) {
387
+ res.statusCode = 401;
388
+ res.end('Invalid or Expired JWT');
389
+ if (this.metricsTracker)
390
+ this.metricsTracker.incrementFailedRequests();
391
+ return;
392
+ }
393
+ }
394
+ }
395
+ // If we found a matching route with function-based targets, use it
396
+ if (matchingRoute && matchingRoute.action.type === 'forward' && matchingRoute.action.target) {
397
+ this.logger.debug(`Found matching route: ${matchingRoute.name || 'unnamed'}`);
398
+ // Extract target information, resolving functions if needed
399
+ let targetHost;
400
+ let targetPort;
401
+ try {
402
+ // Check function cache for host and resolve or use cached value
403
+ if (typeof matchingRoute.action.target.host === 'function') {
404
+ // Generate a function ID for caching (use route name or ID if available)
405
+ const functionId = `host-${matchingRoute.id || matchingRoute.name || 'unnamed'}`;
406
+ // Check if we have a cached result
407
+ if (this.functionCache) {
408
+ const cachedHost = this.functionCache.getCachedHost(routeContext, functionId);
409
+ if (cachedHost !== undefined) {
410
+ targetHost = cachedHost;
411
+ this.logger.debug(`Using cached host value for ${functionId}`);
412
+ }
413
+ else {
414
+ // Resolve the function and cache the result
415
+ const resolvedHost = matchingRoute.action.target.host(toBaseContext(routeContext));
416
+ targetHost = resolvedHost;
417
+ // Cache the result
418
+ this.functionCache.cacheHost(routeContext, functionId, resolvedHost);
419
+ this.logger.debug(`Resolved and cached function-based host to: ${Array.isArray(resolvedHost) ? resolvedHost.join(', ') : resolvedHost}`);
420
+ }
421
+ }
422
+ else {
423
+ // No cache available, just resolve
424
+ const resolvedHost = matchingRoute.action.target.host(routeContext);
425
+ targetHost = resolvedHost;
426
+ this.logger.debug(`Resolved function-based host to: ${Array.isArray(resolvedHost) ? resolvedHost.join(', ') : resolvedHost}`);
427
+ }
428
+ }
429
+ else {
430
+ targetHost = matchingRoute.action.target.host;
431
+ }
432
+ // Check function cache for port and resolve or use cached value
433
+ if (typeof matchingRoute.action.target.port === 'function') {
434
+ // Generate a function ID for caching
435
+ const functionId = `port-${matchingRoute.id || matchingRoute.name || 'unnamed'}`;
436
+ // Check if we have a cached result
437
+ if (this.functionCache) {
438
+ const cachedPort = this.functionCache.getCachedPort(routeContext, functionId);
439
+ if (cachedPort !== undefined) {
440
+ targetPort = cachedPort;
441
+ this.logger.debug(`Using cached port value for ${functionId}`);
442
+ }
443
+ else {
444
+ // Resolve the function and cache the result
445
+ const resolvedPort = matchingRoute.action.target.port(toBaseContext(routeContext));
446
+ targetPort = resolvedPort;
447
+ // Cache the result
448
+ this.functionCache.cachePort(routeContext, functionId, resolvedPort);
449
+ this.logger.debug(`Resolved and cached function-based port to: ${resolvedPort}`);
450
+ }
451
+ }
452
+ else {
453
+ // No cache available, just resolve
454
+ const resolvedPort = matchingRoute.action.target.port(routeContext);
455
+ targetPort = resolvedPort;
456
+ this.logger.debug(`Resolved function-based port to: ${resolvedPort}`);
457
+ }
458
+ }
459
+ else {
460
+ targetPort = matchingRoute.action.target.port === 'preserve' ? routeContext.port : matchingRoute.action.target.port;
461
+ }
462
+ // Select a single host if an array was provided
463
+ const selectedHost = Array.isArray(targetHost)
464
+ ? targetHost[Math.floor(Math.random() * targetHost.length)]
465
+ : targetHost;
466
+ // Create a destination for the connection pool
467
+ const destination = {
468
+ host: selectedHost,
469
+ port: targetPort
470
+ };
471
+ // Apply URL rewriting if configured
472
+ this.applyUrlRewriting(req, matchingRoute, routeContext);
473
+ // Apply header modifications if configured
474
+ this.applyRouteHeaderModifications(matchingRoute, req, res);
475
+ // Continue with handling using the resolved destination
476
+ HttpRequestHandler.handleHttpRequestWithDestination(req, res, destination, routeContext, startTime, this.logger, this.metricsTracker, matchingRoute // Pass the route config for additional processing
477
+ );
478
+ return;
479
+ }
480
+ catch (err) {
481
+ this.logger.error(`Error evaluating function-based target: ${err}`);
482
+ res.statusCode = 500;
483
+ res.end('Internal Server Error: Failed to evaluate target functions');
484
+ if (this.metricsTracker)
485
+ this.metricsTracker.incrementFailedRequests();
486
+ return;
487
+ }
488
+ }
489
+ // Try modern router first, then fall back to legacy routing if needed
490
+ if (this.router) {
491
+ try {
492
+ // Try to find a matching route using the modern router
493
+ const route = this.router.routeReq(req);
494
+ if (route && route.action.type === 'forward' && route.action.target) {
495
+ // Handle this route similarly to RouteManager logic
496
+ this.logger.debug(`Found matching route via modern router: ${route.name || 'unnamed'}`);
497
+ // No need to do anything here, we'll continue with legacy routing
498
+ // The routeManager would have already found this route if applicable
499
+ }
500
+ }
501
+ catch (err) {
502
+ this.logger.error('Error using modern router', err);
503
+ // Continue with legacy routing
504
+ }
505
+ }
506
+ // Fall back to legacy routing if no matching route found via RouteManager
103
507
  let proxyConfig;
104
508
  try {
105
- proxyConfig = this.router.routeReq(req);
509
+ proxyConfig = this.legacyRouter.routeReq(req);
106
510
  }
107
511
  catch (err) {
108
- this.logger.error('Error routing request', err);
512
+ this.logger.error('Error routing request with legacy router', err);
109
513
  res.statusCode = 500;
110
514
  res.end('Internal Server Error');
111
515
  if (this.metricsTracker)
@@ -163,128 +567,159 @@ export class RequestHandler {
163
567
  });
164
568
  return;
165
569
  }
166
- try {
167
- // Find target based on hostname
168
- const proxyConfig = this.router.routeReq(req);
169
- if (!proxyConfig) {
170
- // No matching proxy configuration
171
- this.logger.warn(`No proxy configuration for host: ${req.headers.host}`);
172
- res.statusCode = 404;
173
- res.end('Not Found: No proxy configuration for this host');
174
- // Increment failed requests counter
175
- if (this.metricsTracker) {
176
- this.metricsTracker.incrementFailedRequests();
177
- }
178
- return;
570
+ }
571
+ /**
572
+ * Handle HTTP/2 stream requests with function-based target support
573
+ */
574
+ async handleHttp2(stream, headers) {
575
+ const startTime = Date.now();
576
+ // Create a connection ID for this HTTP/2 stream
577
+ const connectionId = `http2-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
578
+ // Get client IP and server IP from the socket
579
+ const socket = stream.session?.socket;
580
+ const clientIp = socket?.remoteAddress?.replace('::ffff:', '') || '0.0.0.0';
581
+ const serverIp = socket?.localAddress?.replace('::ffff:', '') || '0.0.0.0';
582
+ // Create route context for function-based targets
583
+ const routeContext = this.contextCreator.createHttp2RouteContext(stream, headers, {
584
+ connectionId,
585
+ clientIp,
586
+ serverIp
587
+ });
588
+ // Try to find a matching route using RouteManager
589
+ let matchingRoute = null;
590
+ if (this.routeManager) {
591
+ try {
592
+ matchingRoute = this.routeManager.findMatchingRoute(toBaseContext(routeContext));
179
593
  }
180
- // Get destination IP using round-robin if multiple IPs configured
181
- const destination = this.connectionPool.getNextTarget(proxyConfig.destinationIps, proxyConfig.destinationPorts[0]);
182
- // Create options for the proxy request
183
- const options = {
184
- hostname: destination.host,
185
- port: destination.port,
186
- path: req.url,
187
- method: req.method,
188
- headers: { ...req.headers }
189
- };
190
- // Remove host header to avoid issues with virtual hosts on target server
191
- // The host header should match the target server's expected hostname
192
- if (options.headers && options.headers.host) {
193
- if (proxyConfig.rewriteHostHeader) {
194
- options.headers.host = `${destination.host}:${destination.port}`;
195
- }
594
+ catch (err) {
595
+ this.logger.error('Error finding matching route for HTTP/2 request', err);
196
596
  }
197
- this.logger.debug(`Proxying request to ${destination.host}:${destination.port}${req.url}`, { method: req.method });
198
- // Create proxy request
199
- const proxyReq = plugins.http.request(options, (proxyRes) => {
200
- // Copy status code
201
- res.statusCode = proxyRes.statusCode || 500;
202
- // Copy headers from proxy response to client response
203
- for (const [key, value] of Object.entries(proxyRes.headers)) {
204
- if (value !== undefined) {
205
- res.setHeader(key, value);
597
+ }
598
+ // If we found a matching route with function-based targets, use it
599
+ if (matchingRoute && matchingRoute.action.type === 'forward' && matchingRoute.action.target) {
600
+ this.logger.debug(`Found matching route for HTTP/2 request: ${matchingRoute.name || 'unnamed'}`);
601
+ // Extract target information, resolving functions if needed
602
+ let targetHost;
603
+ let targetPort;
604
+ try {
605
+ // Check function cache for host and resolve or use cached value
606
+ if (typeof matchingRoute.action.target.host === 'function') {
607
+ // Generate a function ID for caching (use route name or ID if available)
608
+ const functionId = `host-http2-${matchingRoute.id || matchingRoute.name || 'unnamed'}`;
609
+ // Check if we have a cached result
610
+ if (this.functionCache) {
611
+ const cachedHost = this.functionCache.getCachedHost(routeContext, functionId);
612
+ if (cachedHost !== undefined) {
613
+ targetHost = cachedHost;
614
+ this.logger.debug(`Using cached host value for HTTP/2: ${functionId}`);
615
+ }
616
+ else {
617
+ // Resolve the function and cache the result
618
+ const resolvedHost = matchingRoute.action.target.host(toBaseContext(routeContext));
619
+ targetHost = resolvedHost;
620
+ // Cache the result
621
+ this.functionCache.cacheHost(routeContext, functionId, resolvedHost);
622
+ this.logger.debug(`Resolved and cached HTTP/2 function-based host to: ${Array.isArray(resolvedHost) ? resolvedHost.join(', ') : resolvedHost}`);
623
+ }
206
624
  }
207
- }
208
- // Pipe proxy response to client response
209
- proxyRes.pipe(res);
210
- // Increment served requests counter when the response finishes
211
- res.on('finish', () => {
212
- if (this.metricsTracker) {
213
- this.metricsTracker.incrementRequestsServed();
625
+ else {
626
+ // No cache available, just resolve
627
+ const resolvedHost = matchingRoute.action.target.host(routeContext);
628
+ targetHost = resolvedHost;
629
+ this.logger.debug(`Resolved HTTP/2 function-based host to: ${Array.isArray(resolvedHost) ? resolvedHost.join(', ') : resolvedHost}`);
214
630
  }
215
- // Log the completed request
216
- const duration = Date.now() - startTime;
217
- this.logger.debug(`Request completed in ${duration}ms: ${req.method} ${req.url} ${res.statusCode}`, { duration, statusCode: res.statusCode });
218
- });
219
- });
220
- // Handle proxy request errors
221
- proxyReq.on('error', (error) => {
222
- const duration = Date.now() - startTime;
223
- this.logger.error(`Proxy error for ${req.method} ${req.url}: ${error.message}`, { duration, error: error.message });
224
- // Increment failed requests counter
225
- if (this.metricsTracker) {
226
- this.metricsTracker.incrementFailedRequests();
227
631
  }
228
- // Check if headers have already been sent
229
- if (!res.headersSent) {
230
- res.statusCode = 502;
231
- res.end(`Bad Gateway: ${error.message}`);
632
+ else {
633
+ targetHost = matchingRoute.action.target.host;
634
+ }
635
+ // Check function cache for port and resolve or use cached value
636
+ if (typeof matchingRoute.action.target.port === 'function') {
637
+ // Generate a function ID for caching
638
+ const functionId = `port-http2-${matchingRoute.id || matchingRoute.name || 'unnamed'}`;
639
+ // Check if we have a cached result
640
+ if (this.functionCache) {
641
+ const cachedPort = this.functionCache.getCachedPort(routeContext, functionId);
642
+ if (cachedPort !== undefined) {
643
+ targetPort = cachedPort;
644
+ this.logger.debug(`Using cached port value for HTTP/2: ${functionId}`);
645
+ }
646
+ else {
647
+ // Resolve the function and cache the result
648
+ const resolvedPort = matchingRoute.action.target.port(toBaseContext(routeContext));
649
+ targetPort = resolvedPort;
650
+ // Cache the result
651
+ this.functionCache.cachePort(routeContext, functionId, resolvedPort);
652
+ this.logger.debug(`Resolved and cached HTTP/2 function-based port to: ${resolvedPort}`);
653
+ }
654
+ }
655
+ else {
656
+ // No cache available, just resolve
657
+ const resolvedPort = matchingRoute.action.target.port(routeContext);
658
+ targetPort = resolvedPort;
659
+ this.logger.debug(`Resolved HTTP/2 function-based port to: ${resolvedPort}`);
660
+ }
232
661
  }
233
662
  else {
234
- // If headers already sent, just close the connection
235
- res.end();
663
+ targetPort = matchingRoute.action.target.port === 'preserve' ? routeContext.port : matchingRoute.action.target.port;
236
664
  }
237
- });
238
- // Pipe request body to proxy request and handle client-side errors
239
- req.pipe(proxyReq);
240
- // Handle client disconnection
241
- req.on('error', (error) => {
242
- this.logger.debug(`Client connection error: ${error.message}`);
243
- proxyReq.destroy();
244
- // Increment failed requests counter on client errors
245
- if (this.metricsTracker) {
246
- this.metricsTracker.incrementFailedRequests();
665
+ // Select a single host if an array was provided
666
+ const selectedHost = Array.isArray(targetHost)
667
+ ? targetHost[Math.floor(Math.random() * targetHost.length)]
668
+ : targetHost;
669
+ // Create a destination for forwarding
670
+ const destination = {
671
+ host: selectedHost,
672
+ port: targetPort
673
+ };
674
+ // Handle HTTP/2 stream based on backend protocol
675
+ const backendProtocol = matchingRoute.action.options?.backendProtocol || this.options.backendProtocol;
676
+ if (backendProtocol === 'http2') {
677
+ // Forward to HTTP/2 backend
678
+ return Http2RequestHandler.handleHttp2WithHttp2Destination(stream, headers, destination, routeContext, this.h2Sessions, this.logger, this.metricsTracker);
247
679
  }
248
- });
249
- // Handle response errors
250
- res.on('error', (error) => {
251
- this.logger.debug(`Response error: ${error.message}`);
252
- proxyReq.destroy();
253
- // Increment failed requests counter on response errors
254
- if (this.metricsTracker) {
255
- this.metricsTracker.incrementFailedRequests();
680
+ else {
681
+ // Forward to HTTP/1.1 backend
682
+ return Http2RequestHandler.handleHttp2WithHttp1Destination(stream, headers, destination, routeContext, this.logger, this.metricsTracker);
256
683
  }
257
- });
258
- }
259
- catch (error) {
260
- // Handle any unexpected errors
261
- this.logger.error(`Unexpected error handling request: ${error.message}`, { error: error.stack });
262
- // Increment failed requests counter
263
- if (this.metricsTracker) {
264
- this.metricsTracker.incrementFailedRequests();
265
- }
266
- if (!res.headersSent) {
267
- res.statusCode = 500;
268
- res.end('Internal Server Error');
269
684
  }
270
- else {
271
- res.end();
685
+ catch (err) {
686
+ this.logger.error(`Error evaluating function-based target for HTTP/2: ${err}`);
687
+ stream.respond({ ':status': 500 });
688
+ stream.end('Internal Server Error: Failed to evaluate target functions');
689
+ if (this.metricsTracker)
690
+ this.metricsTracker.incrementFailedRequests();
691
+ return;
272
692
  }
273
693
  }
274
- }
275
- /**
276
- * Handle HTTP/2 stream requests by proxying to HTTP/1 backends
277
- */
278
- async handleHttp2(stream, headers) {
279
- const startTime = Date.now();
694
+ // Fall back to legacy routing if no matching route found
280
695
  const method = headers[':method'] || 'GET';
281
696
  const path = headers[':path'] || '/';
282
697
  // If configured to proxy to backends over HTTP/2, use HTTP/2 client sessions
283
698
  if (this.options.backendProtocol === 'http2') {
284
699
  const authority = headers[':authority'] || '';
285
700
  const host = authority.split(':')[0];
286
- const fakeReq = { headers: { host }, method: headers[':method'], url: headers[':path'], socket: stream.session.socket };
287
- const proxyConfig = this.router.routeReq(fakeReq);
701
+ const fakeReq = {
702
+ headers: { host },
703
+ method: headers[':method'],
704
+ url: headers[':path'],
705
+ socket: stream.session.socket
706
+ };
707
+ // Try modern router first if available
708
+ let route;
709
+ if (this.router) {
710
+ try {
711
+ route = this.router.routeReq(fakeReq);
712
+ if (route && route.action.type === 'forward' && route.action.target) {
713
+ this.logger.debug(`Found matching HTTP/2 route via modern router: ${route.name || 'unnamed'}`);
714
+ // The routeManager would have already found this route if applicable
715
+ }
716
+ }
717
+ catch (err) {
718
+ this.logger.error('Error using modern router for HTTP/2', err);
719
+ }
720
+ }
721
+ // Fall back to legacy routing
722
+ const proxyConfig = this.legacyRouter.routeReq(fakeReq);
288
723
  if (!proxyConfig) {
289
724
  stream.respond({ ':status': 404 });
290
725
  stream.end('Not Found');
@@ -293,52 +728,35 @@ export class RequestHandler {
293
728
  return;
294
729
  }
295
730
  const destination = this.connectionPool.getNextTarget(proxyConfig.destinationIps, proxyConfig.destinationPorts[0]);
296
- const key = `${destination.host}:${destination.port}`;
297
- let session = this.h2Sessions.get(key);
298
- if (!session || session.closed || session.destroyed) {
299
- session = plugins.http2.connect(`http://${destination.host}:${destination.port}`);
300
- this.h2Sessions.set(key, session);
301
- session.on('error', () => this.h2Sessions.delete(key));
302
- session.on('close', () => this.h2Sessions.delete(key));
303
- }
304
- // Build headers for backend HTTP/2 request
305
- const h2Headers = {
306
- ':method': headers[':method'],
307
- ':path': headers[':path'],
308
- ':authority': `${destination.host}:${destination.port}`
309
- };
310
- for (const [k, v] of Object.entries(headers)) {
311
- if (!k.startsWith(':') && typeof v === 'string') {
312
- h2Headers[k] = v;
313
- }
314
- }
315
- const h2Stream2 = session.request(h2Headers);
316
- stream.pipe(h2Stream2);
317
- h2Stream2.on('response', (hdrs) => {
318
- // Map status and headers to client
319
- const resp = { ':status': hdrs[':status'] };
320
- for (const [hk, hv] of Object.entries(hdrs)) {
321
- if (!hk.startsWith(':') && hv)
322
- resp[hk] = hv;
323
- }
324
- stream.respond(resp);
325
- h2Stream2.pipe(stream);
326
- });
327
- h2Stream2.on('error', (err) => {
328
- stream.respond({ ':status': 502 });
329
- stream.end(`Bad Gateway: ${err.message}`);
330
- if (this.metricsTracker)
331
- this.metricsTracker.incrementFailedRequests();
332
- });
333
- return;
731
+ // Use the helper for HTTP/2 to HTTP/2 routing
732
+ return Http2RequestHandler.handleHttp2WithHttp2Destination(stream, headers, destination, routeContext, this.h2Sessions, this.logger, this.metricsTracker);
334
733
  }
335
734
  try {
336
735
  // Determine host for routing
337
736
  const authority = headers[':authority'] || '';
338
737
  const host = authority.split(':')[0];
339
738
  // Fake request object for routing
340
- const fakeReq = { headers: { host }, method, url: path, socket: stream.session.socket };
341
- const proxyConfig = this.router.routeReq(fakeReq);
739
+ const fakeReq = {
740
+ headers: { host },
741
+ method,
742
+ url: path,
743
+ socket: stream.session.socket
744
+ };
745
+ // Try modern router first if available
746
+ if (this.router) {
747
+ try {
748
+ const route = this.router.routeReq(fakeReq);
749
+ if (route && route.action.type === 'forward' && route.action.target) {
750
+ this.logger.debug(`Found matching HTTP/2 route via modern router: ${route.name || 'unnamed'}`);
751
+ // The routeManager would have already found this route if applicable
752
+ }
753
+ }
754
+ catch (err) {
755
+ this.logger.error('Error using modern router for HTTP/2', err);
756
+ }
757
+ }
758
+ // Fall back to legacy routing
759
+ const proxyConfig = this.legacyRouter.routeReq(fakeReq);
342
760
  if (!proxyConfig) {
343
761
  stream.respond({ ':status': 404 });
344
762
  stream.end('Not Found');
@@ -348,40 +766,8 @@ export class RequestHandler {
348
766
  }
349
767
  // Select backend target
350
768
  const destination = this.connectionPool.getNextTarget(proxyConfig.destinationIps, proxyConfig.destinationPorts[0]);
351
- // Build headers for HTTP/1 proxy
352
- const outboundHeaders = {};
353
- for (const [key, value] of Object.entries(headers)) {
354
- if (typeof key === 'string' && typeof value === 'string' && !key.startsWith(':')) {
355
- outboundHeaders[key] = value;
356
- }
357
- }
358
- if (outboundHeaders.host && proxyConfig.rewriteHostHeader) {
359
- outboundHeaders.host = `${destination.host}:${destination.port}`;
360
- }
361
- // Create HTTP/1 proxy request
362
- const proxyReq = plugins.http.request({ hostname: destination.host, port: destination.port, path, method, headers: outboundHeaders }, (proxyRes) => {
363
- // Map status and headers back to HTTP/2
364
- const responseHeaders = {};
365
- for (const [k, v] of Object.entries(proxyRes.headers)) {
366
- if (v !== undefined) {
367
- responseHeaders[k] = v;
368
- }
369
- }
370
- stream.respond({ ':status': proxyRes.statusCode || 500, ...responseHeaders });
371
- proxyRes.pipe(stream);
372
- stream.on('close', () => proxyReq.destroy());
373
- stream.on('error', () => proxyReq.destroy());
374
- if (this.metricsTracker)
375
- stream.on('end', () => this.metricsTracker.incrementRequestsServed());
376
- });
377
- proxyReq.on('error', (err) => {
378
- stream.respond({ ':status': 502 });
379
- stream.end(`Bad Gateway: ${err.message}`);
380
- if (this.metricsTracker)
381
- this.metricsTracker.incrementFailedRequests();
382
- });
383
- // Pipe client stream to backend
384
- stream.pipe(proxyReq);
769
+ // Use the helper for HTTP/2 to HTTP/1 routing
770
+ return Http2RequestHandler.handleHttp2WithHttp1Destination(stream, headers, destination, routeContext, this.logger, this.metricsTracker);
385
771
  }
386
772
  catch (err) {
387
773
  stream.respond({ ':status': 500 });
@@ -391,4 +777,4 @@ export class RequestHandler {
391
777
  }
392
778
  }
393
779
  }
394
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcHJveGllcy9uZXR3b3JrLXByb3h5L3JlcXVlc3QtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBMkMsWUFBWSxFQUE0QixNQUFNLG1CQUFtQixDQUFDO0FBQ3BILE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFhekQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sY0FBYztJQU96QixZQUNVLE9BQTZCLEVBQzdCLGNBQThCLEVBQzlCLE1BQW1CO1FBRm5CLFlBQU8sR0FBUCxPQUFPLENBQXNCO1FBQzdCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixXQUFNLEdBQU4sTUFBTSxDQUFhO1FBVHJCLG1CQUFjLEdBQThCLEVBQUUsQ0FBQztRQUUvQyxtQkFBYyxHQUEyQixJQUFJLENBQUM7UUFDdEQsOENBQThDO1FBQ3RDLGVBQVUsR0FBa0QsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQU81RSxJQUFJLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRDs7T0FFRztJQUNJLGlCQUFpQixDQUFDLE9BQXdCO1FBQy9DLElBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7T0FFRztJQUNJLGlCQUFpQixDQUFDLE9BQWtDO1FBQ3pELElBQUksQ0FBQyxjQUFjLEdBQUc7WUFDcEIsR0FBRyxJQUFJLENBQUMsY0FBYztZQUN0QixHQUFHLE9BQU87U0FDWCxDQUFDO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLENBQUMsQ0FB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
780
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcHJveGllcy9uZXR3b3JrLXByb3h5L3JlcXVlc3QtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sMENBQTBDLENBQUM7QUFDbEQsT0FBTyxFQUdMLFlBQVksRUFFWixZQUFZLEVBQ2IsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUdqRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDbkUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQWF4RDs7R0FFRztBQUNILE1BQU0sT0FBTyxjQUFjO0lBYXpCLFlBQ1UsT0FBNkIsRUFDN0IsY0FBOEIsRUFDOUIsWUFBeUIsRUFBRSwyQ0FBMkM7SUFDdEUsWUFBMkIsRUFDM0IsYUFBbUIsRUFBRSx5REFBeUQ7SUFDOUUsTUFBWSxDQUFDLHVEQUF1RDs7UUFMcEUsWUFBTyxHQUFQLE9BQU8sQ0FBc0I7UUFDN0IsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLGlCQUFZLEdBQVosWUFBWSxDQUFhO1FBQ3pCLGlCQUFZLEdBQVosWUFBWSxDQUFlO1FBQzNCLGtCQUFhLEdBQWIsYUFBYSxDQUFNO1FBQ25CLFdBQU0s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