@push.rocks/smartproxy 26.3.0 → 27.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/changelog.md +7 -0
- package/dist_rust/rustproxy_linux_amd64 +0 -0
- package/dist_rust/rustproxy_linux_arm64 +0 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/core/models/wrapped-socket.js +4 -1
- package/dist_ts/core/routing/route-manager.js +9 -7
- package/dist_ts/proxies/smart-proxy/datagram-handler-server.js +7 -5
- package/dist_ts/proxies/smart-proxy/route-preprocessor.js +6 -8
- package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.js +186 -184
- package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +2 -1
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +12 -6
- package/dist_ts/proxies/smart-proxy/socket-handler-server.js +5 -3
- package/dist_ts/proxies/smart-proxy/utils/concurrency-semaphore.js +4 -3
- package/dist_ts/proxies/smart-proxy/utils/index.d.ts +2 -3
- package/dist_ts/proxies/smart-proxy/utils/index.js +4 -6
- package/dist_ts/proxies/smart-proxy/utils/mutex.js +3 -5
- package/dist_ts/proxies/smart-proxy/utils/route-validator.js +7 -7
- package/dist_ts/proxies/smart-proxy/utils/{route-helpers/socket-handlers.d.ts → socket-handlers.d.ts} +2 -10
- package/dist_ts/proxies/smart-proxy/utils/socket-handlers.js +268 -0
- package/dist_ts/routing/models/http-types.js +5 -1
- package/package.json +1 -1
- package/readme.hints.md +42 -20
- package/readme.md +144 -146
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/proxies/smart-proxy/utils/index.ts +3 -11
- package/ts/proxies/smart-proxy/utils/{route-helpers/socket-handlers.ts → socket-handlers.ts} +3 -31
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/api-helpers.d.ts +0 -49
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/api-helpers.js +0 -108
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.d.ts +0 -57
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.js +0 -90
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/http-helpers.d.ts +0 -17
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/http-helpers.js +0 -32
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/https-helpers.d.ts +0 -68
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/https-helpers.js +0 -117
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/index.d.ts +0 -17
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/index.js +0 -27
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.d.ts +0 -63
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.js +0 -105
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.d.ts +0 -83
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.js +0 -126
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/security-helpers.d.ts +0 -47
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/security-helpers.js +0 -66
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.js +0 -286
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.d.ts +0 -46
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.js +0 -67
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +0 -9
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +0 -11
- package/ts/proxies/smart-proxy/utils/route-helpers/api-helpers.ts +0 -144
- package/ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.ts +0 -125
- package/ts/proxies/smart-proxy/utils/route-helpers/http-helpers.ts +0 -40
- package/ts/proxies/smart-proxy/utils/route-helpers/https-helpers.ts +0 -163
- package/ts/proxies/smart-proxy/utils/route-helpers/index.ts +0 -62
- package/ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.ts +0 -154
- package/ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.ts +0 -202
- package/ts/proxies/smart-proxy/utils/route-helpers/security-helpers.ts +0 -96
- package/ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.ts +0 -98
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +0 -11
package/readme.md
CHANGED
|
@@ -44,7 +44,7 @@ Whether you're building microservices, deploying edge infrastructure, proxying U
|
|
|
44
44
|
Get up and running in 30 seconds:
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
|
-
import { SmartProxy,
|
|
47
|
+
import { SmartProxy, SocketHandlers } from '@push.rocks/smartproxy';
|
|
48
48
|
|
|
49
49
|
// Create a proxy with automatic HTTPS
|
|
50
50
|
const proxy = new SmartProxy({
|
|
@@ -53,13 +53,25 @@ const proxy = new SmartProxy({
|
|
|
53
53
|
useProduction: true
|
|
54
54
|
},
|
|
55
55
|
routes: [
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
// HTTPS route with automatic Let's Encrypt cert
|
|
57
|
+
{
|
|
58
|
+
name: 'https-app',
|
|
59
|
+
match: { ports: 443, domains: 'app.example.com' },
|
|
60
|
+
action: {
|
|
61
|
+
type: 'forward',
|
|
62
|
+
targets: [{ host: 'localhost', port: 3000 }],
|
|
63
|
+
tls: { mode: 'terminate', certificate: 'auto' }
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
// HTTP → HTTPS redirect
|
|
67
|
+
{
|
|
68
|
+
name: 'http-redirect',
|
|
69
|
+
match: { ports: 80, domains: 'app.example.com' },
|
|
70
|
+
action: {
|
|
71
|
+
type: 'socket-handler',
|
|
72
|
+
socketHandler: SocketHandlers.httpRedirect('https://{domain}:443{path}', 301)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
63
75
|
]
|
|
64
76
|
});
|
|
65
77
|
|
|
@@ -111,31 +123,38 @@ SmartProxy supports three TLS handling modes:
|
|
|
111
123
|
### 🌐 HTTP to HTTPS Redirect
|
|
112
124
|
|
|
113
125
|
```typescript
|
|
114
|
-
import { SmartProxy,
|
|
126
|
+
import { SmartProxy, SocketHandlers } from '@push.rocks/smartproxy';
|
|
115
127
|
|
|
116
128
|
const proxy = new SmartProxy({
|
|
117
|
-
routes: [
|
|
118
|
-
|
|
119
|
-
|
|
129
|
+
routes: [{
|
|
130
|
+
name: 'http-to-https',
|
|
131
|
+
match: { ports: 80, domains: ['example.com', '*.example.com'] },
|
|
132
|
+
action: {
|
|
133
|
+
type: 'socket-handler',
|
|
134
|
+
socketHandler: SocketHandlers.httpRedirect('https://{domain}:443{path}', 301)
|
|
135
|
+
}
|
|
136
|
+
}]
|
|
120
137
|
});
|
|
121
138
|
```
|
|
122
139
|
|
|
123
140
|
### ⚖️ Load Balancer with Health Checks
|
|
124
141
|
|
|
125
142
|
```typescript
|
|
126
|
-
import { SmartProxy
|
|
143
|
+
import { SmartProxy } from '@push.rocks/smartproxy';
|
|
127
144
|
|
|
128
145
|
const proxy = new SmartProxy({
|
|
129
|
-
routes: [
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
146
|
+
routes: [{
|
|
147
|
+
name: 'load-balancer',
|
|
148
|
+
match: { ports: 443, domains: 'app.example.com' },
|
|
149
|
+
action: {
|
|
150
|
+
type: 'forward',
|
|
151
|
+
targets: [
|
|
133
152
|
{ host: 'server1.internal', port: 8080 },
|
|
134
153
|
{ host: 'server2.internal', port: 8080 },
|
|
135
154
|
{ host: 'server3.internal', port: 8080 }
|
|
136
155
|
],
|
|
137
|
-
{
|
|
138
|
-
|
|
156
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
157
|
+
loadBalancing: {
|
|
139
158
|
algorithm: 'round-robin',
|
|
140
159
|
healthCheck: {
|
|
141
160
|
path: '/health',
|
|
@@ -145,57 +164,68 @@ const proxy = new SmartProxy({
|
|
|
145
164
|
healthyThreshold: 2
|
|
146
165
|
}
|
|
147
166
|
}
|
|
148
|
-
|
|
149
|
-
]
|
|
167
|
+
}
|
|
168
|
+
}]
|
|
150
169
|
});
|
|
151
170
|
```
|
|
152
171
|
|
|
153
172
|
### 🔌 WebSocket Proxy
|
|
154
173
|
|
|
155
174
|
```typescript
|
|
156
|
-
import { SmartProxy
|
|
175
|
+
import { SmartProxy } from '@push.rocks/smartproxy';
|
|
157
176
|
|
|
158
177
|
const proxy = new SmartProxy({
|
|
159
|
-
routes: [
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
178
|
+
routes: [{
|
|
179
|
+
name: 'websocket',
|
|
180
|
+
match: { ports: 443, domains: 'ws.example.com', path: '/socket' },
|
|
181
|
+
priority: 100,
|
|
182
|
+
action: {
|
|
183
|
+
type: 'forward',
|
|
184
|
+
targets: [{ host: 'websocket-server', port: 8080 }],
|
|
185
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
186
|
+
websocket: {
|
|
187
|
+
enabled: true,
|
|
167
188
|
pingInterval: 30000,
|
|
168
189
|
pingTimeout: 10000
|
|
169
190
|
}
|
|
170
|
-
|
|
171
|
-
]
|
|
191
|
+
}
|
|
192
|
+
}]
|
|
172
193
|
});
|
|
173
194
|
```
|
|
174
195
|
|
|
175
196
|
### 🚦 API Gateway with Rate Limiting
|
|
176
197
|
|
|
177
198
|
```typescript
|
|
178
|
-
import { SmartProxy
|
|
179
|
-
|
|
180
|
-
let apiRoute = createApiGatewayRoute(
|
|
181
|
-
'api.example.com',
|
|
182
|
-
'/api',
|
|
183
|
-
{ host: 'api-backend', port: 8080 },
|
|
184
|
-
{
|
|
185
|
-
useTls: true,
|
|
186
|
-
certificate: 'auto',
|
|
187
|
-
addCorsHeaders: true
|
|
188
|
-
}
|
|
189
|
-
);
|
|
199
|
+
import { SmartProxy } from '@push.rocks/smartproxy';
|
|
190
200
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
201
|
+
const proxy = new SmartProxy({
|
|
202
|
+
routes: [{
|
|
203
|
+
name: 'api-gateway',
|
|
204
|
+
match: { ports: 443, domains: 'api.example.com', path: '/api/*' },
|
|
205
|
+
priority: 100,
|
|
206
|
+
action: {
|
|
207
|
+
type: 'forward',
|
|
208
|
+
targets: [{ host: 'api-backend', port: 8080 }],
|
|
209
|
+
tls: { mode: 'terminate', certificate: 'auto' }
|
|
210
|
+
},
|
|
211
|
+
headers: {
|
|
212
|
+
response: {
|
|
213
|
+
'Access-Control-Allow-Origin': '*',
|
|
214
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
215
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
216
|
+
'Access-Control-Max-Age': '86400'
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
security: {
|
|
220
|
+
rateLimit: {
|
|
221
|
+
enabled: true,
|
|
222
|
+
maxRequests: 100,
|
|
223
|
+
window: 60,
|
|
224
|
+
keyBy: 'ip'
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}]
|
|
196
228
|
});
|
|
197
|
-
|
|
198
|
-
const proxy = new SmartProxy({ routes: [apiRoute] });
|
|
199
229
|
```
|
|
200
230
|
|
|
201
231
|
### 🎮 Custom Protocol Handler (TCP)
|
|
@@ -203,36 +233,40 @@ const proxy = new SmartProxy({ routes: [apiRoute] });
|
|
|
203
233
|
SmartProxy lets you implement any protocol with full socket control. Routes with JavaScript socket handlers are automatically relayed from the Rust engine back to your TypeScript code:
|
|
204
234
|
|
|
205
235
|
```typescript
|
|
206
|
-
import { SmartProxy,
|
|
207
|
-
|
|
208
|
-
// Use pre-built handlers
|
|
209
|
-
const echoRoute = createSocketHandlerRoute(
|
|
210
|
-
'echo.example.com',
|
|
211
|
-
7777,
|
|
212
|
-
SocketHandlers.echo
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
// Or create your own custom protocol
|
|
216
|
-
const customRoute = createSocketHandlerRoute(
|
|
217
|
-
'custom.example.com',
|
|
218
|
-
9999,
|
|
219
|
-
async (socket) => {
|
|
220
|
-
console.log(`New connection on custom protocol`);
|
|
221
|
-
socket.write('Welcome to my custom protocol!\n');
|
|
222
|
-
|
|
223
|
-
socket.on('data', (data) => {
|
|
224
|
-
const command = data.toString().trim();
|
|
225
|
-
switch (command) {
|
|
226
|
-
case 'PING': socket.write('PONG\n'); break;
|
|
227
|
-
case 'TIME': socket.write(`${new Date().toISOString()}\n`); break;
|
|
228
|
-
case 'QUIT': socket.end('Goodbye!\n'); break;
|
|
229
|
-
default: socket.write(`Unknown: ${command}\n`);
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
);
|
|
236
|
+
import { SmartProxy, SocketHandlers } from '@push.rocks/smartproxy';
|
|
234
237
|
|
|
235
|
-
const proxy = new SmartProxy({
|
|
238
|
+
const proxy = new SmartProxy({
|
|
239
|
+
routes: [
|
|
240
|
+
// Use pre-built handlers
|
|
241
|
+
{
|
|
242
|
+
name: 'echo-server',
|
|
243
|
+
match: { ports: 7777, domains: 'echo.example.com' },
|
|
244
|
+
action: { type: 'socket-handler', socketHandler: SocketHandlers.echo }
|
|
245
|
+
},
|
|
246
|
+
// Or create your own custom protocol
|
|
247
|
+
{
|
|
248
|
+
name: 'custom-protocol',
|
|
249
|
+
match: { ports: 9999, domains: 'custom.example.com' },
|
|
250
|
+
action: {
|
|
251
|
+
type: 'socket-handler',
|
|
252
|
+
socketHandler: async (socket) => {
|
|
253
|
+
console.log(`New connection on custom protocol`);
|
|
254
|
+
socket.write('Welcome to my custom protocol!\n');
|
|
255
|
+
|
|
256
|
+
socket.on('data', (data) => {
|
|
257
|
+
const command = data.toString().trim();
|
|
258
|
+
switch (command) {
|
|
259
|
+
case 'PING': socket.write('PONG\n'); break;
|
|
260
|
+
case 'TIME': socket.write(`${new Date().toISOString()}\n`); break;
|
|
261
|
+
case 'QUIT': socket.end('Goodbye!\n'); break;
|
|
262
|
+
default: socket.write(`Unknown: ${command}\n`);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
});
|
|
236
270
|
```
|
|
237
271
|
|
|
238
272
|
**Pre-built Socket Handlers:**
|
|
@@ -387,20 +421,23 @@ const dualStackRoute: IRouteConfig = {
|
|
|
387
421
|
For ultra-low latency on Linux, use kernel-level forwarding via [`@push.rocks/smartnftables`](https://code.foss.global/push.rocks/smartnftables) (requires root):
|
|
388
422
|
|
|
389
423
|
```typescript
|
|
390
|
-
import { SmartProxy
|
|
424
|
+
import { SmartProxy } from '@push.rocks/smartproxy';
|
|
391
425
|
|
|
392
426
|
const proxy = new SmartProxy({
|
|
393
|
-
routes: [
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
427
|
+
routes: [{
|
|
428
|
+
name: 'nftables-fast',
|
|
429
|
+
match: { ports: 443, domains: 'fast.example.com' },
|
|
430
|
+
action: {
|
|
431
|
+
type: 'forward',
|
|
432
|
+
forwardingEngine: 'nftables',
|
|
433
|
+
targets: [{ host: 'backend', port: 8080 }],
|
|
434
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
435
|
+
nftables: {
|
|
436
|
+
protocol: 'tcp',
|
|
400
437
|
preserveSourceIP: true // Backend sees real client IP
|
|
401
438
|
}
|
|
402
|
-
|
|
403
|
-
]
|
|
439
|
+
}
|
|
440
|
+
}]
|
|
404
441
|
});
|
|
405
442
|
```
|
|
406
443
|
|
|
@@ -409,15 +446,18 @@ const proxy = new SmartProxy({
|
|
|
409
446
|
Forward encrypted traffic to backends without terminating TLS — the proxy routes based on the SNI hostname alone:
|
|
410
447
|
|
|
411
448
|
```typescript
|
|
412
|
-
import { SmartProxy
|
|
449
|
+
import { SmartProxy } from '@push.rocks/smartproxy';
|
|
413
450
|
|
|
414
451
|
const proxy = new SmartProxy({
|
|
415
|
-
routes: [
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
452
|
+
routes: [{
|
|
453
|
+
name: 'sni-passthrough',
|
|
454
|
+
match: { ports: 443, domains: 'secure.example.com' },
|
|
455
|
+
action: {
|
|
456
|
+
type: 'forward',
|
|
457
|
+
targets: [{ host: 'backend-that-handles-tls', port: 8443 }],
|
|
458
|
+
tls: { mode: 'passthrough' }
|
|
459
|
+
}
|
|
460
|
+
}]
|
|
421
461
|
});
|
|
422
462
|
```
|
|
423
463
|
|
|
@@ -524,15 +564,7 @@ Comprehensive per-route security options:
|
|
|
524
564
|
}
|
|
525
565
|
```
|
|
526
566
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
```typescript
|
|
530
|
-
import { addRateLimiting, addBasicAuth, addJwtAuth } from '@push.rocks/smartproxy';
|
|
531
|
-
|
|
532
|
-
let route = createHttpsTerminateRoute('api.example.com', { host: 'backend', port: 8080 });
|
|
533
|
-
route = addRateLimiting(route, { maxRequests: 100, window: 60, keyBy: 'ip' });
|
|
534
|
-
route = addBasicAuth(route, { users: [{ username: 'admin', password: 'secret' }] });
|
|
535
|
-
```
|
|
567
|
+
Security options are configured directly on each route's `security` property — no separate helpers needed.
|
|
536
568
|
|
|
537
569
|
### 📊 Runtime Management
|
|
538
570
|
|
|
@@ -712,7 +744,7 @@ SmartProxy uses a hybrid **Rust + TypeScript** architecture:
|
|
|
712
744
|
```
|
|
713
745
|
|
|
714
746
|
- **Rust Engine** handles all networking: TCP, UDP, TLS, QUIC, HTTP proxying, connection management, security, and metrics
|
|
715
|
-
- **TypeScript** provides the npm API, configuration types,
|
|
747
|
+
- **TypeScript** provides the npm API, configuration types, validation, and handler callbacks
|
|
716
748
|
- **NFTables** managed by [`@push.rocks/smartnftables`](https://code.foss.global/push.rocks/smartnftables) — kernel-level DNAT/SNAT forwarding, firewall rules, and rate limiting via the `nft` CLI
|
|
717
749
|
- **IPC** — The TypeScript wrapper uses JSON commands/events over stdin/stdout to communicate with the Rust binary
|
|
718
750
|
- **Socket/Datagram Relay** — Unix domain socket servers for routes requiring TypeScript-side handling (socket handlers, datagram handlers, dynamic host/port functions)
|
|
@@ -858,47 +890,13 @@ interface IRouteQuic {
|
|
|
858
890
|
}
|
|
859
891
|
```
|
|
860
892
|
|
|
861
|
-
## 🛠️
|
|
862
|
-
|
|
863
|
-
All helpers are fully typed and return `IRouteConfig` or `IRouteConfig[]`:
|
|
893
|
+
## 🛠️ Exports Reference
|
|
864
894
|
|
|
865
895
|
```typescript
|
|
866
896
|
import {
|
|
867
|
-
//
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
createHttpsPassthroughRoute, // SNI passthrough (no termination)
|
|
871
|
-
createHttpToHttpsRedirect, // HTTP → HTTPS redirect
|
|
872
|
-
createCompleteHttpsServer, // HTTPS + redirect combo (returns IRouteConfig[])
|
|
873
|
-
|
|
874
|
-
// Load Balancing
|
|
875
|
-
createLoadBalancerRoute, // Multi-backend with health checks
|
|
876
|
-
createSmartLoadBalancer, // Dynamic domain-based backend selection
|
|
877
|
-
|
|
878
|
-
// API & WebSocket
|
|
879
|
-
createApiRoute, // API route with path matching
|
|
880
|
-
createApiGatewayRoute, // API gateway with CORS
|
|
881
|
-
createWebSocketRoute, // WebSocket-enabled route
|
|
882
|
-
|
|
883
|
-
// Custom Protocols
|
|
884
|
-
createSocketHandlerRoute, // Custom TCP socket handler
|
|
885
|
-
SocketHandlers, // Pre-built handlers (echo, proxy, block, etc.)
|
|
886
|
-
|
|
887
|
-
// NFTables (Linux, requires root)
|
|
888
|
-
createNfTablesRoute, // Kernel-level packet forwarding
|
|
889
|
-
createNfTablesTerminateRoute, // NFTables + TLS termination
|
|
890
|
-
createCompleteNfTablesHttpsServer, // NFTables HTTPS + redirect combo
|
|
891
|
-
|
|
892
|
-
// Dynamic Routing
|
|
893
|
-
createPortMappingRoute, // Port mapping with context
|
|
894
|
-
createOffsetPortMappingRoute, // Simple port offset
|
|
895
|
-
createDynamicRoute, // Dynamic host/port via functions
|
|
896
|
-
createPortOffset, // Port offset factory
|
|
897
|
-
|
|
898
|
-
// Security Modifiers
|
|
899
|
-
addRateLimiting, // Add rate limiting to any route
|
|
900
|
-
addBasicAuth, // Add basic auth to any route
|
|
901
|
-
addJwtAuth, // Add JWT auth to any route
|
|
897
|
+
// Core
|
|
898
|
+
SmartProxy, // Main proxy class
|
|
899
|
+
SocketHandlers, // Pre-built socket handlers (echo, proxy, block, httpRedirect, httpServer, etc.)
|
|
902
900
|
|
|
903
901
|
// Route Utilities
|
|
904
902
|
mergeRouteConfigs, // Deep-merge two route configs
|
|
@@ -910,7 +908,7 @@ import {
|
|
|
910
908
|
} from '@push.rocks/smartproxy';
|
|
911
909
|
```
|
|
912
910
|
|
|
913
|
-
|
|
911
|
+
All routes are configured as plain `IRouteConfig` objects with `match` and `action` properties — see the examples throughout this document.
|
|
914
912
|
|
|
915
913
|
## 📖 API Documentation
|
|
916
914
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartproxy',
|
|
6
|
-
version: '
|
|
6
|
+
version: '27.0.0',
|
|
7
7
|
description: 'A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.'
|
|
8
8
|
}
|
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
* SmartProxy Route Utilities
|
|
3
3
|
*
|
|
4
4
|
* This file exports all route-related utilities for the SmartProxy module,
|
|
5
|
-
* including
|
|
5
|
+
* including validators, utilities, and socket handlers for working with routes.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
// Export route helpers for creating route configurations
|
|
9
|
-
export * from './route-helpers.js';
|
|
10
|
-
|
|
11
8
|
// Export route validator (class-based and functional API)
|
|
12
9
|
export * from './route-validator.js';
|
|
13
10
|
|
|
@@ -20,10 +17,5 @@ export { generateDefaultCertificate } from './default-cert-generator.js';
|
|
|
20
17
|
// Export concurrency semaphore
|
|
21
18
|
export { ConcurrencySemaphore } from './concurrency-semaphore.js';
|
|
22
19
|
|
|
23
|
-
// Export
|
|
24
|
-
export {
|
|
25
|
-
createApiGatewayRoute,
|
|
26
|
-
addRateLimiting,
|
|
27
|
-
addBasicAuth,
|
|
28
|
-
addJwtAuth
|
|
29
|
-
} from './route-helpers.js';
|
|
20
|
+
// Export socket handlers
|
|
21
|
+
export { SocketHandlers } from './socket-handlers.js';
|
package/ts/proxies/smart-proxy/utils/{route-helpers/socket-handlers.ts → socket-handlers.ts}
RENAMED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* like echoing, proxying, HTTP responses, and redirects.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import * as plugins from '
|
|
9
|
-
import type {
|
|
10
|
-
import { createSocketTracker } from '
|
|
8
|
+
import * as plugins from '../../../plugins.js';
|
|
9
|
+
import type { IRouteContext } from '../models/route-types.js';
|
|
10
|
+
import { createSocketTracker } from '../../../core/utils/socket-tracker.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Minimal HTTP request parser for socket handlers.
|
|
@@ -308,31 +308,3 @@ export const SocketHandlers = {
|
|
|
308
308
|
});
|
|
309
309
|
}
|
|
310
310
|
};
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Create a socket handler route configuration
|
|
314
|
-
*/
|
|
315
|
-
export function createSocketHandlerRoute(
|
|
316
|
-
domains: string | string[],
|
|
317
|
-
ports: TPortRange,
|
|
318
|
-
handler: (socket: plugins.net.Socket) => void | Promise<void>,
|
|
319
|
-
options: {
|
|
320
|
-
name?: string;
|
|
321
|
-
priority?: number;
|
|
322
|
-
path?: string;
|
|
323
|
-
} = {}
|
|
324
|
-
): IRouteConfig {
|
|
325
|
-
return {
|
|
326
|
-
name: options.name || 'socket-handler-route',
|
|
327
|
-
priority: options.priority !== undefined ? options.priority : 50,
|
|
328
|
-
match: {
|
|
329
|
-
domains,
|
|
330
|
-
ports,
|
|
331
|
-
...(options.path && { path: options.path })
|
|
332
|
-
},
|
|
333
|
-
action: {
|
|
334
|
-
type: 'socket-handler',
|
|
335
|
-
socketHandler: handler
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
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;
|
|
@@ -1,108 +0,0 @@
|
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90cy9wcm94aWVzL3NtYXJ0LXByb3h5L3V0aWxzL3JvdXRlLWhlbHBlcnMvYXBpLWhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUdILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUvRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsT0FBMEIsRUFDMUIsT0FBZSxFQUNmLE1BQWlELEVBQ2pELFVBUUksRUFBRTtJQUVOLHFCQUFxQjtJQUNyQixNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUM7SUFDekUsTUFBTSxnQkFBZ0IsR0FBRyxjQUFjLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztRQUNuRCxDQUFDLENBQUMsR0FBRyxjQUFjLEdBQUc7UUFDdEIsQ0FBQyxDQUFDLEdBQUcsY0FBYyxJQUFJLENBQUM7SUFFMUIscUJBQXFCO0lBQ3JCLE1BQU0sS0FBSyxHQUFnQjtRQUN6QixLQUFLLEVBQUUsT0FBTyxDQUFDLE1BQU07WUFDbkIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsSUFBSSxHQUFHLENBQUM7WUFDNUIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7UUFDNUIsT0FBTztRQUNQLElBQUksRUFBRSxnQkFBZ0I7S0FDdkIsQ0FBQztJQUVGLHNCQUFzQjtJQUN0QixNQUFNLE1BQU0sR0FBaUI7UUFDM0IsSUFBSSxFQUFFLFNBQVM7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
|