@push.rocks/smartproxy 27.10.0 → 27.10.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/.smartconfig.json +15 -7
- package/changelog.md +14 -1
- 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/package.json +16 -24
- package/readme.md +47 -26
- package/ts/00_commitinfo_data.ts +1 -1
package/.smartconfig.json
CHANGED
|
@@ -28,12 +28,17 @@
|
|
|
28
28
|
]
|
|
29
29
|
},
|
|
30
30
|
"release": {
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
"targets": {
|
|
32
|
+
"npm": {
|
|
33
|
+
"registries": [
|
|
34
|
+
"https://verdaccio.lossless.digital",
|
|
35
|
+
"https://registry.npmjs.org"
|
|
36
|
+
],
|
|
37
|
+
"accessLevel": "public"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"schemaVersion": 2
|
|
37
42
|
},
|
|
38
43
|
"@git.zone/tsdoc": {
|
|
39
44
|
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
|
@@ -42,6 +47,9 @@
|
|
|
42
47
|
"npmGlobalTools": []
|
|
43
48
|
},
|
|
44
49
|
"@git.zone/tsrust": {
|
|
45
|
-
"targets": [
|
|
50
|
+
"targets": [
|
|
51
|
+
"linux_amd64",
|
|
52
|
+
"linux_arm64"
|
|
53
|
+
]
|
|
46
54
|
}
|
|
47
55
|
}
|
package/changelog.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Pending
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## 2026-05-12 - 27.10.1
|
|
7
|
+
|
|
8
|
+
### Fixes
|
|
9
|
+
|
|
10
|
+
- handle HTTP/3 backend forwarding failures with protocol fallback and pool cleanup (proxy-service)
|
|
11
|
+
- Retry bodyless requests over HTTP/1.1 when HTTP/3 forwarding fails in auto backend protocol mode
|
|
12
|
+
- Remove broken HTTP/3 pooled connections and record protocol cache failures to avoid repeated H3 reuse
|
|
13
|
+
- Add regression coverage for backends that advertise an unavailable Alt-Svc HTTP/3 endpoint
|
|
14
|
+
- Refresh documentation examples and API notes to reflect target-level load balancing and certificate provisioning event hooks
|
|
15
|
+
|
|
3
16
|
## 2026-04-30 - 27.10.0 - feat(exports)
|
|
4
17
|
export datagram handler types and align tests with updated nftables and route security APIs
|
|
5
18
|
|
|
@@ -1207,4 +1220,4 @@ Fix ACME certificate provisioning timing to ensure ports are listening first
|
|
|
1207
1220
|
- Fixed race condition where certificate provisioning would start before ports were listening
|
|
1208
1221
|
- Modified SmartCertManager.initialize() to defer certificate provisioning
|
|
1209
1222
|
- Added SmartCertManager.provisionCertificatesAfterPortsReady() for delayed provisioning
|
|
1210
|
-
- Updated SmartProxy.start() to call certificate provisioning after ports are ready
|
|
1223
|
+
- Updated SmartProxy.start() to call certificate provisioning after ports are ready
|
|
Binary file
|
|
Binary file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartproxy',
|
|
6
|
-
version: '27.10.
|
|
6
|
+
version: '27.10.1',
|
|
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
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLHFQQUFxUDtDQUNuUSxDQUFBIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartproxy",
|
|
3
|
-
"version": "27.10.
|
|
3
|
+
"version": "27.10.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"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.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -8,24 +8,17 @@
|
|
|
8
8
|
"type": "module",
|
|
9
9
|
"author": "Lossless GmbH",
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"scripts": {
|
|
12
|
-
"test:before": "(tsrust)",
|
|
13
|
-
"test": "(tstest test/**/test*.ts --verbose --timeout 60 --logfile)",
|
|
14
|
-
"build": "(tsbuild tsfolders) && (tsrust)",
|
|
15
|
-
"format": "(gitzone format)",
|
|
16
|
-
"buildDocs": "tsdoc"
|
|
17
|
-
},
|
|
18
11
|
"devDependencies": {
|
|
19
|
-
"@git.zone/tsbuild": "^4.4.
|
|
20
|
-
"@git.zone/tsrun": "^2.0.
|
|
21
|
-
"@git.zone/tsrust": "^1.3.
|
|
22
|
-
"@git.zone/tstest": "^3.6.
|
|
23
|
-
"@push.rocks/smartserve": "^2.0.
|
|
24
|
-
"@types/node": "^25.
|
|
12
|
+
"@git.zone/tsbuild": "^4.4.1",
|
|
13
|
+
"@git.zone/tsrun": "^2.0.4",
|
|
14
|
+
"@git.zone/tsrust": "^1.3.4",
|
|
15
|
+
"@git.zone/tstest": "^3.6.6",
|
|
16
|
+
"@push.rocks/smartserve": "^2.0.4",
|
|
17
|
+
"@types/node": "^25.7.0",
|
|
25
18
|
"@types/ws": "^8.18.1",
|
|
26
19
|
"typescript": "^6.0.3",
|
|
27
20
|
"why-is-node-running": "^3.2.2",
|
|
28
|
-
"ws": "^8.20.
|
|
21
|
+
"ws": "^8.20.1"
|
|
29
22
|
},
|
|
30
23
|
"dependencies": {
|
|
31
24
|
"@push.rocks/smartcrypto": "^2.0.4",
|
|
@@ -77,12 +70,11 @@
|
|
|
77
70
|
"bugs": {
|
|
78
71
|
"url": "https://code.foss.global/push.rocks/smartproxy/issues"
|
|
79
72
|
},
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
}
|
|
73
|
+
"scripts": {
|
|
74
|
+
"test:before": "(tsrust)",
|
|
75
|
+
"test": "(tstest test/**/test*.ts --verbose --timeout 60 --logfile)",
|
|
76
|
+
"build": "(tsbuild tsfolders) && (tsrust)",
|
|
77
|
+
"format": "(gitzone format)",
|
|
78
|
+
"buildDocs": "tsdoc"
|
|
79
|
+
}
|
|
80
|
+
}
|
package/readme.md
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
**A high-performance, Rust-powered proxy toolkit for Node.js** — unified route-based configuration for SSL/TLS termination, HTTP/HTTPS reverse proxying, WebSocket support, UDP/QUIC/HTTP3, load balancing, custom protocol handlers, and kernel-level NFTables forwarding via [`@push.rocks/smartnftables`](https://code.foss.global/push.rocks/smartnftables).
|
|
4
4
|
|
|
5
|
+
## Issue Reporting and Security
|
|
6
|
+
|
|
7
|
+
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
|
|
8
|
+
|
|
5
9
|
## 📦 Installation
|
|
6
10
|
|
|
7
11
|
```bash
|
|
8
12
|
pnpm add @push.rocks/smartproxy
|
|
9
13
|
```
|
|
10
14
|
|
|
11
|
-
## Issue Reporting and Security
|
|
12
|
-
|
|
13
|
-
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
|
|
14
|
-
|
|
15
15
|
## 🎯 What is SmartProxy?
|
|
16
16
|
|
|
17
17
|
SmartProxy is a production-ready proxy solution that takes the complexity out of traffic management. Under the hood, all networking — TCP, UDP, TLS, HTTP reverse proxy, QUIC/HTTP3, connection tracking, security enforcement, and NFTables — is handled by a **Rust engine** for maximum performance, while you configure everything through a clean TypeScript API with full type safety.
|
|
@@ -28,7 +28,7 @@ Whether you're building microservices, deploying edge infrastructure, proxying U
|
|
|
28
28
|
| 🎯 **Flexible Matching** | Route by port, domain, path, protocol, client IP, TLS version, headers, or custom logic |
|
|
29
29
|
| 🚄 **High-Performance** | Choose between user-space or kernel-level (NFTables) forwarding |
|
|
30
30
|
| 📡 **UDP & QUIC/HTTP3** | First-class UDP transport, datagram handlers, QUIC tunneling, and HTTP/3 support |
|
|
31
|
-
| ⚖️ **Load Balancing** | Round-robin, least-connections, IP-hash
|
|
31
|
+
| ⚖️ **Load Balancing** | Round-robin, least-connections, and IP-hash selection across host arrays |
|
|
32
32
|
| 🛡️ **Enterprise Security** | IP filtering, rate limiting, basic auth, JWT auth, connection limits |
|
|
33
33
|
| 🔌 **WebSocket Support** | First-class WebSocket proxying with ping/pong keep-alive |
|
|
34
34
|
| 🎮 **Custom Protocols** | Socket and datagram handlers for implementing any protocol in TypeScript |
|
|
@@ -135,7 +135,9 @@ const proxy = new SmartProxy({
|
|
|
135
135
|
});
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
### ⚖️ Load Balancer
|
|
138
|
+
### ⚖️ Load Balancer
|
|
139
|
+
|
|
140
|
+
For equivalent backends, put the backend hosts into one target's `host` array and choose a target-level load-balancing algorithm. Multiple `targets` are for sub-routing with `target.match` and `priority`.
|
|
139
141
|
|
|
140
142
|
```typescript
|
|
141
143
|
import { SmartProxy } from '@push.rocks/smartproxy';
|
|
@@ -146,22 +148,12 @@ const proxy = new SmartProxy({
|
|
|
146
148
|
match: { ports: 443, domains: 'app.example.com' },
|
|
147
149
|
action: {
|
|
148
150
|
type: 'forward',
|
|
149
|
-
targets: [
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
{
|
|
153
|
-
],
|
|
154
|
-
tls: { mode: 'terminate', certificate: 'auto' }
|
|
155
|
-
loadBalancing: {
|
|
156
|
-
algorithm: 'round-robin',
|
|
157
|
-
healthCheck: {
|
|
158
|
-
path: '/health',
|
|
159
|
-
interval: 30000,
|
|
160
|
-
timeout: 5000,
|
|
161
|
-
unhealthyThreshold: 3,
|
|
162
|
-
healthyThreshold: 2
|
|
163
|
-
}
|
|
164
|
-
}
|
|
151
|
+
targets: [{
|
|
152
|
+
host: ['server1.internal', 'server2.internal', 'server3.internal'],
|
|
153
|
+
port: 8080,
|
|
154
|
+
loadBalancing: { algorithm: 'round-robin' }
|
|
155
|
+
}],
|
|
156
|
+
tls: { mode: 'terminate', certificate: 'auto' }
|
|
165
157
|
}
|
|
166
158
|
}]
|
|
167
159
|
});
|
|
@@ -647,7 +639,9 @@ Supply your own certificates or integrate with external certificate providers:
|
|
|
647
639
|
|
|
648
640
|
```typescript
|
|
649
641
|
const proxy = new SmartProxy({
|
|
650
|
-
certProvisionFunction: async (domain
|
|
642
|
+
certProvisionFunction: async (domain, eventComms) => {
|
|
643
|
+
eventComms.setSource('custom-acme-provider');
|
|
644
|
+
|
|
651
645
|
// Return 'http01' to let the built-in ACME handle it
|
|
652
646
|
if (domain.endsWith('.example.com')) return 'http01';
|
|
653
647
|
|
|
@@ -670,7 +664,11 @@ SmartProxy **never writes certificates to disk**. Instead, you own all persisten
|
|
|
670
664
|
const proxy = new SmartProxy({
|
|
671
665
|
routes: [...],
|
|
672
666
|
|
|
673
|
-
certProvisionFunction: async (domain) =>
|
|
667
|
+
certProvisionFunction: async (domain, eventComms) => {
|
|
668
|
+
const cert = await myAcme.provision(domain);
|
|
669
|
+
eventComms.setExpiryDate(new Date(cert.validUntil));
|
|
670
|
+
return cert;
|
|
671
|
+
},
|
|
674
672
|
|
|
675
673
|
// Your persistence layer — SmartProxy calls these hooks
|
|
676
674
|
certStore: {
|
|
@@ -774,6 +772,8 @@ type TPortRange = number | Array<number | { from: number; to: number }>;
|
|
|
774
772
|
| `forward` | Proxy to one or more backend targets (with optional TLS, WebSocket, load balancing, UDP/QUIC) |
|
|
775
773
|
| `socket-handler` | Custom socket/datagram handling function in TypeScript |
|
|
776
774
|
|
|
775
|
+
`targets` are evaluated as route-internal sub-routes by `target.match` and `target.priority`. For load balancing across equivalent upstreams, use a single target with `host: ['a', 'b', 'c']` and target-level `loadBalancing`.
|
|
776
|
+
|
|
777
777
|
### Target Options
|
|
778
778
|
|
|
779
779
|
```typescript
|
|
@@ -845,6 +845,8 @@ interface IRouteLoadBalancing {
|
|
|
845
845
|
}
|
|
846
846
|
```
|
|
847
847
|
|
|
848
|
+
Use this on an `IRouteTarget` with `host` as a string array. The `healthCheck` shape is accepted by the type layer, but active backend health polling is not currently performed by the Rust selector.
|
|
849
|
+
|
|
848
850
|
### Backend Protocol Options
|
|
849
851
|
|
|
850
852
|
```typescript
|
|
@@ -922,6 +924,7 @@ class SmartProxy extends EventEmitter {
|
|
|
922
924
|
|
|
923
925
|
// Route Management (atomic, mutex-locked)
|
|
924
926
|
updateRoutes(routes: IRouteConfig[]): Promise<void>;
|
|
927
|
+
updateSecurityPolicy(policy: ISmartProxySecurityPolicy): Promise<void>;
|
|
925
928
|
|
|
926
929
|
// Port Management
|
|
927
930
|
addListeningPort(port: number): Promise<void>;
|
|
@@ -930,7 +933,7 @@ class SmartProxy extends EventEmitter {
|
|
|
930
933
|
|
|
931
934
|
// Monitoring & Metrics
|
|
932
935
|
getMetrics(): IMetrics; // Sync — returns cached metrics adapter
|
|
933
|
-
getStatistics(): Promise<
|
|
936
|
+
getStatistics(): Promise<IRustStatistics>; // Async — queries Rust engine
|
|
934
937
|
|
|
935
938
|
// Certificate Management
|
|
936
939
|
provisionCertificate(routeName: string): Promise<void>;
|
|
@@ -965,7 +968,10 @@ interface ISmartProxyOptions {
|
|
|
965
968
|
};
|
|
966
969
|
|
|
967
970
|
// Custom certificate provisioning
|
|
968
|
-
certProvisionFunction?: (
|
|
971
|
+
certProvisionFunction?: (
|
|
972
|
+
domain: string,
|
|
973
|
+
eventComms: ICertProvisionEventComms
|
|
974
|
+
) => Promise<TSmartProxyCertProvisionObject>;
|
|
969
975
|
certProvisionFallbackToAcme?: boolean; // Fall back to ACME on failure (default: true)
|
|
970
976
|
certProvisionTimeout?: number; // Timeout per provision call (ms)
|
|
971
977
|
certProvisionConcurrency?: number; // Max concurrent provisions
|
|
@@ -1001,6 +1007,10 @@ interface ISmartProxyOptions {
|
|
|
1001
1007
|
// Connection limits
|
|
1002
1008
|
maxConnectionsPerIP?: number; // Per-IP connection limit (default: 100)
|
|
1003
1009
|
connectionRateLimitPerMinute?: number; // Per-IP rate limit (default: 300/min)
|
|
1010
|
+
securityPolicy?: {
|
|
1011
|
+
blockedIps?: string[];
|
|
1012
|
+
blockedCidrs?: string[];
|
|
1013
|
+
}; // Global ingress block policy
|
|
1004
1014
|
|
|
1005
1015
|
// Keep-alive
|
|
1006
1016
|
keepAliveTreatment?: 'standard' | 'extended' | 'immortal';
|
|
@@ -1053,17 +1063,25 @@ metrics.connections.total(); // Total connections since start
|
|
|
1053
1063
|
metrics.connections.byRoute(); // Map<routeName, activeCount>
|
|
1054
1064
|
metrics.connections.byIP(); // Map<ip, activeCount>
|
|
1055
1065
|
metrics.connections.topIPs(10); // Top N IPs by connection count
|
|
1066
|
+
metrics.connections.domainRequestsByIP(); // Map<ip, Map<domain, requestCount>>
|
|
1067
|
+
metrics.connections.topDomainRequests(20); // Top IP/domain pairs by request count
|
|
1068
|
+
metrics.connections.frontendProtocols(); // H1/H2/H3/WS frontend distribution
|
|
1069
|
+
metrics.connections.backendProtocols(); // H1/H2/H3/WS backend distribution
|
|
1056
1070
|
|
|
1057
1071
|
// Throughput (bytes/sec)
|
|
1058
1072
|
metrics.throughput.instant(); // { in: number, out: number }
|
|
1059
1073
|
metrics.throughput.recent(); // Recent average
|
|
1060
1074
|
metrics.throughput.average(); // Overall average
|
|
1075
|
+
metrics.throughput.custom(30); // Custom window, if provided by Rust cache
|
|
1076
|
+
metrics.throughput.history(60); // Recent throughput samples
|
|
1061
1077
|
metrics.throughput.byRoute(); // Map<routeName, { in, out }>
|
|
1078
|
+
metrics.throughput.byIP(); // Map<ip, { in, out }>
|
|
1062
1079
|
|
|
1063
1080
|
// Request rates
|
|
1064
1081
|
metrics.requests.perSecond(); // Requests per second
|
|
1065
1082
|
metrics.requests.perMinute(); // Requests per minute
|
|
1066
1083
|
metrics.requests.total(); // Total requests
|
|
1084
|
+
metrics.requests.byDomain(); // Map<domain, { perSecond, lastMinute }>
|
|
1067
1085
|
|
|
1068
1086
|
// UDP metrics
|
|
1069
1087
|
metrics.udp.activeSessions(); // Current active UDP sessions
|
|
@@ -1080,12 +1098,15 @@ metrics.totals.connections(); // Total connections
|
|
|
1080
1098
|
metrics.backends.byBackend(); // Map<backend, IBackendMetrics>
|
|
1081
1099
|
metrics.backends.protocols(); // Map<backend, protocol>
|
|
1082
1100
|
metrics.backends.topByErrors(10); // Top N error-prone backends
|
|
1101
|
+
metrics.backends.detectedProtocols(); // Backend protocol discovery cache
|
|
1083
1102
|
|
|
1084
1103
|
// Percentiles
|
|
1085
1104
|
metrics.percentiles.connectionDuration(); // { p50, p95, p99 }
|
|
1086
1105
|
metrics.percentiles.bytesTransferred(); // { in: { p50, p95, p99 }, out: { p50, p95, p99 } }
|
|
1087
1106
|
```
|
|
1088
1107
|
|
|
1108
|
+
The percentile methods are part of the public metrics shape. In the current Rust adapter they return zeroed values until percentile collection is implemented in the Rust metrics snapshot.
|
|
1109
|
+
|
|
1089
1110
|
## 🐛 Troubleshooting
|
|
1090
1111
|
|
|
1091
1112
|
### Certificate Issues
|
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: '27.10.
|
|
6
|
+
version: '27.10.1',
|
|
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
|
}
|