@push.rocks/smartproxy 27.9.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 CHANGED
@@ -28,12 +28,17 @@
28
28
  ]
29
29
  },
30
30
  "release": {
31
- "registries": [
32
- "https://verdaccio.lossless.digital",
33
- "https://registry.npmjs.org"
34
- ],
35
- "accessLevel": "public"
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": ["linux_amd64", "linux_arm64"]
50
+ "targets": [
51
+ "linux_amd64",
52
+ "linux_arm64"
53
+ ]
46
54
  }
47
55
  }
package/changelog.md CHANGED
@@ -1,5 +1,26 @@
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
+
16
+ ## 2026-04-30 - 27.10.0 - feat(exports)
17
+ export datagram handler types and align tests with updated nftables and route security APIs
18
+
19
+ - Exports TDatagramHandler and IDatagramInfo from the public index.
20
+ - Updates nftables integration tests for the new grouped status shape and null result after shutdown.
21
+ - Moves route IP allow list configuration to security and awaits the asynchronous listening ports API.
22
+ - Enables stricter TypeScript checks with noImplicitAny and safer error handling in tests.
23
+
3
24
  ## 2026-04-26 - 27.9.0 - feat(smart-proxy)
4
25
  add hot-reloadable global ingress security policy across Rust and TypeScript proxy layers
5
26
 
@@ -1199,4 +1220,4 @@ Fix ACME certificate provisioning timing to ensure ports are listening first
1199
1220
  - Fixed race condition where certificate provisioning would start before ports were listening
1200
1221
  - Modified SmartCertManager.initialize() to defer certificate provisioning
1201
1222
  - Added SmartCertManager.provisionCertificatesAfterPortsReady() for delayed provisioning
1202
- - 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.9.0',
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
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHFQQUFxUDtDQUNuUSxDQUFBIn0=
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLHFQQUFxUDtDQUNuUSxDQUFBIn0=
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export { SmartProxy } from './proxies/smart-proxy/index.js';
5
5
  export { SharedRouteManager as RouteManager } from './core/routing/route-manager.js';
6
- export type { ISmartProxyOptions, ISmartProxySecurityPolicy, IConnectionRecord, IRouteConfig, IRouteMatch, IRouteAction, IRouteTls, IRouteContext } from './proxies/smart-proxy/models/index.js';
6
+ export type { ISmartProxyOptions, ISmartProxySecurityPolicy, IConnectionRecord, IRouteConfig, IRouteMatch, IRouteAction, IRouteTls, IRouteContext, TDatagramHandler, IDatagramInfo } from './proxies/smart-proxy/models/index.js';
7
7
  export type { TSmartProxyCertProvisionObject, ICertProvisionEventComms, ICertificateIssuedEvent, ICertificateFailedEvent } from './proxies/smart-proxy/models/interfaces.js';
8
8
  export * from './proxies/smart-proxy/utils/index.js';
9
9
  export * from './core/models/common-types.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartproxy",
3
- "version": "27.9.0",
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,32 +8,25 @@
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 --allowimplicitany) && (tsrust)",
15
- "format": "(gitzone format)",
16
- "buildDocs": "tsdoc"
17
- },
18
11
  "devDependencies": {
19
- "@git.zone/tsbuild": "^4.4.0",
20
- "@git.zone/tsrun": "^2.0.2",
21
- "@git.zone/tsrust": "^1.3.2",
22
- "@git.zone/tstest": "^3.6.0",
23
- "@push.rocks/smartserve": "^2.0.3",
24
- "@types/node": "^25.5.0",
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
- "typescript": "^6.0.2",
19
+ "typescript": "^6.0.3",
27
20
  "why-is-node-running": "^3.2.2",
28
- "ws": "^8.20.0"
21
+ "ws": "^8.20.1"
29
22
  },
30
23
  "dependencies": {
31
24
  "@push.rocks/smartcrypto": "^2.0.4",
32
- "@push.rocks/smartlog": "^3.2.1",
33
- "@push.rocks/smartnftables": "^1.0.1",
34
- "@push.rocks/smartrust": "^1.3.2",
35
- "@tsclass/tsclass": "^9.5.0",
36
- "minimatch": "^10.2.4"
25
+ "@push.rocks/smartlog": "^3.2.2",
26
+ "@push.rocks/smartnftables": "^1.2.0",
27
+ "@push.rocks/smartrust": "^1.4.0",
28
+ "@tsclass/tsclass": "^9.5.1",
29
+ "minimatch": "^10.2.5"
37
30
  },
38
31
  "files": [
39
32
  "ts/**/*",
@@ -45,6 +38,7 @@
45
38
  "assets/**/*",
46
39
  "cli.js",
47
40
  ".smartconfig.json",
41
+ "license",
48
42
  "readme.md",
49
43
  "changelog.md"
50
44
  ],
@@ -76,13 +70,11 @@
76
70
  "bugs": {
77
71
  "url": "https://code.foss.global/push.rocks/smartproxy/issues"
78
72
  },
