@push.rocks/smartproxy 21.1.7 → 22.6.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/changelog.md +109 -0
- package/dist_rust/rustproxy +0 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/core/utils/shared-security-manager.d.ts +17 -0
- package/dist_ts/core/utils/shared-security-manager.js +66 -1
- package/dist_ts/index.d.ts +1 -5
- package/dist_ts/index.js +3 -9
- package/dist_ts/protocols/common/fragment-handler.js +5 -1
- package/dist_ts/proxies/http-proxy/default-certificates.d.ts +54 -0
- package/dist_ts/proxies/http-proxy/default-certificates.js +127 -0
- package/dist_ts/proxies/http-proxy/http-proxy.d.ts +1 -1
- package/dist_ts/proxies/http-proxy/http-proxy.js +9 -14
- package/dist_ts/proxies/http-proxy/index.d.ts +5 -1
- package/dist_ts/proxies/http-proxy/index.js +6 -2
- package/dist_ts/proxies/http-proxy/security-manager.d.ts +4 -12
- package/dist_ts/proxies/http-proxy/security-manager.js +66 -99
- package/dist_ts/proxies/index.d.ts +1 -5
- package/dist_ts/proxies/index.js +2 -6
- package/dist_ts/proxies/nftables-proxy/index.d.ts +1 -0
- package/dist_ts/proxies/nftables-proxy/index.js +2 -1
- package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +4 -26
- package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +84 -236
- package/dist_ts/proxies/nftables-proxy/utils/index.d.ts +9 -0
- package/dist_ts/proxies/nftables-proxy/utils/index.js +12 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.d.ts +66 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.js +131 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.d.ts +39 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.js +112 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.d.ts +59 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.js +130 -0
- package/dist_ts/proxies/smart-proxy/certificate-manager.js +4 -3
- package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +13 -2
- package/dist_ts/proxies/smart-proxy/connection-manager.js +16 -6
- package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +35 -10
- package/dist_ts/proxies/smart-proxy/index.d.ts +5 -10
- package/dist_ts/proxies/smart-proxy/index.js +7 -13
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -3
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +17 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +72 -9
- package/dist_ts/proxies/smart-proxy/route-preprocessor.d.ts +37 -0
- package/dist_ts/proxies/smart-proxy/route-preprocessor.js +103 -0
- package/dist_ts/proxies/smart-proxy/rust-binary-locator.d.ts +23 -0
- package/dist_ts/proxies/smart-proxy/rust-binary-locator.js +104 -0
- package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.d.ts +74 -0
- package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.js +146 -0
- package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.d.ts +49 -0
- package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +259 -0
- package/dist_ts/proxies/smart-proxy/security-manager.d.ts +14 -12
- package/dist_ts/proxies/smart-proxy/security-manager.js +80 -74
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +39 -157
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +224 -622
- package/dist_ts/proxies/smart-proxy/socket-handler-server.d.ts +45 -0
- package/dist_ts/proxies/smart-proxy/socket-handler-server.js +253 -0
- package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +2 -9
- package/dist_ts/proxies/smart-proxy/tls-manager.js +3 -26
- package/dist_ts/proxies/smart-proxy/utils/index.d.ts +1 -1
- package/dist_ts/proxies/smart-proxy/utils/index.js +3 -4
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/api-helpers.d.ts +49 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/api-helpers.js +108 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.d.ts +57 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.js +89 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/http-helpers.d.ts +17 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/http-helpers.js +32 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/https-helpers.d.ts +68 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/https-helpers.js +117 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/index.d.ts +17 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/index.js +27 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.d.ts +63 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.js +105 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.d.ts +83 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.js +126 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/security-helpers.d.ts +47 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/security-helpers.js +66 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.d.ts +70 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.js +287 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.d.ts +46 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.js +67 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +4 -457
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +6 -950
- package/dist_ts/proxies/smart-proxy/utils/route-utils.js +2 -2
- package/dist_ts/proxies/smart-proxy/utils/route-validator.d.ts +67 -1
- package/dist_ts/proxies/smart-proxy/utils/route-validator.js +251 -3
- package/dist_ts/routing/index.d.ts +1 -1
- package/dist_ts/routing/index.js +3 -3
- package/dist_ts/routing/models/http-types.d.ts +119 -4
- package/dist_ts/routing/models/http-types.js +93 -5
- package/npmextra.json +12 -6
- package/package.json +34 -24
- package/readme.hints.md +184 -1
- package/readme.md +580 -266
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/utils/shared-security-manager.ts +98 -13
- package/ts/index.ts +4 -12
- package/ts/protocols/common/fragment-handler.ts +4 -0
- package/ts/proxies/index.ts +1 -9
- package/ts/proxies/nftables-proxy/index.ts +1 -0
- package/ts/proxies/nftables-proxy/nftables-proxy.ts +116 -290
- package/ts/proxies/nftables-proxy/utils/index.ts +38 -0
- package/ts/proxies/nftables-proxy/utils/nft-command-executor.ts +162 -0
- package/ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.ts +125 -0
- package/ts/proxies/nftables-proxy/utils/nft-rule-validator.ts +156 -0
- package/ts/proxies/smart-proxy/index.ts +6 -13
- package/ts/proxies/smart-proxy/models/interfaces.ts +6 -5
- package/ts/proxies/smart-proxy/route-preprocessor.ts +122 -0
- package/ts/proxies/smart-proxy/rust-binary-locator.ts +112 -0
- package/ts/proxies/smart-proxy/rust-metrics-adapter.ts +161 -0
- package/ts/proxies/smart-proxy/rust-proxy-bridge.ts +310 -0
- package/ts/proxies/smart-proxy/smart-proxy.ts +282 -800
- package/ts/proxies/smart-proxy/socket-handler-server.ts +279 -0
- package/ts/proxies/smart-proxy/utils/index.ts +3 -5
- package/ts/proxies/smart-proxy/utils/route-helpers/api-helpers.ts +144 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.ts +124 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/http-helpers.ts +40 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/https-helpers.ts +163 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/index.ts +62 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.ts +154 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.ts +202 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/security-helpers.ts +96 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.ts +337 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.ts +98 -0
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +5 -1302
- package/ts/proxies/smart-proxy/utils/route-utils.ts +1 -1
- package/ts/proxies/smart-proxy/utils/route-validator.ts +274 -4
- package/ts/routing/index.ts +2 -2
- package/ts/routing/models/http-types.ts +147 -4
- package/ts/proxies/http-proxy/certificate-manager.ts +0 -244
- package/ts/proxies/http-proxy/connection-pool.ts +0 -228
- package/ts/proxies/http-proxy/context-creator.ts +0 -145
- package/ts/proxies/http-proxy/function-cache.ts +0 -279
- package/ts/proxies/http-proxy/handlers/index.ts +0 -5
- package/ts/proxies/http-proxy/http-proxy.ts +0 -675
- package/ts/proxies/http-proxy/http-request-handler.ts +0 -331
- package/ts/proxies/http-proxy/http2-request-handler.ts +0 -255
- package/ts/proxies/http-proxy/index.ts +0 -13
- package/ts/proxies/http-proxy/models/http-types.ts +0 -148
- package/ts/proxies/http-proxy/models/index.ts +0 -5
- package/ts/proxies/http-proxy/models/types.ts +0 -125
- package/ts/proxies/http-proxy/request-handler.ts +0 -878
- package/ts/proxies/http-proxy/security-manager.ts +0 -433
- package/ts/proxies/http-proxy/websocket-handler.ts +0 -581
- package/ts/proxies/smart-proxy/acme-state-manager.ts +0 -112
- package/ts/proxies/smart-proxy/cert-store.ts +0 -92
- package/ts/proxies/smart-proxy/certificate-manager.ts +0 -894
- package/ts/proxies/smart-proxy/connection-manager.ts +0 -796
- package/ts/proxies/smart-proxy/http-proxy-bridge.ts +0 -187
- package/ts/proxies/smart-proxy/metrics-collector.ts +0 -453
- package/ts/proxies/smart-proxy/nftables-manager.ts +0 -271
- package/ts/proxies/smart-proxy/port-manager.ts +0 -358
- package/ts/proxies/smart-proxy/route-connection-handler.ts +0 -1640
- package/ts/proxies/smart-proxy/route-orchestrator.ts +0 -297
- package/ts/proxies/smart-proxy/security-manager.ts +0 -257
- package/ts/proxies/smart-proxy/throughput-tracker.ts +0 -138
- package/ts/proxies/smart-proxy/timeout-manager.ts +0 -196
- package/ts/proxies/smart-proxy/tls-manager.ts +0 -207
- package/ts/proxies/smart-proxy/utils/route-validators.ts +0 -283
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { RoutePreprocessor } from './route-preprocessor.js';
|
|
2
|
+
/**
|
|
3
|
+
* Unix domain socket server that receives relayed connections from the Rust proxy.
|
|
4
|
+
*
|
|
5
|
+
* When Rust encounters a route of type `socket-handler`, it connects to this
|
|
6
|
+
* Unix socket, sends a JSON metadata line, then proxies the raw TCP bytes.
|
|
7
|
+
* This server reads the metadata, finds the original JS handler, builds an
|
|
8
|
+
* IRouteContext, and hands the socket to the handler.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SocketHandlerServer {
|
|
11
|
+
private server;
|
|
12
|
+
private socketPath;
|
|
13
|
+
private preprocessor;
|
|
14
|
+
private activeSockets;
|
|
15
|
+
constructor(preprocessor: RoutePreprocessor);
|
|
16
|
+
/**
|
|
17
|
+
* The Unix socket path this server listens on.
|
|
18
|
+
*/
|
|
19
|
+
getSocketPath(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Start listening for relayed connections from Rust.
|
|
22
|
+
*/
|
|
23
|
+
start(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Stop the server and clean up.
|
|
26
|
+
*/
|
|
27
|
+
stop(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Handle an incoming relayed connection from Rust.
|
|
30
|
+
*
|
|
31
|
+
* Protocol: Rust sends a single JSON line with metadata, then raw bytes follow.
|
|
32
|
+
* JSON format: { "routeKey": "my-route", "remoteIP": "1.2.3.4", "remotePort": 12345,
|
|
33
|
+
* "localPort": 443, "isTLS": true, "domain": "example.com" }
|
|
34
|
+
*/
|
|
35
|
+
private handleConnection;
|
|
36
|
+
/**
|
|
37
|
+
* Dispatch a relayed connection to the appropriate JS handler.
|
|
38
|
+
*/
|
|
39
|
+
private dispatchToHandler;
|
|
40
|
+
/**
|
|
41
|
+
* Forward a connection to a dynamically resolved target.
|
|
42
|
+
* Used for routes with function-based host/port that Rust cannot handle.
|
|
43
|
+
*/
|
|
44
|
+
private forwardDynamicRoute;
|
|
45
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import { logger } from '../../core/utils/logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* Unix domain socket server that receives relayed connections from the Rust proxy.
|
|
5
|
+
*
|
|
6
|
+
* When Rust encounters a route of type `socket-handler`, it connects to this
|
|
7
|
+
* Unix socket, sends a JSON metadata line, then proxies the raw TCP bytes.
|
|
8
|
+
* This server reads the metadata, finds the original JS handler, builds an
|
|
9
|
+
* IRouteContext, and hands the socket to the handler.
|
|
10
|
+
*/
|
|
11
|
+
export class SocketHandlerServer {
|
|
12
|
+
constructor(preprocessor) {
|
|
13
|
+
this.server = null;
|
|
14
|
+
this.activeSockets = new Set();
|
|
15
|
+
this.preprocessor = preprocessor;
|
|
16
|
+
this.socketPath = `/tmp/smartproxy-relay-${process.pid}.sock`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The Unix socket path this server listens on.
|
|
20
|
+
*/
|
|
21
|
+
getSocketPath() {
|
|
22
|
+
return this.socketPath;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Start listening for relayed connections from Rust.
|
|
26
|
+
*/
|
|
27
|
+
async start() {
|
|
28
|
+
// Clean up stale socket file
|
|
29
|
+
try {
|
|
30
|
+
await plugins.fs.promises.unlink(this.socketPath);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Ignore if doesn't exist
|
|
34
|
+
}
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
this.server = plugins.net.createServer((socket) => {
|
|
37
|
+
this.activeSockets.add(socket);
|
|
38
|
+
socket.on('close', () => this.activeSockets.delete(socket));
|
|
39
|
+
this.handleConnection(socket);
|
|
40
|
+
});
|
|
41
|
+
this.server.on('error', (err) => {
|
|
42
|
+
logger.log('error', `SocketHandlerServer error: ${err.message}`, { component: 'socket-handler-server' });
|
|
43
|
+
});
|
|
44
|
+
this.server.listen(this.socketPath, () => {
|
|
45
|
+
logger.log('info', `SocketHandlerServer listening on ${this.socketPath}`, { component: 'socket-handler-server' });
|
|
46
|
+
resolve();
|
|
47
|
+
});
|
|
48
|
+
this.server.on('error', reject);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Stop the server and clean up.
|
|
53
|
+
*/
|
|
54
|
+
async stop() {
|
|
55
|
+
// Destroy all active connections first
|
|
56
|
+
for (const socket of this.activeSockets) {
|
|
57
|
+
socket.destroy();
|
|
58
|
+
}
|
|
59
|
+
this.activeSockets.clear();
|
|
60
|
+
if (this.server) {
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
this.server.close(() => {
|
|
63
|
+
this.server = null;
|
|
64
|
+
// Clean up socket file
|
|
65
|
+
plugins.fs.unlink(this.socketPath, () => resolve());
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Handle an incoming relayed connection from Rust.
|
|
72
|
+
*
|
|
73
|
+
* Protocol: Rust sends a single JSON line with metadata, then raw bytes follow.
|
|
74
|
+
* JSON format: { "routeKey": "my-route", "remoteIP": "1.2.3.4", "remotePort": 12345,
|
|
75
|
+
* "localPort": 443, "isTLS": true, "domain": "example.com" }
|
|
76
|
+
*/
|
|
77
|
+
handleConnection(socket) {
|
|
78
|
+
let metadataBuffer = '';
|
|
79
|
+
let metadataParsed = false;
|
|
80
|
+
const onData = (chunk) => {
|
|
81
|
+
if (metadataParsed)
|
|
82
|
+
return;
|
|
83
|
+
metadataBuffer += chunk.toString('utf8');
|
|
84
|
+
const newlineIndex = metadataBuffer.indexOf('\n');
|
|
85
|
+
if (newlineIndex === -1) {
|
|
86
|
+
// Haven't received full metadata line yet
|
|
87
|
+
if (metadataBuffer.length > 8192) {
|
|
88
|
+
logger.log('error', 'Socket handler metadata too large, closing', { component: 'socket-handler-server' });
|
|
89
|
+
socket.destroy();
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
metadataParsed = true;
|
|
94
|
+
socket.removeListener('data', onData);
|
|
95
|
+
socket.pause(); // Prevent data loss between handler removal and pipe setup
|
|
96
|
+
const metadataJson = metadataBuffer.slice(0, newlineIndex);
|
|
97
|
+
const remainingData = metadataBuffer.slice(newlineIndex + 1);
|
|
98
|
+
let metadata;
|
|
99
|
+
try {
|
|
100
|
+
metadata = JSON.parse(metadataJson);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
logger.log('error', `Invalid socket handler metadata JSON: ${metadataJson.slice(0, 200)}`, { component: 'socket-handler-server' });
|
|
104
|
+
socket.destroy();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.dispatchToHandler(socket, metadata, remainingData);
|
|
108
|
+
};
|
|
109
|
+
socket.on('data', onData);
|
|
110
|
+
socket.on('error', (err) => {
|
|
111
|
+
logger.log('error', `Socket handler relay error: ${err.message}`, { component: 'socket-handler-server' });
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Dispatch a relayed connection to the appropriate JS handler.
|
|
116
|
+
*/
|
|
117
|
+
dispatchToHandler(socket, metadata, remainingData) {
|
|
118
|
+
const routeKey = metadata.routeKey;
|
|
119
|
+
if (!routeKey) {
|
|
120
|
+
logger.log('error', 'Socket handler relay missing routeKey', { component: 'socket-handler-server' });
|
|
121
|
+
socket.destroy();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const originalRoute = this.preprocessor.getOriginalRoute(routeKey);
|
|
125
|
+
if (!originalRoute) {
|
|
126
|
+
logger.log('error', `No handler found for route: ${routeKey}`, { component: 'socket-handler-server' });
|
|
127
|
+
socket.destroy();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// Build route context
|
|
131
|
+
const context = {
|
|
132
|
+
port: metadata.localPort || 0,
|
|
133
|
+
domain: metadata.domain,
|
|
134
|
+
clientIp: metadata.remoteIP || 'unknown',
|
|
135
|
+
serverIp: '0.0.0.0',
|
|
136
|
+
path: metadata.path,
|
|
137
|
+
isTls: metadata.isTLS || false,
|
|
138
|
+
tlsVersion: metadata.tlsVersion,
|
|
139
|
+
routeName: originalRoute.name,
|
|
140
|
+
routeId: originalRoute.id,
|
|
141
|
+
timestamp: Date.now(),
|
|
142
|
+
connectionId: metadata.connectionId || `relay-${Date.now()}`,
|
|
143
|
+
};
|
|
144
|
+
// If there was remaining data after the metadata line, push it back
|
|
145
|
+
if (remainingData.length > 0) {
|
|
146
|
+
socket.unshift(Buffer.from(remainingData, 'utf8'));
|
|
147
|
+
}
|
|
148
|
+
const handler = originalRoute.action.socketHandler;
|
|
149
|
+
if (handler) {
|
|
150
|
+
// Route has an explicit socket handler callback
|
|
151
|
+
try {
|
|
152
|
+
const result = handler(socket, context);
|
|
153
|
+
// If the handler is async, wait for it to finish setup before resuming.
|
|
154
|
+
// This prevents data loss when async handlers need to do work before
|
|
155
|
+
// attaching their `data` listeners.
|
|
156
|
+
if (result && typeof result.then === 'function') {
|
|
157
|
+
result.then(() => {
|
|
158
|
+
socket.resume();
|
|
159
|
+
}).catch((err) => {
|
|
160
|
+
logger.log('error', `Async socket handler rejected for route ${routeKey}: ${err.message}`, { component: 'socket-handler-server' });
|
|
161
|
+
socket.destroy();
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Synchronous handler — listeners are already attached, safe to resume.
|
|
166
|
+
socket.resume();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
logger.log('error', `Socket handler threw for route ${routeKey}: ${err.message}`, { component: 'socket-handler-server' });
|
|
171
|
+
socket.destroy();
|
|
172
|
+
}
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
// Route has dynamic host/port functions - resolve and forward
|
|
176
|
+
if (originalRoute.action.targets && originalRoute.action.targets.length > 0) {
|
|
177
|
+
this.forwardDynamicRoute(socket, originalRoute, context);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
logger.log('error', `Route ${routeKey} has no socketHandler and no targets`, { component: 'socket-handler-server' });
|
|
181
|
+
socket.destroy();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Forward a connection to a dynamically resolved target.
|
|
185
|
+
* Used for routes with function-based host/port that Rust cannot handle.
|
|
186
|
+
*/
|
|
187
|
+
forwardDynamicRoute(socket, route, context) {
|
|
188
|
+
const targets = route.action.targets;
|
|
189
|
+
// Pick a target (round-robin would be ideal, but simple random for now)
|
|
190
|
+
const target = targets[Math.floor(Math.random() * targets.length)];
|
|
191
|
+
// Resolve host
|
|
192
|
+
let host;
|
|
193
|
+
if (typeof target.host === 'function') {
|
|
194
|
+
try {
|
|
195
|
+
const result = target.host(context);
|
|
196
|
+
host = Array.isArray(result) ? result[Math.floor(Math.random() * result.length)] : result;
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
logger.log('error', `Dynamic host function failed: ${err.message}`, { component: 'socket-handler-server' });
|
|
200
|
+
socket.destroy();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else if (typeof target.host === 'string') {
|
|
205
|
+
host = target.host;
|
|
206
|
+
}
|
|
207
|
+
else if (Array.isArray(target.host)) {
|
|
208
|
+
host = target.host[Math.floor(Math.random() * target.host.length)];
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
host = 'localhost';
|
|
212
|
+
}
|
|
213
|
+
// Resolve port
|
|
214
|
+
let port;
|
|
215
|
+
if (typeof target.port === 'function') {
|
|
216
|
+
try {
|
|
217
|
+
port = target.port(context);
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
logger.log('error', `Dynamic port function failed: ${err.message}`, { component: 'socket-handler-server' });
|
|
221
|
+
socket.destroy();
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else if (typeof target.port === 'number') {
|
|
226
|
+
port = target.port;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
port = context.port;
|
|
230
|
+
}
|
|
231
|
+
logger.log('debug', `Dynamic forward: ${context.clientIp} -> ${host}:${port}`, { component: 'socket-handler-server' });
|
|
232
|
+
// Connect to the resolved target
|
|
233
|
+
const backend = plugins.net.connect(port, host, () => {
|
|
234
|
+
// Pipe bidirectionally
|
|
235
|
+
socket.pipe(backend);
|
|
236
|
+
backend.pipe(socket);
|
|
237
|
+
});
|
|
238
|
+
backend.on('error', (err) => {
|
|
239
|
+
logger.log('error', `Dynamic forward backend error: ${err.message}`, { component: 'socket-handler-server' });
|
|
240
|
+
socket.destroy();
|
|
241
|
+
});
|
|
242
|
+
socket.on('error', () => {
|
|
243
|
+
backend.destroy();
|
|
244
|
+
});
|
|
245
|
+
socket.on('close', () => {
|
|
246
|
+
backend.destroy();
|
|
247
|
+
});
|
|
248
|
+
backend.on('close', () => {
|
|
249
|
+
socket.destroy();
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ja2V0LWhhbmRsZXItc2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcHJveGllcy9zbWFydC1wcm94eS9zb2NrZXQtaGFuZGxlci1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFJcEQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sT0FBTyxtQkFBbUI7SUFNOUIsWUFBWSxZQUErQjtRQUxuQyxXQUFNLEdBQThCLElBQUksQ0FBQztRQUd6QyxrQkFBYSxHQUFHLElBQUksR0FBRyxFQUFzQixDQUFDO1FBR3BELElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxVQUFVLEdBQUcseUJBQXlCLE9BQU8sQ0FBQyxHQUFHLE9BQU8sQ0FBQztJQUNoRSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxhQUFhO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsS0FBSztRQUNoQiw2QkFBNkI7UUFDN0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxPQUFPLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCwwQkFBMEI7UUFDNUIsQ0FBQztRQUVELE9BQU8sSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDM0MsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO2dCQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDL0Is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
|
|
@@ -27,15 +27,8 @@ export declare class TlsManager {
|
|
|
27
27
|
*/
|
|
28
28
|
extractSNI(chunk: Buffer, connInfo: IConnectionInfo, previousDomain?: string): string | undefined;
|
|
29
29
|
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
handleSessionResumption(chunk: Buffer, connectionId: string, hasSNI: boolean): {
|
|
33
|
-
shouldBlock: boolean;
|
|
34
|
-
reason?: string;
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Check for SNI mismatch during renegotiation
|
|
38
|
-
*/
|
|
30
|
+
* Check for SNI mismatch during renegotiation
|
|
31
|
+
*/
|
|
39
32
|
checkRenegotiationSNI(chunk: Buffer, connInfo: IConnectionInfo, expectedDomain: string, connectionId: string): {
|
|
40
33
|
hasMismatch: boolean;
|
|
41
34
|
extractedSNI?: string;
|
|
@@ -28,31 +28,8 @@ export class TlsManager {
|
|
|
28
28
|
return SniHandler.processTlsPacket(chunk, connInfo, this.smartProxy.settings.enableTlsDebugLogging || false, previousDomain);
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
handleSessionResumption(chunk, connectionId, hasSNI) {
|
|
34
|
-
// Skip if session tickets are allowed
|
|
35
|
-
if (this.smartProxy.settings.allowSessionTicket !== false) {
|
|
36
|
-
return { shouldBlock: false };
|
|
37
|
-
}
|
|
38
|
-
// Check for session resumption attempt
|
|
39
|
-
const resumptionInfo = SniHandler.hasSessionResumption(chunk, this.smartProxy.settings.enableTlsDebugLogging || false);
|
|
40
|
-
// If this is a resumption attempt without SNI, block it
|
|
41
|
-
if (resumptionInfo.isResumption && !hasSNI && !resumptionInfo.hasSNI) {
|
|
42
|
-
if (this.smartProxy.settings.enableTlsDebugLogging) {
|
|
43
|
-
console.log(`[${connectionId}] Session resumption detected without SNI and allowSessionTicket=false. ` +
|
|
44
|
-
`Terminating connection to force new TLS handshake.`);
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
shouldBlock: true,
|
|
48
|
-
reason: 'session_ticket_blocked'
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
return { shouldBlock: false };
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Check for SNI mismatch during renegotiation
|
|
55
|
-
*/
|
|
31
|
+
* Check for SNI mismatch during renegotiation
|
|
32
|
+
*/
|
|
56
33
|
checkRenegotiationSNI(chunk, connInfo, expectedDomain, connectionId) {
|
|
57
34
|
// Only process if this looks like a TLS ClientHello
|
|
58
35
|
if (!this.isClientHello(chunk)) {
|
|
@@ -130,4 +107,4 @@ export class TlsManager {
|
|
|
130
107
|
}
|
|
131
108
|
}
|
|
132
109
|
}
|
|
133
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGxzLW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9wcm94aWVzL3NtYXJ0LXByb3h5L3Rscy1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzFELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQWF6RTs7R0FFRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBQ3JCLFlBQW9CLFVBQXNCO1FBQXRCLGVBQVUsR0FBVixVQUFVLENBQVk7SUFBRyxDQUFDO0lBRTlDOztPQUVHO0lBQ0ksY0FBYyxDQUFDLEtBQWE7UUFDakMsT0FBTyxVQUFVLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7T0FFRztJQUNJLGFBQWEsQ0FBQyxLQUFhO1FBQ2hDLE9BQU8sVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxVQUFVLENBQ2YsS0FBYSxFQUNiLFFBQXlCLEVBQ3pCLGNBQXVCO1FBRXZCLCtDQUErQztRQUMvQyxPQUFPLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FDaEMsS0FBSyxFQUNMLFFBQVEsRUFDUixJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsSUFBSSxLQUFLLEVBQ3ZELGNBQWMsQ0FDZixDQUFDO0lBQ0osQ0FBQztJQUVIOztTQUVLO0lBQ0kscUJBQXFCLENBQzFCLEtBQWEsRUFDYixRQUF5QixFQUN6QixjQUFzQixFQUN0QixZQUFvQjtRQUVwQixvREFBb0Q7UUFDcEQsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvQixPQUFPLEVBQUUsV0FBVyxFQUFFLEtB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
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* including helpers, validators, utilities, and patterns for working with routes.
|
|
6
6
|
*/
|
|
7
7
|
export * from './route-helpers.js';
|
|
8
|
-
export * from './route-
|
|
8
|
+
export * from './route-validator.js';
|
|
9
9
|
export * from './route-utils.js';
|
|
10
10
|
export { createApiGatewayRoute, addRateLimiting, addBasicAuth, addJwtAuth } from './route-helpers.js';
|
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
// Export route helpers for creating route configurations
|
|
8
8
|
export * from './route-helpers.js';
|
|
9
|
-
// Export route
|
|
10
|
-
export * from './route-
|
|
9
|
+
// Export route validator (class-based and functional API)
|
|
10
|
+
export * from './route-validator.js';
|
|
11
11
|
// Export route utilities for route operations
|
|
12
12
|
export * from './route-utils.js';
|
|
13
13
|
// Export additional functions from route-helpers that weren't already exported
|
|
14
14
|
export { createApiGatewayRoute, addRateLimiting, addBasicAuth, addJwtAuth } from './route-helpers.js';
|
|
15
|
-
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9wcm94aWVzL3NtYXJ0LXByb3h5L3V0aWxzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBRUgseURBQXlEO0FBQ3pELGNBQWMsb0JBQW9CLENBQUM7QUFFbkMsOERBQThEO0FBQzlELGNBQWMsdUJBQXVCLENBQUM7QUFFdEMsOENBQThDO0FBQzlDLGNBQWMsa0JBQWtCLENBQUM7QUFFakMsK0VBQStFO0FBQy9FLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsZUFBZSxFQUNmLFlBQVksRUFDWixVQUFVLEVBQ1gsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QixxRUFBcUUifQ==
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9wcm94aWVzL3NtYXJ0LXByb3h5L3V0aWxzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBRUgseURBQXlEO0FBQ3pELGNBQWMsb0JBQW9CLENBQUM7QUFFbkMsMERBQTBEO0FBQzFELGNBQWMsc0JBQXNCLENBQUM7QUFFckMsOENBQThDO0FBQzlDLGNBQWMsa0JBQWtCLENBQUM7QUFFakMsK0VBQStFO0FBQy9FLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsZUFBZSxFQUNmLFlBQVksRUFDWixVQUFVLEVBQ1gsTUFBTSxvQkFBb0IsQ0FBQyJ9
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Route Helper Functions
|
|
3
|
+
*
|
|
4
|
+
* This module provides utility functions for creating API route configurations.
|
|
5
|
+
*/
|
|
6
|
+
import type { IRouteConfig } from '../../models/route-types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Create an API route configuration
|
|
9
|
+
* @param domains Domain(s) to match
|
|
10
|
+
* @param apiPath API base path (e.g., "/api")
|
|
11
|
+
* @param target Target host and port
|
|
12
|
+
* @param options Additional route options
|
|
13
|
+
* @returns Route configuration object
|
|
14
|
+
*/
|
|
15
|
+
export declare function createApiRoute(domains: string | string[], apiPath: string, target: {
|
|
16
|
+
host: string | string[];
|
|
17
|
+
port: number;
|
|
18
|
+
}, options?: {
|
|
19
|
+
useTls?: boolean;
|
|
20
|
+
certificate?: 'auto' | {
|
|
21
|
+
key: string;
|
|
22
|
+
cert: string;
|
|
23
|
+
};
|
|
24
|
+
addCorsHeaders?: boolean;
|
|
25
|
+
httpPort?: number | number[];
|
|
26
|
+
httpsPort?: number | number[];
|
|
27
|
+
name?: string;
|
|
28
|
+
[key: string]: any;
|
|
29
|
+
}): IRouteConfig;
|
|
30
|
+
/**
|
|
31
|
+
* Create an API Gateway route pattern
|
|
32
|
+
* @param domains Domain(s) to match
|
|
33
|
+
* @param apiBasePath Base path for API endpoints (e.g., '/api')
|
|
34
|
+
* @param target Target host and port
|
|
35
|
+
* @param options Additional route options
|
|
36
|
+
* @returns API route configuration
|
|
37
|
+
*/
|
|
38
|
+
export declare function createApiGatewayRoute(domains: string | string[], apiBasePath: string, target: {
|
|
39
|
+
host: string | string[];
|
|
40
|
+
port: number;
|
|
41
|
+
}, options?: {
|
|
42
|
+
useTls?: boolean;
|
|
43
|
+
certificate?: 'auto' | {
|
|
44
|
+
key: string;
|
|
45
|
+
cert: string;
|
|
46
|
+
};
|
|
47
|
+
addCorsHeaders?: boolean;
|
|
48
|
+
[key: string]: any;
|
|
49
|
+
}): IRouteConfig;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Route Helper Functions
|
|
3
|
+
*
|
|
4
|
+
* This module provides utility functions for creating API route configurations.
|
|
5
|
+
*/
|
|
6
|
+
import { mergeRouteConfigs } from '../route-utils.js';
|
|
7
|
+
import { createHttpRoute } from './http-helpers.js';
|
|
8
|
+
import { createHttpsTerminateRoute } from './https-helpers.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create an API route configuration
|
|
11
|
+
* @param domains Domain(s) to match
|
|
12
|
+
* @param apiPath API base path (e.g., "/api")
|
|
13
|
+
* @param target Target host and port
|
|
14
|
+
* @param options Additional route options
|
|
15
|
+
* @returns Route configuration object
|
|
16
|
+
*/
|
|
17
|
+
export function createApiRoute(domains, apiPath, target, options = {}) {
|
|
18
|
+
// Normalize API path
|
|
19
|
+
const normalizedPath = apiPath.startsWith('/') ? apiPath : `/${apiPath}`;
|
|
20
|
+
const pathWithWildcard = normalizedPath.endsWith('/')
|
|
21
|
+
? `${normalizedPath}*`
|
|
22
|
+
: `${normalizedPath}/*`;
|
|
23
|
+
// Create route match
|
|
24
|
+
const match = {
|
|
25
|
+
ports: options.useTls
|
|
26
|
+
? (options.httpsPort || 443)
|
|
27
|
+
: (options.httpPort || 80),
|
|
28
|
+
domains,
|
|
29
|
+
path: pathWithWildcard
|
|
30
|
+
};
|
|
31
|
+
// Create route action
|
|
32
|
+
const action = {
|
|
33
|
+
type: 'forward',
|
|
34
|
+
targets: [target]
|
|
35
|
+
};
|
|
36
|
+
// Add TLS configuration if using HTTPS
|
|
37
|
+
if (options.useTls) {
|
|
38
|
+
action.tls = {
|
|
39
|
+
mode: 'terminate',
|
|
40
|
+
certificate: options.certificate || 'auto'
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Add CORS headers if requested
|
|
44
|
+
const headers = {};
|
|
45
|
+
if (options.addCorsHeaders) {
|
|
46
|
+
headers.response = {
|
|
47
|
+
'Access-Control-Allow-Origin': '*',
|
|
48
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
49
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
50
|
+
'Access-Control-Max-Age': '86400'
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Create the route config
|
|
54
|
+
return {
|
|
55
|
+
match,
|
|
56
|
+
action,
|
|
57
|
+
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
58
|
+
name: options.name || `API Route ${normalizedPath} for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
|
|
59
|
+
priority: options.priority || 100, // Higher priority for specific path matches
|
|
60
|
+
...options
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create an API Gateway route pattern
|
|
65
|
+
* @param domains Domain(s) to match
|
|
66
|
+
* @param apiBasePath Base path for API endpoints (e.g., '/api')
|
|
67
|
+
* @param target Target host and port
|
|
68
|
+
* @param options Additional route options
|
|
69
|
+
* @returns API route configuration
|
|
70
|
+
*/
|
|
71
|
+
export function createApiGatewayRoute(domains, apiBasePath, target, options = {}) {
|
|
72
|
+
// Normalize apiBasePath to ensure it starts with / and doesn't end with /
|
|
73
|
+
const normalizedPath = apiBasePath.startsWith('/')
|
|
74
|
+
? apiBasePath
|
|
75
|
+
: `/${apiBasePath}`;
|
|
76
|
+
// Add wildcard to path to match all API endpoints
|
|
77
|
+
const apiPath = normalizedPath.endsWith('/')
|
|
78
|
+
? `${normalizedPath}*`
|
|
79
|
+
: `${normalizedPath}/*`;
|
|
80
|
+
// Create base route
|
|
81
|
+
const baseRoute = options.useTls
|
|
82
|
+
? createHttpsTerminateRoute(domains, target, {
|
|
83
|
+
certificate: options.certificate || 'auto'
|
|
84
|
+
})
|
|
85
|
+
: createHttpRoute(domains, target);
|
|
86
|
+
// Add API-specific configurations
|
|
87
|
+
const apiRoute = {
|
|
88
|
+
match: {
|
|
89
|
+
...baseRoute.match,
|
|
90
|
+
path: apiPath
|
|
91
|
+
},
|
|
92
|
+
name: options.name || `API Gateway: ${apiPath} -> ${Array.isArray(target.host) ? target.host.join(', ') : target.host}:${target.port}`,
|
|
93
|
+
priority: options.priority || 100 // Higher priority for specific path matching
|
|
94
|
+
};
|
|
95
|
+
// Add CORS headers if requested
|
|
96
|
+
if (options.addCorsHeaders) {
|
|
97
|
+
apiRoute.headers = {
|
|
98
|
+
response: {
|
|
99
|
+
'Access-Control-Allow-Origin': '*',
|
|
100
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
101
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
102
|
+
'Access-Control-Max-Age': '86400'
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return mergeRouteConfigs(baseRoute, apiRoute);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90cy9wcm94aWVzL3NtYXJ0LXByb3h5L3V0aWxzL3JvdXRlLWhlbHBlcnMvYXBpLWhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUdILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUvRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsT0FBMEIsRUFDMUIsT0FBZSxFQUNmLE1BQWlELEVBQ2pELFVBUUksRUFBRTtJQUVOLHFCQUFxQjtJQUNyQixNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUM7SUFDekUsTUFBTSxnQkFBZ0IsR0FBRyxjQUFjLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztRQUNuRCxDQUFDLENBQUMsR0FBRyxjQUFjLEdBQUc7UUFDdEIsQ0FBQyxDQUFDLEdBQUcsY0FBYyxJQUFJLENBQUM7SUFFMUIscUJBQXFCO0lBQ3JCLE1BQU0sS0FBSyxHQUFnQjtRQUN6QixLQUFLLEVBQUUsT0FBTyxDQUFDLE1BQU07WUFDbkIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsSUFBSSxHQUFHLENBQUM7WUFDNUIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7UUFDNUIsT0FBTztRQUNQLElBQUksRUFBRSxnQkFBZ0I7S0FDdkIsQ0FBQztJQUVGLHNCQUFzQjtJQUN0QixNQUFNLE1BQU0sR0FBaUI7UUFDM0IsSUFBSSxFQUFFLFNBQVM7UUFDZixPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUM7S0FDbEIsQ0FBQztJQUVGLHVDQUF1QztJQUN2QyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNuQixNQUFNLENBQUMsR0FBRyxHQUFHO1lBQ1gsSUFBSSxFQUFFLFdBQVc7WUFDakIsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXLElBQUksTUFBTTtTQUMzQyxDQUFDO0lBQ0osQ0FBQztJQUVELGdDQUFnQztJQUNoQyxNQUFNLE9BQU8sR0FBMkMsRUFBRSxDQUFDO0lBQzNELElBQUksT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzNCLE9BQU8sQ0FBQyxRQUFRLEdBQUc7WUFDakIsNkJBQTZCLEVBQUUsR0FBRztZQUNsQyw4QkFBOEIsRUFBRSxpQ0FBaUM7WUFDakUsOEJBQThCLEVBQUUsNkJBQTZCO1lBQzdELHdCQUF3QixFQUFFLE9BQU87U0FDbEMsQ0FBQztJQUNKLENBQUM7SUFFRCwwQkFBMEI7SUFDMUIsT0FBTztRQUNMLEtBQUs7UUFDTCxNQUFNO1FBQ04sT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQzlELElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLGFBQWEsY0FBYyxRQUFRLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRTtRQUNoSCxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVEsSUFBSSxHQUFHLEVBQUUsNENBQTRDO1FBQy9FLEdBQUcsT0FBTztLQUNYLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsT0FBMEIsRUFDMUIsV0FBbUIsRUFDbkIsTUFBaUQsRUFDakQsVUFLSSxFQUFFO0lBRU4sMEVBQTBFO0lBQzFFLE1BQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO1FBQ2hELENBQUMsQ0FBQyxXQUFXO1FBQ2IsQ0FBQyxDQUFDLElBQUksV0FBVyxFQUFFLENBQUM7SUFFdEIsa0RBQWtEO0lBQ2xELE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxHQUFHLGNBQWMsR0FBRztRQUN0QixDQUFDLENBQUMsR0FBRyxjQUFjLElBQUksQ0FBQztJQUUxQixvQkFBb0I7SUFDcEIsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLE1BQU07UUFDOUIsQ0FBQyxDQUFDLHlCQUF5QixDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7WUFDekMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXLElBQUksTUFBTTtTQUMzQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFckMsa0NBQWtDO0lBQ2xDLE1BQU0sUUFBUSxHQUEwQjtRQUN0QyxLQUFLLEVBQUU7WUFDTCxHQUFHLFNBQVMsQ0FBQyxLQUFLO1lBQ2xCLElBQUksRUFBRSxPQUFPO1NBQ2Q7UUFDRCxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxnQkFBZ0IsT0FBTyxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFO1FBQ3RJLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUSxJQUFJLEdBQUcsQ0FBQyw2Q0FBNkM7S0FDaEYsQ0FBQztJQUVGLGdDQUFnQztJQUNoQyxJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUMzQixRQUFRLENBQUMsT0FBTyxHQUFHO1lBQ2pCLFFBQVEsRUFBRTtnQkFDUiw2QkFBNkIsRUFBRSxHQUFHO2dCQUNsQyw4QkFBOEIsRUFBRSxpQ0FBaUM7Z0JBQ2pFLDhCQUE4QixFQUFFLDZCQUE2QjtnQkFDN0Qsd0JBQXdCLEVBQUUsT0FBTzthQUNsQztTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDaEQsQ0FBQyJ9
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Route Helper Functions
|
|
3
|
+
*
|
|
4
|
+
* This module provides utility functions for creating dynamic routes
|
|
5
|
+
* with context-based host and port mapping.
|
|
6
|
+
*/
|
|
7
|
+
import type { IRouteConfig, TPortRange, IRouteContext } from '../../models/route-types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create a helper function that applies a port offset
|
|
10
|
+
* @param offset The offset to apply to the matched port
|
|
11
|
+
* @returns A function that adds the offset to the matched port
|
|
12
|
+
*/
|
|
13
|
+
export declare function createPortOffset(offset: number): (context: IRouteContext) => number;
|
|
14
|
+
/**
|
|
15
|
+
* Create a port mapping route with context-based port function
|
|
16
|
+
* @param options Port mapping route options
|
|
17
|
+
* @returns Route configuration object
|
|
18
|
+
*/
|
|
19
|
+
export declare function createPortMappingRoute(options: {
|
|
20
|
+
sourcePortRange: TPortRange;
|
|
21
|
+
targetHost: string | string[] | ((context: IRouteContext) => string | string[]);
|
|
22
|
+
portMapper: (context: IRouteContext) => number;
|
|
23
|
+
name?: string;
|
|
24
|
+
domains?: string | string[];
|
|
25
|
+
priority?: number;
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}): IRouteConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Create a simple offset port mapping route
|
|
30
|
+
* @param options Offset port mapping route options
|
|
31
|
+
* @returns Route configuration object
|
|
32
|
+
*/
|
|
33
|
+
export declare function createOffsetPortMappingRoute(options: {
|
|
34
|
+
ports: TPortRange;
|
|
35
|
+
targetHost: string | string[];
|
|
36
|
+
offset: number;
|
|
37
|
+
name?: string;
|
|
38
|
+
domains?: string | string[];
|
|
39
|
+
priority?: number;
|
|
40
|
+
[key: string]: any;
|
|
41
|
+
}): IRouteConfig;
|
|
42
|
+
/**
|
|
43
|
+
* Create a dynamic route with context-based host and port mapping
|
|
44
|
+
* @param options Dynamic route options
|
|
45
|
+
* @returns Route configuration object
|
|
46
|
+
*/
|
|
47
|
+
export declare function createDynamicRoute(options: {
|
|
48
|
+
ports: TPortRange;
|
|
49
|
+
targetHost: (context: IRouteContext) => string | string[];
|
|
50
|
+
portMapper: (context: IRouteContext) => number;
|
|
51
|
+
name?: string;
|
|
52
|
+
domains?: string | string[];
|
|
53
|
+
path?: string;
|
|
54
|
+
clientIp?: string[];
|
|
55
|
+
priority?: number;
|
|
56
|
+
[key: string]: any;
|
|
57
|
+
}): IRouteConfig;
|