@push.rocks/smartproxy 13.1.3 → 15.0.1
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 +3 -3
- package/dist_ts/proxies/smart-proxy/domain-config-manager.d.ts +15 -0
- package/dist_ts/proxies/smart-proxy/domain-config-manager.js +140 -9
- package/dist_ts/proxies/smart-proxy/index.d.ts +5 -3
- package/dist_ts/proxies/smart-proxy/index.js +9 -5
- package/dist_ts/proxies/smart-proxy/models/index.d.ts +2 -0
- package/dist_ts/proxies/smart-proxy/models/index.js +2 -1
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +82 -15
- package/dist_ts/proxies/smart-proxy/models/interfaces.js +11 -1
- package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +133 -0
- package/dist_ts/proxies/smart-proxy/models/route-types.js +2 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +55 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +804 -0
- package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +127 -0
- package/dist_ts/proxies/smart-proxy/route-helpers.js +196 -0
- package/dist_ts/proxies/smart-proxy/route-manager.d.ts +103 -0
- package/dist_ts/proxies/smart-proxy/route-manager.js +483 -0
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +19 -8
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +250 -46
- package/package.json +2 -2
- package/readme.md +675 -446
- package/readme.plan.md +311 -250
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/proxies/smart-proxy/domain-config-manager.ts +157 -14
- package/ts/proxies/smart-proxy/index.ts +20 -4
- package/ts/proxies/smart-proxy/models/index.ts +4 -0
- package/ts/proxies/smart-proxy/models/interfaces.ts +92 -13
- package/ts/proxies/smart-proxy/models/route-types.ts +184 -0
- package/ts/proxies/smart-proxy/route-connection-handler.ts +1117 -0
- package/ts/proxies/smart-proxy/route-helpers.ts +344 -0
- package/ts/proxies/smart-proxy/route-manager.ts +587 -0
- package/ts/proxies/smart-proxy/smart-proxy.ts +312 -69
|
@@ -3,6 +3,8 @@ import type { IDomainConfig, ISmartProxyOptions } from './models/interfaces.js';
|
|
|
3
3
|
import type { TForwardingType, IForwardConfig } from '../../forwarding/config/forwarding-types.js';
|
|
4
4
|
import type { ForwardingHandler } from '../../forwarding/handlers/base-handler.js';
|
|
5
5
|
import { ForwardingHandlerFactory } from '../../forwarding/factory/forwarding-factory.js';
|
|
6
|
+
import type { IRouteConfig } from './models/route-types.js';
|
|
7
|
+
import { RouteManager } from './route-manager.js';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Manages domain configurations and target selection
|
|
@@ -14,13 +16,112 @@ export class DomainConfigManager {
|
|
|
14
16
|
// Cache forwarding handlers for each domain config
|
|
15
17
|
private forwardingHandlers: Map<IDomainConfig, ForwardingHandler> = new Map();
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
// Store derived domain configs from routes
|
|
20
|
+
private derivedDomainConfigs: IDomainConfig[] = [];
|
|
21
|
+
|
|
22
|
+
// Reference to RouteManager for route-based configuration
|
|
23
|
+
private routeManager?: RouteManager;
|
|
24
|
+
|
|
25
|
+
constructor(private settings: ISmartProxyOptions) {
|
|
26
|
+
// Initialize with derived domain configs if using route-based configuration
|
|
27
|
+
if (settings.routes && !settings.domainConfigs) {
|
|
28
|
+
this.generateDomainConfigsFromRoutes();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Set the route manager reference for route-based queries
|
|
34
|
+
*/
|
|
35
|
+
public setRouteManager(routeManager: RouteManager): void {
|
|
36
|
+
this.routeManager = routeManager;
|
|
37
|
+
|
|
38
|
+
// Regenerate domain configs from routes if needed
|
|
39
|
+
if (this.settings.routes && (!this.settings.domainConfigs || this.settings.domainConfigs.length === 0)) {
|
|
40
|
+
this.generateDomainConfigsFromRoutes();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Generate domain configs from routes
|
|
46
|
+
*/
|
|
47
|
+
public generateDomainConfigsFromRoutes(): void {
|
|
48
|
+
this.derivedDomainConfigs = [];
|
|
49
|
+
|
|
50
|
+
if (!this.settings.routes) return;
|
|
51
|
+
|
|
52
|
+
for (const route of this.settings.routes) {
|
|
53
|
+
if (route.action.type !== 'forward' || !route.match.domains) continue;
|
|
54
|
+
|
|
55
|
+
// Convert route to domain config
|
|
56
|
+
const domainConfig = this.routeToDomainConfig(route);
|
|
57
|
+
if (domainConfig) {
|
|
58
|
+
this.derivedDomainConfigs.push(domainConfig);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Convert a route to a domain config
|
|
65
|
+
*/
|
|
66
|
+
private routeToDomainConfig(route: IRouteConfig): IDomainConfig | null {
|
|
67
|
+
if (route.action.type !== 'forward' || !route.action.target) return null;
|
|
68
|
+
|
|
69
|
+
// Get domains from route
|
|
70
|
+
const domains = Array.isArray(route.match.domains) ?
|
|
71
|
+
route.match.domains :
|
|
72
|
+
(route.match.domains ? [route.match.domains] : []);
|
|
73
|
+
|
|
74
|
+
if (domains.length === 0) return null;
|
|
75
|
+
|
|
76
|
+
// Determine forwarding type based on TLS mode
|
|
77
|
+
let forwardingType: TForwardingType = 'http-only';
|
|
78
|
+
if (route.action.tls) {
|
|
79
|
+
switch (route.action.tls.mode) {
|
|
80
|
+
case 'passthrough':
|
|
81
|
+
forwardingType = 'https-passthrough';
|
|
82
|
+
break;
|
|
83
|
+
case 'terminate':
|
|
84
|
+
forwardingType = 'https-terminate-to-http';
|
|
85
|
+
break;
|
|
86
|
+
case 'terminate-and-reencrypt':
|
|
87
|
+
forwardingType = 'https-terminate-to-https';
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Create domain config
|
|
93
|
+
return {
|
|
94
|
+
domains,
|
|
95
|
+
forwarding: {
|
|
96
|
+
type: forwardingType,
|
|
97
|
+
target: {
|
|
98
|
+
host: route.action.target.host,
|
|
99
|
+
port: route.action.target.port
|
|
100
|
+
},
|
|
101
|
+
security: route.action.security ? {
|
|
102
|
+
allowedIps: route.action.security.allowedIps,
|
|
103
|
+
blockedIps: route.action.security.blockedIps,
|
|
104
|
+
maxConnections: route.action.security.maxConnections
|
|
105
|
+
} : undefined,
|
|
106
|
+
https: route.action.tls && route.action.tls.certificate !== 'auto' ? {
|
|
107
|
+
customCert: route.action.tls.certificate
|
|
108
|
+
} : undefined,
|
|
109
|
+
advanced: route.action.advanced
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
19
114
|
/**
|
|
20
115
|
* Updates the domain configurations
|
|
21
116
|
*/
|
|
22
117
|
public updateDomainConfigs(newDomainConfigs: IDomainConfig[]): void {
|
|
23
|
-
|
|
118
|
+
// If we're using domainConfigs property, update it
|
|
119
|
+
if (this.settings.domainConfigs) {
|
|
120
|
+
this.settings.domainConfigs = newDomainConfigs;
|
|
121
|
+
} else {
|
|
122
|
+
// Otherwise update our derived configs
|
|
123
|
+
this.derivedDomainConfigs = newDomainConfigs;
|
|
124
|
+
}
|
|
24
125
|
|
|
25
126
|
// Reset target indices for removed configs
|
|
26
127
|
const currentConfigSet = new Set(newDomainConfigs);
|
|
@@ -60,7 +161,8 @@ export class DomainConfigManager {
|
|
|
60
161
|
* Get all domain configurations
|
|
61
162
|
*/
|
|
62
163
|
public getDomainConfigs(): IDomainConfig[] {
|
|
63
|
-
|
|
164
|
+
// Use domainConfigs from settings if available, otherwise use derived configs
|
|
165
|
+
return this.settings.domainConfigs || this.derivedDomainConfigs;
|
|
64
166
|
}
|
|
65
167
|
|
|
66
168
|
/**
|
|
@@ -69,23 +171,64 @@ export class DomainConfigManager {
|
|
|
69
171
|
public findDomainConfig(serverName: string): IDomainConfig | undefined {
|
|
70
172
|
if (!serverName) return undefined;
|
|
71
173
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
174
|
+
// Get domain configs from the appropriate source
|
|
175
|
+
const domainConfigs = this.getDomainConfigs();
|
|
176
|
+
|
|
177
|
+
// Check for direct match
|
|
178
|
+
for (const config of domainConfigs) {
|
|
179
|
+
if (config.domains.some(d => plugins.minimatch(serverName, d))) {
|
|
180
|
+
return config;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// No match found
|
|
185
|
+
return undefined;
|
|
75
186
|
}
|
|
76
187
|
|
|
77
188
|
/**
|
|
78
189
|
* Find domain config for a specific port
|
|
79
190
|
*/
|
|
80
191
|
public findDomainConfigForPort(port: number): IDomainConfig | undefined {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
192
|
+
// Get domain configs from the appropriate source
|
|
193
|
+
const domainConfigs = this.getDomainConfigs();
|
|
194
|
+
|
|
195
|
+
// Check if any domain config has a matching port range
|
|
196
|
+
for (const domain of domainConfigs) {
|
|
197
|
+
const portRanges = domain.forwarding?.advanced?.portRanges;
|
|
198
|
+
if (portRanges && portRanges.length > 0 && this.isPortInRanges(port, portRanges)) {
|
|
199
|
+
return domain;
|
|
87
200
|
}
|
|
88
|
-
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// If we're in route-based mode, also check routes for this port
|
|
204
|
+
if (this.settings.routes && (!this.settings.domainConfigs || this.settings.domainConfigs.length === 0)) {
|
|
205
|
+
const routesForPort = this.settings.routes.filter(route => {
|
|
206
|
+
// Check if this port is in the route's ports
|
|
207
|
+
if (typeof route.match.ports === 'number') {
|
|
208
|
+
return route.match.ports === port;
|
|
209
|
+
} else if (Array.isArray(route.match.ports)) {
|
|
210
|
+
return route.match.ports.some(p => {
|
|
211
|
+
if (typeof p === 'number') {
|
|
212
|
+
return p === port;
|
|
213
|
+
} else if (p.from && p.to) {
|
|
214
|
+
return port >= p.from && port <= p.to;
|
|
215
|
+
}
|
|
216
|
+
return false;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return false;
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// If we found any routes for this port, convert the first one to a domain config
|
|
223
|
+
if (routesForPort.length > 0 && routesForPort[0].action.type === 'forward') {
|
|
224
|
+
const domainConfig = this.routeToDomainConfig(routesForPort[0]);
|
|
225
|
+
if (domainConfig) {
|
|
226
|
+
return domainConfig;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return undefined;
|
|
89
232
|
}
|
|
90
233
|
|
|
91
234
|
/**
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SmartProxy implementation
|
|
3
|
+
*
|
|
4
|
+
* Version 14.0.0: Unified Route-Based Configuration API
|
|
3
5
|
*/
|
|
4
6
|
// Re-export models
|
|
5
7
|
export * from './models/index.js';
|
|
@@ -7,12 +9,26 @@ export * from './models/index.js';
|
|
|
7
9
|
// Export the main SmartProxy class
|
|
8
10
|
export { SmartProxy } from './smart-proxy.js';
|
|
9
11
|
|
|
10
|
-
// Export supporting classes
|
|
12
|
+
// Export core supporting classes
|
|
11
13
|
export { ConnectionManager } from './connection-manager.js';
|
|
12
14
|
export { SecurityManager } from './security-manager.js';
|
|
13
|
-
export { DomainConfigManager } from './domain-config-manager.js';
|
|
14
15
|
export { TimeoutManager } from './timeout-manager.js';
|
|
15
16
|
export { TlsManager } from './tls-manager.js';
|
|
16
17
|
export { NetworkProxyBridge } from './network-proxy-bridge.js';
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
// Export route-based components
|
|
20
|
+
export { RouteManager } from './route-manager.js';
|
|
21
|
+
export { RouteConnectionHandler } from './route-connection-handler.js';
|
|
22
|
+
|
|
23
|
+
// Export route helpers for configuration
|
|
24
|
+
export {
|
|
25
|
+
createRoute,
|
|
26
|
+
createHttpRoute,
|
|
27
|
+
createHttpsRoute,
|
|
28
|
+
createPassthroughRoute,
|
|
29
|
+
createRedirectRoute,
|
|
30
|
+
createHttpToHttpsRedirect,
|
|
31
|
+
createBlockRoute,
|
|
32
|
+
createLoadBalancerRoute,
|
|
33
|
+
createHttpsServer
|
|
34
|
+
} from './route-helpers.js';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../../plugins.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
|
|
3
|
+
import type { IRouteConfig } from './route-types.js';
|
|
4
|
+
import type { TForwardingType } from '../../../forwarding/config/forwarding-types.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Provision object for static or HTTP-01 certificate
|
|
@@ -7,27 +9,103 @@ import type { IForwardConfig } from '../../../forwarding/config/forwarding-types
|
|
|
7
9
|
export type TSmartProxyCertProvisionObject = plugins.tsclass.network.ICert | 'http01';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Alias for backward compatibility with code that uses IRoutedSmartProxyOptions
|
|
13
|
+
*/
|
|
14
|
+
export type IRoutedSmartProxyOptions = ISmartProxyOptions;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Legacy domain configuration interface for backward compatibility
|
|
11
18
|
*/
|
|
12
19
|
export interface IDomainConfig {
|
|
13
|
-
domains: string[];
|
|
14
|
-
forwarding:
|
|
20
|
+
domains: string[];
|
|
21
|
+
forwarding: {
|
|
22
|
+
type: TForwardingType;
|
|
23
|
+
target: {
|
|
24
|
+
host: string | string[];
|
|
25
|
+
port: number;
|
|
26
|
+
};
|
|
27
|
+
acme?: {
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
maintenance?: boolean;
|
|
30
|
+
production?: boolean;
|
|
31
|
+
forwardChallenges?: {
|
|
32
|
+
host: string;
|
|
33
|
+
port: number;
|
|
34
|
+
useTls?: boolean;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
http?: {
|
|
38
|
+
enabled?: boolean;
|
|
39
|
+
redirectToHttps?: boolean;
|
|
40
|
+
headers?: Record<string, string>;
|
|
41
|
+
};
|
|
42
|
+
https?: {
|
|
43
|
+
customCert?: {
|
|
44
|
+
key: string;
|
|
45
|
+
cert: string;
|
|
46
|
+
};
|
|
47
|
+
forwardSni?: boolean;
|
|
48
|
+
};
|
|
49
|
+
security?: {
|
|
50
|
+
allowedIps?: string[];
|
|
51
|
+
blockedIps?: string[];
|
|
52
|
+
maxConnections?: number;
|
|
53
|
+
};
|
|
54
|
+
advanced?: {
|
|
55
|
+
portRanges?: Array<{ from: number; to: number }>;
|
|
56
|
+
networkProxyPort?: number;
|
|
57
|
+
keepAlive?: boolean;
|
|
58
|
+
timeout?: number;
|
|
59
|
+
headers?: Record<string, string>;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
15
62
|
}
|
|
16
63
|
|
|
17
64
|
/**
|
|
18
|
-
*
|
|
65
|
+
* Helper functions for type checking configuration types
|
|
66
|
+
*/
|
|
67
|
+
export function isLegacyOptions(options: any): boolean {
|
|
68
|
+
return !!(options.domainConfigs && options.domainConfigs.length > 0 &&
|
|
69
|
+
(!options.routes || options.routes.length === 0));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function isRoutedOptions(options: any): boolean {
|
|
73
|
+
return !!(options.routes && options.routes.length > 0);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* SmartProxy configuration options
|
|
19
78
|
*/
|
|
20
|
-
import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
|
|
21
79
|
export interface ISmartProxyOptions {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
80
|
+
// The unified configuration array (required)
|
|
81
|
+
routes: IRouteConfig[];
|
|
82
|
+
|
|
83
|
+
// Legacy options for backward compatibility
|
|
84
|
+
fromPort?: number;
|
|
85
|
+
toPort?: number;
|
|
26
86
|
sniEnabled?: boolean;
|
|
87
|
+
domainConfigs?: IDomainConfig[];
|
|
88
|
+
targetIP?: string;
|
|
27
89
|
defaultAllowedIPs?: string[];
|
|
28
90
|
defaultBlockedIPs?: string[];
|
|
91
|
+
globalPortRanges?: Array<{ from: number; to: number }>;
|
|
92
|
+
forwardAllGlobalRanges?: boolean;
|
|
29
93
|
preserveSourceIP?: boolean;
|
|
30
94
|
|
|
95
|
+
// Global/default settings
|
|
96
|
+
defaults?: {
|
|
97
|
+
target?: {
|
|
98
|
+
host: string; // Default host to use when not specified in routes
|
|
99
|
+
port: number; // Default port to use when not specified in routes
|
|
100
|
+
};
|
|
101
|
+
security?: {
|
|
102
|
+
allowedIPs?: string[]; // Default allowed IPs
|
|
103
|
+
blockedIPs?: string[]; // Default blocked IPs
|
|
104
|
+
maxConnections?: number; // Default max connections
|
|
105
|
+
};
|
|
106
|
+
preserveSourceIP?: boolean; // Default source IP preservation
|
|
107
|
+
};
|
|
108
|
+
|
|
31
109
|
// TLS options
|
|
32
110
|
pfx?: Buffer;
|
|
33
111
|
key?: string | Buffer | Array<Buffer | string>;
|
|
@@ -50,8 +128,6 @@ export interface ISmartProxyOptions {
|
|
|
50
128
|
inactivityTimeout?: number; // Inactivity timeout (ms), default: 14400000 (4h)
|
|
51
129
|
|
|
52
130
|
gracefulShutdownTimeout?: number; // (ms) maximum time to wait for connections to close during shutdown
|
|
53
|
-
globalPortRanges: Array<{ from: number; to: number }>; // Global allowed port ranges
|
|
54
|
-
forwardAllGlobalRanges?: boolean; // When true, forwards all connections on global port ranges to the global targetIP
|
|
55
131
|
|
|
56
132
|
// Socket optimization settings
|
|
57
133
|
noDelay?: boolean; // Disable Nagle's algorithm (default: true)
|
|
@@ -108,6 +184,9 @@ export interface IConnectionRecord {
|
|
|
108
184
|
pendingData: Buffer[]; // Buffer to hold data during connection setup
|
|
109
185
|
pendingDataSize: number; // Track total size of pending data
|
|
110
186
|
|
|
187
|
+
// Legacy property for backward compatibility
|
|
188
|
+
domainConfig?: IDomainConfig;
|
|
189
|
+
|
|
111
190
|
// Enhanced tracking fields
|
|
112
191
|
bytesReceived: number; // Total bytes received
|
|
113
192
|
bytesSent: number; // Total bytes sent
|
|
@@ -116,7 +195,7 @@ export interface IConnectionRecord {
|
|
|
116
195
|
isTLS: boolean; // Whether this connection is a TLS connection
|
|
117
196
|
tlsHandshakeComplete: boolean; // Whether the TLS handshake is complete
|
|
118
197
|
hasReceivedInitialData: boolean; // Whether initial data has been received
|
|
119
|
-
|
|
198
|
+
routeConfig?: IRouteConfig; // Associated route config for this connection
|
|
120
199
|
|
|
121
200
|
// Keep-alive tracking
|
|
122
201
|
hasKeepAlive: boolean; // Whether keep-alive is enabled for this connection
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import * as plugins from '../../../plugins.js';
|
|
2
|
+
import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
|
|
3
|
+
import type { TForwardingType } from '../../../forwarding/config/forwarding-types.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Supported action types for route configurations
|
|
7
|
+
*/
|
|
8
|
+
export type TRouteActionType = 'forward' | 'redirect' | 'block';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* TLS handling modes for route configurations
|
|
12
|
+
*/
|
|
13
|
+
export type TTlsMode = 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Port range specification format
|
|
17
|
+
*/
|
|
18
|
+
export type TPortRange = number | number[] | Array<{ from: number; to: number }>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Route match criteria for incoming requests
|
|
22
|
+
*/
|
|
23
|
+
export interface IRouteMatch {
|
|
24
|
+
// Listen on these ports (required)
|
|
25
|
+
ports: TPortRange;
|
|
26
|
+
|
|
27
|
+
// Optional domain patterns to match (default: all domains)
|
|
28
|
+
domains?: string | string[];
|
|
29
|
+
|
|
30
|
+
// Advanced matching criteria
|
|
31
|
+
path?: string; // Match specific paths
|
|
32
|
+
clientIp?: string[]; // Match specific client IPs
|
|
33
|
+
tlsVersion?: string[]; // Match specific TLS versions
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Target configuration for forwarding
|
|
38
|
+
*/
|
|
39
|
+
export interface IRouteTarget {
|
|
40
|
+
host: string | string[]; // Support single host or round-robin
|
|
41
|
+
port: number;
|
|
42
|
+
preservePort?: boolean; // Use incoming port as target port
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* TLS configuration for route actions
|
|
47
|
+
*/
|
|
48
|
+
export interface IRouteTls {
|
|
49
|
+
mode: TTlsMode;
|
|
50
|
+
certificate?: 'auto' | { // Auto = use ACME
|
|
51
|
+
key: string;
|
|
52
|
+
cert: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Redirect configuration for route actions
|
|
58
|
+
*/
|
|
59
|
+
export interface IRouteRedirect {
|
|
60
|
+
to: string; // URL or template with {domain}, {port}, etc.
|
|
61
|
+
status: 301 | 302 | 307 | 308;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Security options for route actions
|
|
66
|
+
*/
|
|
67
|
+
export interface IRouteSecurity {
|
|
68
|
+
allowedIps?: string[];
|
|
69
|
+
blockedIps?: string[];
|
|
70
|
+
maxConnections?: number;
|
|
71
|
+
authentication?: {
|
|
72
|
+
type: 'basic' | 'digest' | 'oauth';
|
|
73
|
+
// Auth-specific options would go here
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Advanced options for route actions
|
|
79
|
+
*/
|
|
80
|
+
export interface IRouteAdvanced {
|
|
81
|
+
timeout?: number;
|
|
82
|
+
headers?: Record<string, string>;
|
|
83
|
+
keepAlive?: boolean;
|
|
84
|
+
// Additional advanced options would go here
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Action configuration for route handling
|
|
89
|
+
*/
|
|
90
|
+
export interface IRouteAction {
|
|
91
|
+
// Basic routing
|
|
92
|
+
type: TRouteActionType;
|
|
93
|
+
|
|
94
|
+
// Target for forwarding
|
|
95
|
+
target?: IRouteTarget;
|
|
96
|
+
|
|
97
|
+
// TLS handling
|
|
98
|
+
tls?: IRouteTls;
|
|
99
|
+
|
|
100
|
+
// For redirects
|
|
101
|
+
redirect?: IRouteRedirect;
|
|
102
|
+
|
|
103
|
+
// Security options
|
|
104
|
+
security?: IRouteSecurity;
|
|
105
|
+
|
|
106
|
+
// Advanced options
|
|
107
|
+
advanced?: IRouteAdvanced;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The core unified configuration interface
|
|
112
|
+
*/
|
|
113
|
+
export interface IRouteConfig {
|
|
114
|
+
// What to match
|
|
115
|
+
match: IRouteMatch;
|
|
116
|
+
|
|
117
|
+
// What to do with matched traffic
|
|
118
|
+
action: IRouteAction;
|
|
119
|
+
|
|
120
|
+
// Optional metadata
|
|
121
|
+
name?: string; // Human-readable name for this route
|
|
122
|
+
description?: string; // Description of the route's purpose
|
|
123
|
+
priority?: number; // Controls matching order (higher = matched first)
|
|
124
|
+
tags?: string[]; // Arbitrary tags for categorization
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Unified SmartProxy options with routes-based configuration
|
|
129
|
+
*/
|
|
130
|
+
export interface IRoutedSmartProxyOptions {
|
|
131
|
+
// The unified configuration array (required)
|
|
132
|
+
routes: IRouteConfig[];
|
|
133
|
+
|
|
134
|
+
// Global/default settings
|
|
135
|
+
defaults?: {
|
|
136
|
+
target?: {
|
|
137
|
+
host: string;
|
|
138
|
+
port: number;
|
|
139
|
+
};
|
|
140
|
+
security?: IRouteSecurity;
|
|
141
|
+
tls?: IRouteTls;
|
|
142
|
+
// ...other defaults
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// Other global settings remain (acme, etc.)
|
|
146
|
+
acme?: IAcmeOptions;
|
|
147
|
+
|
|
148
|
+
// Connection timeouts and other global settings
|
|
149
|
+
initialDataTimeout?: number;
|
|
150
|
+
socketTimeout?: number;
|
|
151
|
+
inactivityCheckInterval?: number;
|
|
152
|
+
maxConnectionLifetime?: number;
|
|
153
|
+
inactivityTimeout?: number;
|
|
154
|
+
gracefulShutdownTimeout?: number;
|
|
155
|
+
|
|
156
|
+
// Socket optimization settings
|
|
157
|
+
noDelay?: boolean;
|
|
158
|
+
keepAlive?: boolean;
|
|
159
|
+
keepAliveInitialDelay?: number;
|
|
160
|
+
maxPendingDataSize?: number;
|
|
161
|
+
|
|
162
|
+
// Enhanced features
|
|
163
|
+
disableInactivityCheck?: boolean;
|
|
164
|
+
enableKeepAliveProbes?: boolean;
|
|
165
|
+
enableDetailedLogging?: boolean;
|
|
166
|
+
enableTlsDebugLogging?: boolean;
|
|
167
|
+
enableRandomizedTimeouts?: boolean;
|
|
168
|
+
allowSessionTicket?: boolean;
|
|
169
|
+
|
|
170
|
+
// Rate limiting and security
|
|
171
|
+
maxConnectionsPerIP?: number;
|
|
172
|
+
connectionRateLimitPerMinute?: number;
|
|
173
|
+
|
|
174
|
+
// Enhanced keep-alive settings
|
|
175
|
+
keepAliveTreatment?: 'standard' | 'extended' | 'immortal';
|
|
176
|
+
keepAliveInactivityMultiplier?: number;
|
|
177
|
+
extendedKeepAliveLifetime?: number;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Optional certificate provider callback. Return 'http01' to use HTTP-01 challenges,
|
|
181
|
+
* or a static certificate object for immediate provisioning.
|
|
182
|
+
*/
|
|
183
|
+
certProvisionFunction?: (domain: string) => Promise<any>;
|
|
184
|
+
}
|