79
- "pnpm": {
80
- "overrides": {},
81
- "onlyBuiltDependencies": [
82
- "esbuild",
83
- "mongodb-memory-server",
84
- "puppeteer"
85
- ]
86
- },
87
- "packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39"
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,18 +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
- npm install @push.rocks/smartproxy
9
- # or
10
12
  pnpm add @push.rocks/smartproxy
11
13
  ```
12
14
 
13
- ## Issue Reporting and Security
14
-
15
- 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.
16
-
17
15
  ## 🎯 What is SmartProxy?
18
16
 
19
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.
@@ -30,7 +28,7 @@ Whether you're building microservices, deploying edge infrastructure, proxying U
30
28
  | 🎯 **Flexible Matching** | Route by port, domain, path, protocol, client IP, TLS version, headers, or custom logic |
31
29
  | 🚄 **High-Performance** | Choose between user-space or kernel-level (NFTables) forwarding |
32
30
  | 📡 **UDP & QUIC/HTTP3** | First-class UDP transport, datagram handlers, QUIC tunneling, and HTTP/3 support |
33
- | ⚖️ **Load Balancing** | Round-robin, least-connections, IP-hash with health checks |
31
+ | ⚖️ **Load Balancing** | Round-robin, least-connections, and IP-hash selection across host arrays |
34
32
  | 🛡️ **Enterprise Security** | IP filtering, rate limiting, basic auth, JWT auth, connection limits |
35
33
  | 🔌 **WebSocket Support** | First-class WebSocket proxying with ping/pong keep-alive |
36
34
  | 🎮 **Custom Protocols** | Socket and datagram handlers for implementing any protocol in TypeScript |
@@ -137,7 +135,9 @@ const proxy = new SmartProxy({
137
135
  });
138
136
  ```
139
137
 
140
- ### ⚖️ Load Balancer with Health Checks
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`.
141
141
 
142
142
  ```typescript
143
143
  import { SmartProxy } from '@push.rocks/smartproxy';
@@ -148,22 +148,12 @@ const proxy = new SmartProxy({
148
148
  match: { ports: 443, domains: 'app.example.com' },
149
149
  action: {
150
150
  type: 'forward',
151
- targets: [
152
- { host: 'server1.internal', port: 8080 },
153
- { host: 'server2.internal', port: 8080 },
154
- { host: 'server3.internal', port: 8080 }
155
- ],
156
- tls: { mode: 'terminate', certificate: 'auto' },
157
- loadBalancing: {
158
- algorithm: 'round-robin',
159
- healthCheck: {
160
- path: '/health',
161
- interval: 30000,
162
- timeout: 5000,
163
- unhealthyThreshold: 3,
164
- healthyThreshold: 2
165
- }
166
- }
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' }
167
157
  }
168
158
  }]
169
159
  });
@@ -649,7 +639,9 @@ Supply your own certificates or integrate with external certificate providers:
649
639
 
650
640
  ```typescript
651
641
  const proxy = new SmartProxy({
652
- certProvisionFunction: async (domain: string) => {
642
+ certProvisionFunction: async (domain, eventComms) => {
643
+ eventComms.setSource('custom-acme-provider');
644
+
653
645
  // Return 'http01' to let the built-in ACME handle it
654
646
  if (domain.endsWith('.example.com')) return 'http01';
655
647
 
@@ -672,7 +664,11 @@ SmartProxy **never writes certificates to disk**. Instead, you own all persisten
672
664
  const proxy = new SmartProxy({
673
665
  routes: [...],
674
666
 
675
- certProvisionFunction: async (domain) => myAcme.provision(domain),
667
+ certProvisionFunction: async (domain, eventComms) => {
668
+ const cert = await myAcme.provision(domain);
669
+ eventComms.setExpiryDate(new Date(cert.validUntil));
670
+ return cert;
671
+ },
676
672
 
677
673
  // Your persistence layer — SmartProxy calls these hooks
678
674
  certStore: {
@@ -776,6 +772,8 @@ type TPortRange = number | Array<number | { from: number; to: number }>;
776
772
  | `forward` | Proxy to one or more backend targets (with optional TLS, WebSocket, load balancing, UDP/QUIC) |
777
773
  | `socket-handler` | Custom socket/datagram handling function in TypeScript |
778
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
+
779
777
  ### Target Options
780
778
 
781
779
  ```typescript
@@ -847,6 +845,8 @@ interface IRouteLoadBalancing {
847
845
  }
848
846
  ```
849
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
+
850
850
  ### Backend Protocol Options
851
851
 
852
852
  ```typescript
