@push.rocks/smartproxy 16.0.3 → 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/common/port80-adapter.js +29 -3
- package/dist_ts/forwarding/config/forwarding-types.d.ts +3 -29
- package/dist_ts/forwarding/config/forwarding-types.js +3 -36
- package/dist_ts/forwarding/config/index.d.ts +3 -2
- package/dist_ts/forwarding/config/index.js +4 -3
- package/dist_ts/forwarding/factory/forwarding-factory.js +9 -3
- package/dist_ts/forwarding/handlers/base-handler.d.ts +4 -0
- package/dist_ts/forwarding/handlers/base-handler.js +25 -3
- package/dist_ts/forwarding/index.d.ts +3 -8
- package/dist_ts/forwarding/index.js +4 -13
- package/dist_ts/proxies/network-proxy/network-proxy.js +4 -2
- package/dist_ts/proxies/network-proxy/request-handler.js +3 -3
- package/dist_ts/proxies/network-proxy/websocket-handler.js +2 -2
- package/dist_ts/proxies/smart-proxy/models/index.d.ts +0 -1
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +0 -9
- package/dist_ts/proxies/smart-proxy/models/interfaces.js +1 -12
- package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +1 -44
- package/dist_ts/proxies/smart-proxy/models/route-types.js +2 -1
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +0 -3
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +8 -13
- package/dist_ts/proxies/smart-proxy/route-manager.js +2 -3
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +2 -3
- package/dist_ts/proxies/smart-proxy/utils/index.d.ts +0 -2
- package/dist_ts/proxies/smart-proxy/utils/index.js +3 -6
- package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +48 -0
- package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +106 -2
- package/package.json +1 -1
- package/readme.plan.md +175 -77
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/common/port80-adapter.ts +26 -2
- package/ts/forwarding/config/forwarding-types.ts +12 -70
- package/ts/forwarding/config/index.ts +19 -2
- package/ts/forwarding/factory/forwarding-factory.ts +7 -2
- package/ts/forwarding/handlers/base-handler.ts +22 -2
- package/ts/forwarding/index.ts +17 -17
- package/ts/proxies/network-proxy/network-proxy.ts +4 -1
- package/ts/proxies/network-proxy/request-handler.ts +2 -2
- package/ts/proxies/network-proxy/websocket-handler.ts +1 -1
- package/ts/proxies/smart-proxy/models/index.ts +0 -3
- package/ts/proxies/smart-proxy/models/interfaces.ts +1 -17
- package/ts/proxies/smart-proxy/models/route-types.ts +2 -60
- package/ts/proxies/smart-proxy/route-connection-handler.ts +4 -14
- package/ts/proxies/smart-proxy/route-manager.ts +3 -8
- package/ts/proxies/smart-proxy/smart-proxy.ts +2 -4
- package/ts/proxies/smart-proxy/utils/index.ts +2 -5
- package/ts/proxies/smart-proxy/utils/route-patterns.ts +146 -2
- package/ts/proxies/smart-proxy/utils/route-migration-utils.ts +0 -165
|
@@ -55,17 +55,37 @@ export abstract class ForwardingHandler extends plugins.EventEmitter implements
|
|
|
55
55
|
const randomIndex = Math.floor(Math.random() * target.host.length);
|
|
56
56
|
return {
|
|
57
57
|
host: target.host[randomIndex],
|
|
58
|
-
port: target.port
|
|
58
|
+
port: this.resolvePort(target.port)
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
// Single host
|
|
63
63
|
return {
|
|
64
64
|
host: target.host,
|
|
65
|
-
port: target.port
|
|
65
|
+
port: this.resolvePort(target.port)
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Resolves a port value, handling 'preserve' and function ports
|
|
71
|
+
*/
|
|
72
|
+
protected resolvePort(port: number | 'preserve' | ((ctx: any) => number)): number {
|
|
73
|
+
if (typeof port === 'function') {
|
|
74
|
+
try {
|
|
75
|
+
// Create a minimal context for the function
|
|
76
|
+
const ctx = { port: 80 }; // Default port for minimal context
|
|
77
|
+
return port(ctx);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.error('Error resolving port function:', err);
|
|
80
|
+
return 80; // Default fallback port
|
|
81
|
+
}
|
|
82
|
+
} else if (port === 'preserve') {
|
|
83
|
+
return 80; // Default port for 'preserve' in base handler
|
|
84
|
+
} else {
|
|
85
|
+
return port;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
69
89
|
/**
|
|
70
90
|
* Redirect an HTTP request to HTTPS
|
|
71
91
|
* @param req The HTTP request
|
package/ts/forwarding/index.ts
CHANGED
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
* Provides a flexible and type-safe way to configure and manage various forwarding strategies
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
// Export types and configuration
|
|
7
|
-
export * from './config/forwarding-types.js';
|
|
8
|
-
|
|
9
6
|
// Export handlers
|
|
10
7
|
export { ForwardingHandler } from './handlers/base-handler.js';
|
|
11
8
|
export * from './handlers/http-handler.js';
|
|
@@ -16,20 +13,23 @@ export * from './handlers/https-terminate-to-https-handler.js';
|
|
|
16
13
|
// Export factory
|
|
17
14
|
export * from './factory/forwarding-factory.js';
|
|
18
15
|
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
httpsPassthrough
|
|
16
|
+
// Export types - these include TForwardingType and IForwardConfig
|
|
17
|
+
export type {
|
|
18
|
+
TForwardingType,
|
|
19
|
+
IForwardConfig,
|
|
20
|
+
IForwardingHandler
|
|
25
21
|
} from './config/forwarding-types.js';
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
export {
|
|
24
|
+
ForwardingHandlerEvents
|
|
25
|
+
} from './config/forwarding-types.js';
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
// Export route helpers directly from route-patterns
|
|
28
|
+
export {
|
|
29
|
+
createHttpRoute,
|
|
30
|
+
createHttpsTerminateRoute,
|
|
31
|
+
createHttpsPassthroughRoute,
|
|
32
|
+
createHttpToHttpsRedirect,
|
|
33
|
+
createCompleteHttpsServer,
|
|
34
|
+
createLoadBalancerRoute
|
|
35
|
+
} from '../proxies/smart-proxy/utils/route-patterns.js';
|
|
@@ -447,6 +447,8 @@ export class NetworkProxy implements IMetricsTracker {
|
|
|
447
447
|
|
|
448
448
|
// Create legacy proxy configs for the router
|
|
449
449
|
// This is only needed for backward compatibility with ProxyRouter
|
|
450
|
+
|
|
451
|
+
const defaultPort = 443; // Default port for HTTPS when using 'preserve'
|
|
450
452
|
// and will be removed in the future
|
|
451
453
|
const legacyConfigs: IReverseProxyConfig[] = [];
|
|
452
454
|
|
|
@@ -472,7 +474,8 @@ export class NetworkProxy implements IMetricsTracker {
|
|
|
472
474
|
? route.action.target.host
|
|
473
475
|
: [route.action.target.host];
|
|
474
476
|
|
|
475
|
-
|
|
477
|
+
// Handle 'preserve' port value
|
|
478
|
+
const targetPort = route.action.target.port === 'preserve' ? defaultPort : route.action.target.port;
|
|
476
479
|
|
|
477
480
|
// Get certificate information
|
|
478
481
|
const certData = certificateUpdates.get(domain);
|
|
@@ -540,7 +540,7 @@ export class RequestHandler {
|
|
|
540
540
|
this.logger.debug(`Resolved function-based port to: ${resolvedPort}`);
|
|
541
541
|
}
|
|
542
542
|
} else {
|
|
543
|
-
targetPort = matchingRoute.action.target.port;
|
|
543
|
+
targetPort = matchingRoute.action.target.port === 'preserve' ? routeContext.port : matchingRoute.action.target.port as number;
|
|
544
544
|
}
|
|
545
545
|
|
|
546
546
|
// Select a single host if an array was provided
|
|
@@ -760,7 +760,7 @@ export class RequestHandler {
|
|
|
760
760
|
this.logger.debug(`Resolved HTTP/2 function-based port to: ${resolvedPort}`);
|
|
761
761
|
}
|
|
762
762
|
} else {
|
|
763
|
-
targetPort = matchingRoute.action.target.port;
|
|
763
|
+
targetPort = matchingRoute.action.target.port === 'preserve' ? routeContext.port : matchingRoute.action.target.port as number;
|
|
764
764
|
}
|
|
765
765
|
|
|
766
766
|
// Select a single host if an array was provided
|
|
@@ -204,7 +204,7 @@ export class WebSocketHandler {
|
|
|
204
204
|
targetPort = route.action.target.port(toBaseContext(routeContext));
|
|
205
205
|
this.logger.debug(`Resolved function-based port for WebSocket: ${targetPort}`);
|
|
206
206
|
} else {
|
|
207
|
-
targetPort = route.action.target.port;
|
|
207
|
+
targetPort = route.action.target.port === 'preserve' ? routeContext.port : route.action.target.port as number;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
// Select a single host if an array was provided
|
|
@@ -8,23 +8,7 @@ import type { TForwardingType } from '../../../forwarding/config/forwarding-type
|
|
|
8
8
|
*/
|
|
9
9
|
export type TSmartProxyCertProvisionObject = plugins.tsclass.network.ICert | 'http01';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
* Alias for backward compatibility with code that uses IRoutedSmartProxyOptions
|
|
13
|
-
*/
|
|
14
|
-
export type IRoutedSmartProxyOptions = ISmartProxyOptions;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Helper functions for type checking configuration types
|
|
18
|
-
*/
|
|
19
|
-
export function isLegacyOptions(options: any): boolean {
|
|
20
|
-
// Legacy options are no longer supported
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function isRoutedOptions(options: any): boolean {
|
|
25
|
-
// All configurations are now route-based
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
11
|
+
// Legacy options and type checking functions have been removed
|
|
28
12
|
|
|
29
13
|
/**
|
|
30
14
|
* SmartProxy configuration options
|
|
@@ -69,8 +69,7 @@ export interface IRouteContext {
|
|
|
69
69
|
*/
|
|
70
70
|
export interface IRouteTarget {
|
|
71
71
|
host: string | string[] | ((context: IRouteContext) => string | string[]); // Host or hosts with optional function for dynamic resolution
|
|
72
|
-
port: number | ((context: IRouteContext) => number); // Port with optional function for dynamic mapping
|
|
73
|
-
preservePort?: boolean; // Use incoming port as target port (ignored if port is a function)
|
|
72
|
+
port: number | 'preserve' | ((context: IRouteContext) => number); // Port with optional function for dynamic mapping (use 'preserve' to keep the incoming port)
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
/**
|
|
@@ -322,61 +321,4 @@ export interface IRouteConfig {
|
|
|
322
321
|
enabled?: boolean; // Whether the route is active (default: true)
|
|
323
322
|
}
|
|
324
323
|
|
|
325
|
-
|
|
326
|
-
* Unified SmartProxy options with routes-based configuration
|
|
327
|
-
*/
|
|
328
|
-
export interface IRoutedSmartProxyOptions {
|
|
329
|
-
// The unified configuration array (required)
|
|
330
|
-
routes: IRouteConfig[];
|
|
331
|
-
|
|
332
|
-
// Global/default settings
|
|
333
|
-
defaults?: {
|
|
334
|
-
target?: {
|
|
335
|
-
host: string;
|
|
336
|
-
port: number;
|
|
337
|
-
};
|
|
338
|
-
security?: IRouteSecurity;
|
|
339
|
-
tls?: IRouteTls;
|
|
340
|
-
// ...other defaults
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
// Other global settings remain (acme, etc.)
|
|
344
|
-
acme?: IAcmeOptions;
|
|
345
|
-
|
|
346
|
-
// Connection timeouts and other global settings
|
|
347
|
-
initialDataTimeout?: number;
|
|
348
|
-
socketTimeout?: number;
|
|
349
|
-
inactivityCheckInterval?: number;
|
|
350
|
-
maxConnectionLifetime?: number;
|
|
351
|
-
inactivityTimeout?: number;
|
|
352
|
-
gracefulShutdownTimeout?: number;
|
|
353
|
-
|
|
354
|
-
// Socket optimization settings
|
|
355
|
-
noDelay?: boolean;
|
|
356
|
-
keepAlive?: boolean;
|
|
357
|
-
keepAliveInitialDelay?: number;
|
|
358
|
-
maxPendingDataSize?: number;
|
|
359
|
-
|
|
360
|
-
// Enhanced features
|
|
361
|
-
disableInactivityCheck?: boolean;
|
|
362
|
-
enableKeepAliveProbes?: boolean;
|
|
363
|
-
enableDetailedLogging?: boolean;
|
|
364
|
-
enableTlsDebugLogging?: boolean;
|
|
365
|
-
enableRandomizedTimeouts?: boolean;
|
|
366
|
-
allowSessionTicket?: boolean;
|
|
367
|
-
|
|
368
|
-
// Rate limiting and security
|
|
369
|
-
maxConnectionsPerIP?: number;
|
|
370
|
-
connectionRateLimitPerMinute?: number;
|
|
371
|
-
|
|
372
|
-
// Enhanced keep-alive settings
|
|
373
|
-
keepAliveTreatment?: 'standard' | 'extended' | 'immortal';
|
|
374
|
-
keepAliveInactivityMultiplier?: number;
|
|
375
|
-
extendedKeepAliveLifetime?: number;
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Optional certificate provider callback. Return 'http01' to use HTTP-01 challenges,
|
|
379
|
-
* or a static certificate object for immediate provisioning.
|
|
380
|
-
*/
|
|
381
|
-
certProvisionFunction?: (domain: string) => Promise<any>;
|
|
382
|
-
}
|
|
324
|
+
// Configuration moved to models/interfaces.ts as ISmartProxyOptions
|
|
@@ -3,9 +3,7 @@ import type {
|
|
|
3
3
|
IConnectionRecord,
|
|
4
4
|
ISmartProxyOptions
|
|
5
5
|
} from './models/interfaces.js';
|
|
6
|
-
|
|
7
|
-
isRoutedOptions
|
|
8
|
-
} from './models/interfaces.js';
|
|
6
|
+
// Route checking functions have been removed
|
|
9
7
|
import type {
|
|
10
8
|
IRouteConfig,
|
|
11
9
|
IRouteAction,
|
|
@@ -316,7 +314,6 @@ export class RouteConnectionHandler {
|
|
|
316
314
|
return this.setupDirectConnection(
|
|
317
315
|
socket,
|
|
318
316
|
record,
|
|
319
|
-
undefined,
|
|
320
317
|
serverName,
|
|
321
318
|
initialChunk,
|
|
322
319
|
undefined,
|
|
@@ -434,8 +431,8 @@ export class RouteConnectionHandler {
|
|
|
434
431
|
this.connectionManager.cleanupConnection(record, 'port_mapping_error');
|
|
435
432
|
return;
|
|
436
433
|
}
|
|
437
|
-
} else if (action.target.
|
|
438
|
-
// Use incoming port if
|
|
434
|
+
} else if (action.target.port === 'preserve') {
|
|
435
|
+
// Use incoming port if port is 'preserve'
|
|
439
436
|
targetPort = record.localPort;
|
|
440
437
|
} else {
|
|
441
438
|
// Use static port from configuration
|
|
@@ -457,7 +454,6 @@ export class RouteConnectionHandler {
|
|
|
457
454
|
return this.setupDirectConnection(
|
|
458
455
|
socket,
|
|
459
456
|
record,
|
|
460
|
-
undefined,
|
|
461
457
|
record.lockedDomain,
|
|
462
458
|
initialChunk,
|
|
463
459
|
undefined,
|
|
@@ -525,7 +521,7 @@ export class RouteConnectionHandler {
|
|
|
525
521
|
let targetPort: number;
|
|
526
522
|
if (typeof action.target.port === 'function') {
|
|
527
523
|
targetPort = action.target.port(routeContext);
|
|
528
|
-
} else if (action.target.
|
|
524
|
+
} else if (action.target.port === 'preserve') {
|
|
529
525
|
targetPort = record.localPort;
|
|
530
526
|
} else {
|
|
531
527
|
targetPort = action.target.port;
|
|
@@ -538,7 +534,6 @@ export class RouteConnectionHandler {
|
|
|
538
534
|
return this.setupDirectConnection(
|
|
539
535
|
socket,
|
|
540
536
|
record,
|
|
541
|
-
undefined,
|
|
542
537
|
record.lockedDomain,
|
|
543
538
|
initialChunk,
|
|
544
539
|
undefined,
|
|
@@ -656,17 +651,12 @@ export class RouteConnectionHandler {
|
|
|
656
651
|
this.connectionManager.initiateCleanupOnce(record, 'route_blocked');
|
|
657
652
|
}
|
|
658
653
|
|
|
659
|
-
/**
|
|
660
|
-
* Legacy connection handling has been removed in favor of pure route-based approach
|
|
661
|
-
*/
|
|
662
|
-
|
|
663
654
|
/**
|
|
664
655
|
* Sets up a direct connection to the target
|
|
665
656
|
*/
|
|
666
657
|
private setupDirectConnection(
|
|
667
658
|
socket: plugins.net.Socket,
|
|
668
659
|
record: IConnectionRecord,
|
|
669
|
-
_unused?: any, // kept for backward compatibility
|
|
670
660
|
serverName?: string,
|
|
671
661
|
initialChunk?: Buffer,
|
|
672
662
|
overridePort?: number,
|
|
@@ -6,12 +6,7 @@ import type {
|
|
|
6
6
|
TPortRange
|
|
7
7
|
} from './models/route-types.js';
|
|
8
8
|
import type {
|
|
9
|
-
ISmartProxyOptions
|
|
10
|
-
IRoutedSmartProxyOptions
|
|
11
|
-
} from './models/interfaces.js';
|
|
12
|
-
import {
|
|
13
|
-
isRoutedOptions,
|
|
14
|
-
isLegacyOptions
|
|
9
|
+
ISmartProxyOptions
|
|
15
10
|
} from './models/interfaces.js';
|
|
16
11
|
|
|
17
12
|
/**
|
|
@@ -29,12 +24,12 @@ export interface IRouteMatchResult {
|
|
|
29
24
|
export class RouteManager extends plugins.EventEmitter {
|
|
30
25
|
private routes: IRouteConfig[] = [];
|
|
31
26
|
private portMap: Map<number, IRouteConfig[]> = new Map();
|
|
32
|
-
private options:
|
|
27
|
+
private options: ISmartProxyOptions;
|
|
33
28
|
|
|
34
29
|
constructor(options: ISmartProxyOptions) {
|
|
35
30
|
super();
|
|
36
31
|
|
|
37
|
-
//
|
|
32
|
+
// Store options
|
|
38
33
|
this.options = options;
|
|
39
34
|
|
|
40
35
|
// Initialize routes from either source
|
|
@@ -19,10 +19,8 @@ import { createPort80HandlerOptions } from '../../common/port80-adapter.js';
|
|
|
19
19
|
|
|
20
20
|
// Import types and utilities
|
|
21
21
|
import type {
|
|
22
|
-
ISmartProxyOptions
|
|
23
|
-
IRoutedSmartProxyOptions
|
|
22
|
+
ISmartProxyOptions
|
|
24
23
|
} from './models/interfaces.js';
|
|
25
|
-
import { isRoutedOptions, isLegacyOptions } from './models/interfaces.js';
|
|
26
24
|
import type { IRouteConfig } from './models/route-types.js';
|
|
27
25
|
|
|
28
26
|
/**
|
|
@@ -650,7 +648,7 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
650
648
|
const domains: string[] = [];
|
|
651
649
|
|
|
652
650
|
// Get domains from routes
|
|
653
|
-
const routes =
|
|
651
|
+
const routes = this.settings.routes || [];
|
|
654
652
|
|
|
655
653
|
for (const route of routes) {
|
|
656
654
|
if (!route.match.domains) continue;
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* including helpers, validators, utilities, and patterns for working with routes.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
export * from './route-helpers.js';
|
|
8
|
+
// Route helpers have been consolidated in route-patterns.js
|
|
10
9
|
|
|
11
10
|
// Export route validators for validating route configurations
|
|
12
11
|
export * from './route-validators.js';
|
|
@@ -35,6 +34,4 @@ export {
|
|
|
35
34
|
addJwtAuth
|
|
36
35
|
};
|
|
37
36
|
|
|
38
|
-
//
|
|
39
|
-
// Note: These will be removed in a future version once migration is complete
|
|
40
|
-
export * from './route-migration-utils.js';
|
|
37
|
+
// Migration utilities have been removed as they are no longer needed
|
|
@@ -5,10 +5,154 @@
|
|
|
5
5
|
* These patterns can be used as templates for creating route configurations.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { IRouteConfig } from '../models/route-types.js';
|
|
9
|
-
import { createHttpRoute, createHttpsTerminateRoute, createHttpsPassthroughRoute, createCompleteHttpsServer } from './route-helpers.js';
|
|
8
|
+
import type { IRouteConfig, IRouteMatch, IRouteAction, IRouteTarget } from '../models/route-types.js';
|
|
10
9
|
import { mergeRouteConfigs } from './route-utils.js';
|
|
11
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Create a basic HTTP route configuration
|
|
13
|
+
*/
|
|
14
|
+
export function createHttpRoute(
|
|
15
|
+
domains: string | string[],
|
|
16
|
+
target: { host: string | string[]; port: number | 'preserve' | ((ctx: any) => number) },
|
|
17
|
+
options: Partial<IRouteConfig> = {}
|
|
18
|
+
): IRouteConfig {
|
|
19
|
+
const route: IRouteConfig = {
|
|
20
|
+
match: {
|
|
21
|
+
domains,
|
|
22
|
+
ports: 80
|
|
23
|
+
},
|
|
24
|
+
action: {
|
|
25
|
+
type: 'forward',
|
|
26
|
+
target: {
|
|
27
|
+
host: target.host,
|
|
28
|
+
port: target.port
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
name: options.name || `HTTP: ${Array.isArray(domains) ? domains.join(', ') : domains}`
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return mergeRouteConfigs(route, options);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Create an HTTPS route with TLS termination
|
|
39
|
+
*/
|
|
40
|
+
export function createHttpsTerminateRoute(
|
|
41
|
+
domains: string | string[],
|
|
42
|
+
target: { host: string | string[]; port: number | 'preserve' | ((ctx: any) => number) },
|
|
43
|
+
options: Partial<IRouteConfig> & {
|
|
44
|
+
certificate?: 'auto' | { key: string; cert: string };
|
|
45
|
+
reencrypt?: boolean;
|
|
46
|
+
} = {}
|
|
47
|
+
): IRouteConfig {
|
|
48
|
+
const route: IRouteConfig = {
|
|
49
|
+
match: {
|
|
50
|
+
domains,
|
|
51
|
+
ports: 443
|
|
52
|
+
},
|
|
53
|
+
action: {
|
|
54
|
+
type: 'forward',
|
|
55
|
+
target: {
|
|
56
|
+
host: target.host,
|
|
57
|
+
port: target.port
|
|
58
|
+
},
|
|
59
|
+
tls: {
|
|
60
|
+
mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate',
|
|
61
|
+
certificate: options.certificate || 'auto'
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
name: options.name || `HTTPS (terminate): ${Array.isArray(domains) ? domains.join(', ') : domains}`
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return mergeRouteConfigs(route, options);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Create an HTTPS route with TLS passthrough
|
|
72
|
+
*/
|
|
73
|
+
export function createHttpsPassthroughRoute(
|
|
74
|
+
domains: string | string[],
|
|
75
|
+
target: { host: string | string[]; port: number | 'preserve' | ((ctx: any) => number) },
|
|
76
|
+
options: Partial<IRouteConfig> = {}
|
|
77
|
+
): IRouteConfig {
|
|
78
|
+
const route: IRouteConfig = {
|
|
79
|
+
match: {
|
|
80
|
+
domains,
|
|
81
|
+
ports: 443
|
|
82
|
+
},
|
|
83
|
+
action: {
|
|
84
|
+
type: 'forward',
|
|
85
|
+
target: {
|
|
86
|
+
host: target.host,
|
|
87
|
+
port: target.port
|
|
88
|
+
},
|
|
89
|
+
tls: {
|
|
90
|
+
mode: 'passthrough'
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
name: options.name || `HTTPS (passthrough): ${Array.isArray(domains) ? domains.join(', ') : domains}`
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return mergeRouteConfigs(route, options);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Create an HTTP to HTTPS redirect route
|
|
101
|
+
*/
|
|
102
|
+
export function createHttpToHttpsRedirect(
|
|
103
|
+
domains: string | string[],
|
|
104
|
+
options: Partial<IRouteConfig> & {
|
|
105
|
+
redirectCode?: 301 | 302 | 307 | 308;
|
|
106
|
+
preservePath?: boolean;
|
|
107
|
+
} = {}
|
|
108
|
+
): IRouteConfig {
|
|
109
|
+
const route: IRouteConfig = {
|
|
110
|
+
match: {
|
|
111
|
+
domains,
|
|
112
|
+
ports: 80
|
|
113
|
+
},
|
|
114
|
+
action: {
|
|
115
|
+
type: 'redirect',
|
|
116
|
+
redirect: {
|
|
117
|
+
to: options.preservePath ? 'https://{domain}{path}' : 'https://{domain}',
|
|
118
|
+
status: options.redirectCode || 301
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
name: options.name || `HTTP to HTTPS redirect: ${Array.isArray(domains) ? domains.join(', ') : domains}`
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
return mergeRouteConfigs(route, options);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Create a complete HTTPS server with redirect from HTTP
|
|
129
|
+
*/
|
|
130
|
+
export function createCompleteHttpsServer(
|
|
131
|
+
domains: string | string[],
|
|
132
|
+
target: { host: string | string[]; port: number | 'preserve' | ((ctx: any) => number) },
|
|
133
|
+
options: Partial<IRouteConfig> & {
|
|
134
|
+
certificate?: 'auto' | { key: string; cert: string };
|
|
135
|
+
tlsMode?: 'terminate' | 'passthrough' | 'terminate-and-reencrypt';
|
|
136
|
+
redirectCode?: 301 | 302 | 307 | 308;
|
|
137
|
+
} = {}
|
|
138
|
+
): IRouteConfig[] {
|
|
139
|
+
// Create the TLS route based on the selected mode
|
|
140
|
+
const tlsRoute = options.tlsMode === 'passthrough'
|
|
141
|
+
? createHttpsPassthroughRoute(domains, target, options)
|
|
142
|
+
: createHttpsTerminateRoute(domains, target, {
|
|
143
|
+
...options,
|
|
144
|
+
reencrypt: options.tlsMode === 'terminate-and-reencrypt'
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Create the HTTP to HTTPS redirect route
|
|
148
|
+
const redirectRoute = createHttpToHttpsRedirect(domains, {
|
|
149
|
+
redirectCode: options.redirectCode,
|
|
150
|
+
preservePath: true
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return [tlsRoute, redirectRoute];
|
|
154
|
+
}
|
|
155
|
+
|
|
12
156
|
/**
|
|
13
157
|
* Create an API Gateway route pattern
|
|
14
158
|
* @param domains Domain(s) to match
|