@@ -924,6 +924,7 @@ class SmartProxy extends EventEmitter {
924
924
 
925
925
  // Route Management (atomic, mutex-locked)
926
926
  updateRoutes(routes: IRouteConfig[]): Promise<void>;
927
+ updateSecurityPolicy(policy: ISmartProxySecurityPolicy): Promise<void>;
927
928
 
928
929
  // Port Management
929
930
  addListeningPort(port: number): Promise<void>;
@@ -932,7 +933,7 @@ class SmartProxy extends EventEmitter {
932
933
 
933
934
  // Monitoring & Metrics
934
935
  getMetrics(): IMetrics; // Sync — returns cached metrics adapter
935
- getStatistics(): Promise<any>; // Async — queries Rust engine
936
+ getStatistics(): Promise<IRustStatistics>; // Async — queries Rust engine
936
937
 
937
938
  // Certificate Management
938
939
  provisionCertificate(routeName: string): Promise<void>;
@@ -967,7 +968,10 @@ interface ISmartProxyOptions {
967
968
  };
968
969
 
969
970
  // Custom certificate provisioning
970
- certProvisionFunction?: (domain: string) => Promise<ICert | 'http01'>;
971
+ certProvisionFunction?: (
972
+ domain: string,
973
+ eventComms: ICertProvisionEventComms
974
+ ) => Promise<TSmartProxyCertProvisionObject>;
971
975
  certProvisionFallbackToAcme?: boolean; // Fall back to ACME on failure (default: true)
972
976
  certProvisionTimeout?: number; // Timeout per provision call (ms)
973
977
  certProvisionConcurrency?: number; // Max concurrent provisions
@@ -1003,6 +1007,10 @@ interface ISmartProxyOptions {
1003
1007
  // Connection limits
1004
1008
  maxConnectionsPerIP?: number; // Per-IP connection limit (default: 100)
1005
1009
  connectionRateLimitPerMinute?: number; // Per-IP rate limit (default: 300/min)
1010
+ securityPolicy?: {
1011
+ blockedIps?: string[];
1012
+ blockedCidrs?: string[];
1013
+ }; // Global ingress block policy
1006
1014
 
1007
1015
  // Keep-alive
1008
1016
  keepAliveTreatment?: 'standard' | 'extended' | 'immortal';
@@ -1055,17 +1063,25 @@ metrics.connections.total(); // Total connections since start
1055
1063
  metrics.connections.byRoute(); // Map<routeName, activeCount>
1056
1064
  metrics.connections.byIP(); // Map<ip, activeCount>
1057
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
1058
1070
 
1059
1071
  // Throughput (bytes/sec)
1060
1072
  metrics.throughput.instant(); // { in: number, out: number }
1061
1073
  metrics.throughput.recent(); // Recent average
1062
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
1063
1077
  metrics.throughput.byRoute(); // Map<routeName, { in, out }>
1078
+ metrics.throughput.byIP(); // Map<ip, { in, out }>
1064
1079
 
1065
1080
  // Request rates
1066
1081
  metrics.requests.perSecond(); // Requests per second
1067
1082
  metrics.requests.perMinute(); // Requests per minute
1068
1083
  metrics.requests.total(); // Total requests
1084
+ metrics.requests.byDomain(); // Map<domain, { perSecond, lastMinute }>
1069
1085
 
1070
1086
  // UDP metrics
1071
1087
  metrics.udp.activeSessions(); // Current active UDP sessions
@@ -1082,12 +1098,15 @@ metrics.totals.connections(); // Total connections
1082
1098
  metrics.backends.byBackend(); // Map<backend, IBackendMetrics>
1083
1099
  metrics.backends.protocols(); // Map<backend, protocol>
1084
1100
  metrics.backends.topByErrors(10); // Top N error-prone backends
1101
+ metrics.backends.detectedProtocols(); // Backend protocol discovery cache
1085
1102
 
1086
1103
  // Percentiles
1087
1104
  metrics.percentiles.connectionDuration(); // { p50, p95, p99 }
1088
1105
  metrics.percentiles.bytesTransferred(); // { in: { p50, p95, p99 }, out: { p50, p95, p99 } }
1089
1106
  ```
1090
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
+
1091
1110
  ## 🐛 Troubleshooting
1092
1111
 
1093
1112
  ### Certificate Issues
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartproxy',
6
- version: '27.9.0',
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
  }
package/ts/index.ts CHANGED
@@ -7,7 +7,7 @@ export { SmartProxy } from './proxies/smart-proxy/index.js';
7
7
  export { SharedRouteManager as RouteManager } from './core/routing/route-manager.js';
8
8
 
9
9
  // Export smart-proxy models
10
- export type { ISmartProxyOptions, ISmartProxySecurityPolicy, IConnectionRecord, IRouteConfig, IRouteMatch, IRouteAction, IRouteTls, IRouteContext } from './proxies/smart-proxy/models/index.js';
10
+ export type { ISmartProxyOptions, ISmartProxySecurityPolicy, IConnectionRecord, IRouteConfig, IRouteMatch, IRouteAction, IRouteTls, IRouteContext, TDatagramHandler, IDatagramInfo } from './proxies/smart-proxy/models/index.js';
11
11
  export type { TSmartProxyCertProvisionObject, ICertProvisionEventComms, ICertificateIssuedEvent, ICertificateFailedEvent } from './proxies/smart-proxy/models/interfaces.js';
12
12
  export * from './proxies/smart-proxy/utils/index.js';
13
13