@push.rocks/smartproxy 22.4.2 → 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 +28 -0
- package/dist_rust/rustproxy +0 -0
- package/dist_ts/00_commitinfo_data.js +1 -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/index.d.ts +1 -5
- package/dist_ts/proxies/index.js +2 -6
- 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 -2
- 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/smart-proxy.d.ts +39 -157
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +224 -621
- 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/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/package.json +1 -1
- package/readme.md +470 -219
- package/ts/00_commitinfo_data.ts +1 -1
- 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/smart-proxy/index.ts +6 -13
- package/ts/proxies/smart-proxy/models/interfaces.ts +6 -4
- 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 -798
- package/ts/proxies/smart-proxy/socket-handler-server.ts +279 -0
- package/ts/routing/index.ts +2 -2
- package/ts/routing/models/http-types.ts +147 -4
- 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/default-certificates.ts +0 -150
- 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 -669
- 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 -18
- 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 -413
- 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 -895
- package/ts/proxies/smart-proxy/connection-manager.ts +0 -809
- package/ts/proxies/smart-proxy/http-proxy-bridge.ts +0 -213
- 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 -1712
- package/ts/proxies/smart-proxy/route-orchestrator.ts +0 -297
- package/ts/proxies/smart-proxy/security-manager.ts +0 -269
- 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 -171
package/changelog.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-02-09 - 22.6.0 - feat(smart-proxy)
|
|
4
|
+
add socket-handler relay, fast-path port-only forwarding, metrics and bridge improvements, and various TS/Rust integration fixes
|
|
5
|
+
|
|
6
|
+
- Add Unix-domain socket relay for socket-handler routes so Rust can hand off matched connections to TypeScript handlers (metadata JSON + initial bytes, relay implementation in Rust and SocketHandlerServer in TS).
|
|
7
|
+
- Implement fast-path port-only forwarding in the TCP accept/handler path to forward simple non-TLS, port-only routes immediately without peeking at client data (improves server-speaks-first protocol handling).
|
|
8
|
+
- Use ArcSwap for route manager hot-reload visibility in accept loops and share socket_handler_relay via Arc<RwLock> so listeners see relay path updates immediately.
|
|
9
|
+
- Enhance SNI/HTTP parsing: add extract_http_path and extract_http_host to aid domain/path matching from initial data.
|
|
10
|
+
- Improve RustProxy shutdown/kill handling: remove listeners, reject pending requests, destroy stdio pipes and unref process to avoid leaking handles.
|
|
11
|
+
- Enhance Rust <-> TS metrics bridge and adapter: add immediate poll(), map Rust JSON fields to IMetrics (per-route active/throughput/totals), and use safer polling/unref timers.
|
|
12
|
+
- SocketHandlerServer enhancements: track active sockets, destroy on stop, pause/resume to prevent data loss, support async socketHandler callbacks and dynamic function-based target forwarding (resolve host/port functions and forward).
|
|
13
|
+
- TypeScript smart-proxy lifecycle tweaks: only set bridge relay after Rust starts, guard unexpected-exit emission when intentionally stopping, stop polling and remove listeners on stop, add stopping flag.
|
|
14
|
+
- Misc: README and API ergonomics updates (nft proxy option renames and config comments), various test updates to use stable http.request helper, adjust timeouts/metrics sampling and assertions, and multiple small bugfixes in listeners, timeouts and TLS typings.
|
|
15
|
+
|
|
16
|
+
## 2026-02-09 - 22.5.0 - feat(rustproxy)
|
|
17
|
+
introduce a Rust-powered proxy engine and workspace with core crates for proxy functionality, ACME/TLS support, passthrough and HTTP proxies, metrics, nftables integration, routing/security, management IPC, tests, and README updates
|
|
18
|
+
|
|
19
|
+
- Add Rust workspace and multiple crates: rustproxy, rustproxy-config, rustproxy-routing, rustproxy-tls, rustproxy-passthrough, rustproxy-http, rustproxy-nftables, rustproxy-metrics, rustproxy-security
|
|
20
|
+
- Implement ACME integration (instant-acme) and an HTTP-01 challenge server with certificate lifecycle management
|
|
21
|
+
- Add TLS management: cert store, cert manager, SNI resolver, TLS acceptor/connector and certificate hot-swap support
|
|
22
|
+
- Implement TCP/TLS passthrough engine with ClientHello SNI parsing, PROXY v1 support, connection tracking and bidirectional forwarder
|
|
23
|
+
- Add Hyper-based HTTP proxy components: request/response filtering, CORS, auth, header templating and upstream selection with load balancing
|
|
24
|
+
- Introduce metrics (throughput tracker, metrics collector) and log deduplication utilities
|
|
25
|
+
- Implement nftables manager and rule builder (safe no-op behavior when not running as root)
|
|
26
|
+
- Add route types, validation, helpers, route manager and matchers (domain/path/header/ip)
|
|
27
|
+
- Provide management IPC (JSON over stdin/stdout) for TypeScript wrapper control (start/stop/add/remove ports, load certificates, etc.)
|
|
28
|
+
- Include extensive unit and integration tests, test helpers, and an example Rust config.json
|
|
29
|
+
- Update README to document the Rust-powered engine, new features and rustBinaryPath lookup
|
|
30
|
+
|
|
3
31
|
## 2026-01-31 - 22.4.2 - fix(tests)
|
|
4
32
|
shorten long-lived connection test timeouts and update certificate metadata timestamps
|
|
5
33
|
|
|
Binary file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartproxy',
|
|
6
|
-
version: '22.
|
|
6
|
+
version: '22.6.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
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHFQQUFxUDtDQUNuUSxDQUFBIn0=
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -2,11 +2,7 @@
|
|
|
2
2
|
* SmartProxy main module exports
|
|
3
3
|
*/
|
|
4
4
|
export * from './proxies/nftables-proxy/index.js';
|
|
5
|
-
export {
|
|
6
|
-
export type { IMetricsTracker, MetricsTracker } from './proxies/http-proxy/index.js';
|
|
7
|
-
export type { IHttpProxyOptions, ICertificateEntry, ILogger } from './proxies/http-proxy/models/types.js';
|
|
8
|
-
export { SharedRouteManager as HttpProxyRouteManager } from './core/routing/route-manager.js';
|
|
9
|
-
export { SmartProxy, ConnectionManager, SecurityManager, TimeoutManager, TlsManager, HttpProxyBridge, RouteConnectionHandler, SmartCertManager } from './proxies/smart-proxy/index.js';
|
|
5
|
+
export { SmartProxy } from './proxies/smart-proxy/index.js';
|
|
10
6
|
export { SharedRouteManager as RouteManager } from './core/routing/route-manager.js';
|
|
11
7
|
export type { ISmartProxyOptions, IConnectionRecord, IRouteConfig, IRouteMatch, IRouteAction, IRouteTls, IRouteContext } from './proxies/smart-proxy/models/index.js';
|
|
12
8
|
export type { TSmartProxyCertProvisionObject } from './proxies/smart-proxy/models/interfaces.js';
|
package/dist_ts/index.js
CHANGED
|
@@ -3,24 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
// NFTables proxy exports
|
|
5
5
|
export * from './proxies/nftables-proxy/index.js';
|
|
6
|
-
// Export
|
|
7
|
-
export {
|
|
8
|
-
export { SharedRouteManager as HttpProxyRouteManager } from './core/routing/route-manager.js';
|
|
9
|
-
// Export SmartProxy elements selectively to avoid RouteManager ambiguity
|
|
10
|
-
export { SmartProxy, ConnectionManager, SecurityManager, TimeoutManager, TlsManager, HttpProxyBridge, RouteConnectionHandler, SmartCertManager } from './proxies/smart-proxy/index.js';
|
|
6
|
+
// Export SmartProxy elements
|
|
7
|
+
export { SmartProxy } from './proxies/smart-proxy/index.js';
|
|
11
8
|
export { SharedRouteManager as RouteManager } from './core/routing/route-manager.js';
|
|
12
9
|
export * from './proxies/smart-proxy/utils/index.js';
|
|
13
10
|
// Original: export * from './smartproxy/classes.pp.snihandler.js'
|
|
14
11
|
// Now we export from the new module
|
|
15
12
|
export { SniHandler } from './tls/sni/sni-handler.js';
|
|
16
|
-
// Original: export * from './smartproxy/classes.pp.interfaces.js'
|
|
17
|
-
// Now we export from the new module (selectively to avoid conflicts)
|
|
18
13
|
// Core types and utilities
|
|
19
14
|
export * from './core/models/common-types.js';
|
|
20
15
|
// Modular exports for new architecture
|
|
21
|
-
// Certificate module has been removed - use SmartCertManager instead
|
|
22
16
|
export * as tls from './tls/index.js';
|
|
23
17
|
export * as routing from './routing/index.js';
|
|
24
18
|
export * as detection from './detection/index.js';
|
|
25
19
|
export * as protocols from './protocols/index.js';
|
|
26
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILHlCQUF5QjtBQUN6QixjQUFjLG1DQUFtQyxDQUFDO0FBRWxELDZCQUE2QjtBQUM3QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDNUQsT0FBTyxFQUFFLGtCQUFrQixJQUFJLFlBQVksRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBS3JGLGNBQWMsc0NBQXNDLENBQUM7QUFFckQsa0VBQWtFO0FBQ2xFLG9DQUFvQztBQUNwQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFdEQsMkJBQTJCO0FBQzNCLGNBQWMsK0JBQStCLENBQUM7QUFLOUMsdUNBQXVDO0FBQ3ZDLE9BQU8sS0FBSyxHQUFHLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEMsT0FBTyxLQUFLLE9BQU8sTUFBTSxvQkFBb0IsQ0FBQztBQUM5QyxPQUFPLEtBQUssU0FBUyxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxTQUFTLE1BQU0sc0JBQXNCLENBQUMifQ==
|
|
@@ -15,6 +15,10 @@ export class FragmentHandler {
|
|
|
15
15
|
// Start cleanup timer if not already running
|
|
16
16
|
if (options.cleanupInterval && !this.cleanupTimer) {
|
|
17
17
|
this.cleanupTimer = setInterval(() => this.cleanup(), options.cleanupInterval);
|
|
18
|
+
// Don't let this timer prevent process exit
|
|
19
|
+
if (this.cleanupTimer.unref) {
|
|
20
|
+
this.cleanupTimer.unref();
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
@@ -114,4 +118,4 @@ export class FragmentHandler {
|
|
|
114
118
|
return this.fragments.size;
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
121
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhZ21lbnQtaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3RvY29scy9jb21tb24vZnJhZ21lbnQtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUM7QUE4QmhDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFJMUIsWUFBb0IsVUFBNEIsRUFBRTtRQUE5QixZQUFPLEdBQVAsT0FBTyxDQUF1QjtRQUgxQyxjQUFTLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7UUFJbkQsNkNBQTZDO1FBQzdDLElBQUksT0FBTyxDQUFDLGVBQWUsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FDN0IsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUNwQixPQUFPLENBQUMsZUFBZSxDQUN4QixDQUFDO1lBQ0YsNENBQTRDO1lBQzVDLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUM1QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVcsQ0FBQyxZQUFvQixFQUFFLFFBQWdCO1FBQ2hELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWxELElBQUksUUFBUSxFQUFFLENBQUM7WUFDYiw0QkFBNEI7WUFDNUIsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUU3RCxtQkFBbUI7WUFDbkIsTUFBTSxPQUFPLEdBQUcsSUFBSSxD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
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Proxy implementations module
|
|
3
3
|
*/
|
|
4
|
-
export {
|
|
5
|
-
export type { IMetricsTracker, MetricsTracker } from './http-proxy/index.js';
|
|
6
|
-
export type { IHttpProxyOptions, ICertificateEntry, ILogger } from './http-proxy/models/types.js';
|
|
7
|
-
export { SharedRouteManager as HttpProxyRouteManager } from '../core/routing/route-manager.js';
|
|
8
|
-
export { SmartProxy, ConnectionManager, SecurityManager, TimeoutManager, TlsManager, HttpProxyBridge, RouteConnectionHandler } from './smart-proxy/index.js';
|
|
4
|
+
export { SmartProxy } from './smart-proxy/index.js';
|
|
9
5
|
export { SharedRouteManager as SmartProxyRouteManager } from '../core/routing/route-manager.js';
|
|
10
6
|
export * from './smart-proxy/utils/index.js';
|
|
11
7
|
export type { ISmartProxyOptions, IConnectionRecord, IRouteConfig, IRouteMatch, IRouteAction, IRouteTls, IRouteContext } from './smart-proxy/models/index.js';
|
package/dist_ts/proxies/index.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Proxy implementations module
|
|
3
3
|
*/
|
|
4
|
-
// Export HttpProxy with selective imports to avoid conflicts
|
|
5
|
-
export { HttpProxy, CertificateManager, ConnectionPool, RequestHandler, WebSocketHandler } from './http-proxy/index.js';
|
|
6
|
-
// RouteManager has been unified - use SharedRouteManager from core/routing
|
|
7
|
-
export { SharedRouteManager as HttpProxyRouteManager } from '../core/routing/route-manager.js';
|
|
8
4
|
// Export SmartProxy with selective imports to avoid conflicts
|
|
9
|
-
export { SmartProxy
|
|
5
|
+
export { SmartProxy } from './smart-proxy/index.js';
|
|
10
6
|
export { SharedRouteManager as SmartProxyRouteManager } from '../core/routing/route-manager.js';
|
|
11
7
|
export * from './smart-proxy/utils/index.js';
|
|
12
8
|
// Export NFTables proxy (no conflicts)
|
|
13
9
|
export * from './nftables-proxy/index.js';
|
|
14
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9wcm94aWVzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsOERBQThEO0FBQzlELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsa0JBQWtCLElBQUksc0JBQXNCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNoRyxjQUFjLDhCQUE4QixDQUFDO0FBSTdDLHVDQUF1QztBQUN2QyxjQUFjLDJCQUEyQixDQUFDIn0=
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SmartProxy implementation
|
|
3
3
|
*
|
|
4
|
-
* Version
|
|
4
|
+
* Version 23.0.0: Rust-backed proxy engine
|
|
5
5
|
*/
|
|
6
6
|
export * from './models/index.js';
|
|
7
7
|
export { SmartProxy } from './smart-proxy.js';
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export { HttpProxyBridge } from './http-proxy-bridge.js';
|
|
8
|
+
export { RustProxyBridge } from './rust-proxy-bridge.js';
|
|
9
|
+
export { RoutePreprocessor } from './route-preprocessor.js';
|
|
10
|
+
export { SocketHandlerServer } from './socket-handler-server.js';
|
|
11
|
+
export { RustMetricsAdapter } from './rust-metrics-adapter.js';
|
|
13
12
|
export { SharedRouteManager as RouteManager } from '../../core/routing/route-manager.js';
|
|
14
|
-
export { RouteConnectionHandler } from './route-connection-handler.js';
|
|
15
|
-
export { NFTablesManager } from './nftables-manager.js';
|
|
16
|
-
export { RouteOrchestrator } from './route-orchestrator.js';
|
|
17
|
-
export { SmartCertManager } from './certificate-manager.js';
|
|
18
13
|
export * from './utils/index.js';
|
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SmartProxy implementation
|
|
3
3
|
*
|
|
4
|
-
* Version
|
|
4
|
+
* Version 23.0.0: Rust-backed proxy engine
|
|
5
5
|
*/
|
|
6
6
|
// Re-export models
|
|
7
7
|
export * from './models/index.js';
|
|
8
8
|
// Export the main SmartProxy class
|
|
9
9
|
export { SmartProxy } from './smart-proxy.js';
|
|
10
|
-
// Export
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
15
|
-
export { HttpProxyBridge } from './http-proxy-bridge.js';
|
|
10
|
+
// Export Rust bridge and helpers
|
|
11
|
+
export { RustProxyBridge } from './rust-proxy-bridge.js';
|
|
12
|
+
export { RoutePreprocessor } from './route-preprocessor.js';
|
|
13
|
+
export { SocketHandlerServer } from './socket-handler-server.js';
|
|
14
|
+
export { RustMetricsAdapter } from './rust-metrics-adapter.js';
|
|
16
15
|
// Export route-based components
|
|
17
16
|
export { SharedRouteManager as RouteManager } from '../../core/routing/route-manager.js';
|
|
18
|
-
export { RouteConnectionHandler } from './route-connection-handler.js';
|
|
19
|
-
export { NFTablesManager } from './nftables-manager.js';
|
|
20
|
-
export { RouteOrchestrator } from './route-orchestrator.js';
|
|
21
|
-
// Export certificate management
|
|
22
|
-
export { SmartCertManager } from './certificate-manager.js';
|
|
23
17
|
// Export all helper functions from the utils directory
|
|
24
18
|
export * from './utils/index.js';
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9wcm94aWVzL3NtYXJ0LXByb3h5L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFDSCxtQkFBbUI7QUFDbkIsY0FBYyxtQkFBbUIsQ0FBQztBQUVsQyxtQ0FBbUM7QUFDbkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTlDLGlDQUFpQztBQUNqQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFL0QsZ0NBQWdDO0FBQ2hDLE9BQU8sRUFBRSxrQkFBa0IsSUFBSSxZQUFZLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUV6Rix1REFBdUQ7QUFDdkQsY0FBYyxrQkFBa0IsQ0FBQyJ9
|
|
@@ -73,8 +73,6 @@ export interface ISmartProxyOptions {
|
|
|
73
73
|
keepAliveTreatment?: 'standard' | 'extended' | 'immortal';
|
|
74
74
|
keepAliveInactivityMultiplier?: number;
|
|
75
75
|
extendedKeepAliveLifetime?: number;
|
|
76
|
-
useHttpProxy?: number[];
|
|
77
|
-
httpProxyPort?: number;
|
|
78
76
|
metrics?: {
|
|
79
77
|
enabled?: boolean;
|
|
80
78
|
sampleIntervalMs?: number;
|
|
@@ -107,6 +105,11 @@ export interface ISmartProxyOptions {
|
|
|
107
105
|
* Default: true
|
|
108
106
|
*/
|
|
109
107
|
certProvisionFallbackToAcme?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Path to the RustProxy binary. If not set, the binary is located
|
|
110
|
+
* automatically via env var, platform package, local build, or PATH.
|
|
111
|
+
*/
|
|
112
|
+
rustBinaryPath?: string;
|
|
110
113
|
}
|
|
111
114
|
/**
|
|
112
115
|
* Enhanced connection record
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { IRouteConfig } from './models/route-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Preprocesses routes before sending them to Rust.
|
|
4
|
+
*
|
|
5
|
+
* Strips non-serializable fields (functions, callbacks) and classifies
|
|
6
|
+
* routes that must be handled by TypeScript (socket-handler, dynamic host/port).
|
|
7
|
+
*/
|
|
8
|
+
export declare class RoutePreprocessor {
|
|
9
|
+
/**
|
|
10
|
+
* Map of route name/id → original route config (with JS functions preserved).
|
|
11
|
+
* Used by the socket handler server to look up the original handler.
|
|
12
|
+
*/
|
|
13
|
+
private originalRoutes;
|
|
14
|
+
/**
|
|
15
|
+
* Preprocess routes for the Rust binary.
|
|
16
|
+
*
|
|
17
|
+
* - Routes with `socketHandler` callbacks are marked as socket-handler type
|
|
18
|
+
* (Rust will relay these back to TS)
|
|
19
|
+
* - Routes with dynamic `host`/`port` functions are converted to socket-handler
|
|
20
|
+
* type (Rust relays, TS resolves the function)
|
|
21
|
+
* - Non-serializable fields are stripped
|
|
22
|
+
* - Original routes are preserved in the local map for handler lookup
|
|
23
|
+
*/
|
|
24
|
+
preprocessForRust(routes: IRouteConfig[]): IRouteConfig[];
|
|
25
|
+
/**
|
|
26
|
+
* Get the original route config (with JS functions) by route name or id.
|
|
27
|
+
*/
|
|
28
|
+
getOriginalRoute(routeKey: string): IRouteConfig | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Get all original routes that have socket handlers or dynamic functions.
|
|
31
|
+
*/
|
|
32
|
+
getHandlerRoutes(): Map<string, IRouteConfig>;
|
|
33
|
+
private preprocessRoute;
|
|
34
|
+
private routeNeedsTsHandling;
|
|
35
|
+
private cleanAction;
|
|
36
|
+
private cleanTarget;
|
|
37
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { logger } from '../../core/utils/logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Preprocesses routes before sending them to Rust.
|
|
4
|
+
*
|
|
5
|
+
* Strips non-serializable fields (functions, callbacks) and classifies
|
|
6
|
+
* routes that must be handled by TypeScript (socket-handler, dynamic host/port).
|
|
7
|
+
*/
|
|
8
|
+
export class RoutePreprocessor {
|
|
9
|
+
constructor() {
|
|
10
|
+
/**
|
|
11
|
+
* Map of route name/id → original route config (with JS functions preserved).
|
|
12
|
+
* Used by the socket handler server to look up the original handler.
|
|
13
|
+
*/
|
|
14
|
+
this.originalRoutes = new Map();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Preprocess routes for the Rust binary.
|
|
18
|
+
*
|
|
19
|
+
* - Routes with `socketHandler` callbacks are marked as socket-handler type
|
|
20
|
+
* (Rust will relay these back to TS)
|
|
21
|
+
* - Routes with dynamic `host`/`port` functions are converted to socket-handler
|
|
22
|
+
* type (Rust relays, TS resolves the function)
|
|
23
|
+
* - Non-serializable fields are stripped
|
|
24
|
+
* - Original routes are preserved in the local map for handler lookup
|
|
25
|
+
*/
|
|
26
|
+
preprocessForRust(routes) {
|
|
27
|
+
this.originalRoutes.clear();
|
|
28
|
+
return routes.map((route, index) => this.preprocessRoute(route, index));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the original route config (with JS functions) by route name or id.
|
|
32
|
+
*/
|
|
33
|
+
getOriginalRoute(routeKey) {
|
|
34
|
+
return this.originalRoutes.get(routeKey);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get all original routes that have socket handlers or dynamic functions.
|
|
38
|
+
*/
|
|
39
|
+
getHandlerRoutes() {
|
|
40
|
+
return new Map(this.originalRoutes);
|
|
41
|
+
}
|
|
42
|
+
preprocessRoute(route, index) {
|
|
43
|
+
const routeKey = route.name || route.id || `route_${index}`;
|
|
44
|
+
// Check if this route needs TS-side handling
|
|
45
|
+
const needsTsHandling = this.routeNeedsTsHandling(route);
|
|
46
|
+
if (needsTsHandling) {
|
|
47
|
+
// Store the original route for handler lookup
|
|
48
|
+
this.originalRoutes.set(routeKey, route);
|
|
49
|
+
}
|
|
50
|
+
// Create a clean copy for Rust
|
|
51
|
+
const cleanRoute = {
|
|
52
|
+
...route,
|
|
53
|
+
action: this.cleanAction(route.action, routeKey, needsTsHandling),
|
|
54
|
+
};
|
|
55
|
+
// Ensure we have a name for handler lookup
|
|
56
|
+
if (!cleanRoute.name && !cleanRoute.id) {
|
|
57
|
+
cleanRoute.name = routeKey;
|
|
58
|
+
}
|
|
59
|
+
return cleanRoute;
|
|
60
|
+
}
|
|
61
|
+
routeNeedsTsHandling(route) {
|
|
62
|
+
// Socket handler routes always need TS
|
|
63
|
+
if (route.action.type === 'socket-handler' && route.action.socketHandler) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
// Routes with dynamic host/port functions need TS
|
|
67
|
+
if (route.action.targets) {
|
|
68
|
+
for (const target of route.action.targets) {
|
|
69
|
+
if (typeof target.host === 'function' || typeof target.port === 'function') {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
cleanAction(action, routeKey, needsTsHandling) {
|
|
77
|
+
const cleanAction = { ...action };
|
|
78
|
+
if (needsTsHandling) {
|
|
79
|
+
// Convert to socket-handler type for Rust (Rust will relay back to TS)
|
|
80
|
+
cleanAction.type = 'socket-handler';
|
|
81
|
+
// Remove the JS handler (not serializable)
|
|
82
|
+
delete cleanAction.socketHandler;
|
|
83
|
+
}
|
|
84
|
+
// Clean targets - replace functions with static values
|
|
85
|
+
if (cleanAction.targets) {
|
|
86
|
+
cleanAction.targets = cleanAction.targets.map(t => this.cleanTarget(t));
|
|
87
|
+
}
|
|
88
|
+
return cleanAction;
|
|
89
|
+
}
|
|
90
|
+
cleanTarget(target) {
|
|
91
|
+
const clean = { ...target };
|
|
92
|
+
// Replace function host with placeholder
|
|
93
|
+
if (typeof clean.host === 'function') {
|
|
94
|
+
clean.host = 'localhost';
|
|
95
|
+
}
|
|
96
|
+
// Replace function port with placeholder
|
|
97
|
+
if (typeof clean.port === 'function') {
|
|
98
|
+
clean.port = 0;
|
|
99
|
+
}
|
|
100
|
+
return clean;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtcHJlcHJvY2Vzc29yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcHJveGllcy9zbWFydC1wcm94eS9yb3V0ZS1wcmVwcm9jZXNzb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXBEOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQUE5QjtRQUNFOzs7V0FHRztRQUNLLG1CQUFjLEdBQUcsSUFBSSxHQUFHLEVBQXdCLENBQUM7SUEyRzNELENBQUM7SUF6R0M7Ozs7Ozs7OztPQVNHO0lBQ0ksaUJBQWlCLENBQUMsTUFBc0I7UUFDN0MsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QixPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFFRDs7T0FFRztJQUNJLGdCQUFnQixDQUFDLFFBQWdCO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOztPQUVHO0lBQ0ksZ0JBQWdCO1FBQ3JCLE9BQU8sSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFTyxlQUFlLENBQUMsS0FBbUIsRUFBRSxLQUFhO1FBQ3hELE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLEVBQUUsSUFBSSxTQUFTLEtBQUssRUFBRSxDQUFDO1FBRTVELDZDQUE2QztRQUM3QyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFekQsSUFBSSxlQUFlLEVBQUUsQ0FB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
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locates the RustProxy binary using a priority-ordered search strategy:
|
|
3
|
+
* 1. SMARTPROXY_RUST_BINARY environment variable
|
|
4
|
+
* 2. Platform-specific optional npm package
|
|
5
|
+
* 3. Local development build at ./rust/target/release/rustproxy
|
|
6
|
+
* 4. System PATH
|
|
7
|
+
*/
|
|
8
|
+
export declare class RustBinaryLocator {
|
|
9
|
+
private cachedPath;
|
|
10
|
+
/**
|
|
11
|
+
* Find the RustProxy binary path.
|
|
12
|
+
* Returns null if no binary is available.
|
|
13
|
+
*/
|
|
14
|
+
findBinary(): Promise<string | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Clear the cached binary path (e.g., after a failed launch).
|
|
17
|
+
*/
|
|
18
|
+
clearCache(): void;
|
|
19
|
+
private searchBinary;
|
|
20
|
+
private findPlatformPackageBinary;
|
|
21
|
+
private isExecutable;
|
|
22
|
+
private findInPath;
|
|
23
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import { logger } from '../../core/utils/logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* Locates the RustProxy binary using a priority-ordered search strategy:
|
|
5
|
+
* 1. SMARTPROXY_RUST_BINARY environment variable
|
|
6
|
+
* 2. Platform-specific optional npm package
|
|
7
|
+
* 3. Local development build at ./rust/target/release/rustproxy
|
|
8
|
+
* 4. System PATH
|
|
9
|
+
*/
|
|
10
|
+
export class RustBinaryLocator {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.cachedPath = null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Find the RustProxy binary path.
|
|
16
|
+
* Returns null if no binary is available.
|
|
17
|
+
*/
|
|
18
|
+
async findBinary() {
|
|
19
|
+
if (this.cachedPath !== null) {
|
|
20
|
+
return this.cachedPath;
|
|
21
|
+
}
|
|
22
|
+
const path = await this.searchBinary();
|
|
23
|
+
this.cachedPath = path;
|
|
24
|
+
return path;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Clear the cached binary path (e.g., after a failed launch).
|
|
28
|
+
*/
|
|
29
|
+
clearCache() {
|
|
30
|
+
this.cachedPath = null;
|
|
31
|
+
}
|
|
32
|
+
async searchBinary() {
|
|
33
|
+
// 1. Environment variable override
|
|
34
|
+
const envPath = process.env.SMARTPROXY_RUST_BINARY;
|
|
35
|
+
if (envPath) {
|
|
36
|
+
if (await this.isExecutable(envPath)) {
|
|
37
|
+
logger.log('info', `RustProxy binary found via SMARTPROXY_RUST_BINARY: ${envPath}`, { component: 'rust-locator' });
|
|
38
|
+
return envPath;
|
|
39
|
+
}
|
|
40
|
+
logger.log('warn', `SMARTPROXY_RUST_BINARY set but not executable: ${envPath}`, { component: 'rust-locator' });
|
|
41
|
+
}
|
|
42
|
+
// 2. Platform-specific optional npm package
|
|
43
|
+
const platformBinary = await this.findPlatformPackageBinary();
|
|
44
|
+
if (platformBinary) {
|
|
45
|
+
logger.log('info', `RustProxy binary found in platform package: ${platformBinary}`, { component: 'rust-locator' });
|
|
46
|
+
return platformBinary;
|
|
47
|
+
}
|
|
48
|
+
// 3. Local development build
|
|
49
|
+
const localPaths = [
|
|
50
|
+
plugins.path.resolve(process.cwd(), 'rust/target/release/rustproxy'),
|
|
51
|
+
plugins.path.resolve(process.cwd(), 'rust/target/debug/rustproxy'),
|
|
52
|
+
];
|
|
53
|
+
for (const localPath of localPaths) {
|
|
54
|
+
if (await this.isExecutable(localPath)) {
|
|
55
|
+
logger.log('info', `RustProxy binary found at local path: ${localPath}`, { component: 'rust-locator' });
|
|
56
|
+
return localPath;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// 4. System PATH
|
|
60
|
+
const systemPath = await this.findInPath('rustproxy');
|
|
61
|
+
if (systemPath) {
|
|
62
|
+
logger.log('info', `RustProxy binary found in system PATH: ${systemPath}`, { component: 'rust-locator' });
|
|
63
|
+
return systemPath;
|
|
64
|
+
}
|
|
65
|
+
logger.log('error', 'No RustProxy binary found. Set SMARTPROXY_RUST_BINARY, install the platform package, or build with: cd rust && cargo build --release', { component: 'rust-locator' });
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
async findPlatformPackageBinary() {
|
|
69
|
+
const platform = process.platform;
|
|
70
|
+
const arch = process.arch;
|
|
71
|
+
const packageName = `@push.rocks/smartproxy-${platform}-${arch}`;
|
|
72
|
+
try {
|
|
73
|
+
// Try to resolve the platform-specific package
|
|
74
|
+
const packagePath = require.resolve(`${packageName}/rustproxy`);
|
|
75
|
+
if (await this.isExecutable(packagePath)) {
|
|
76
|
+
return packagePath;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Package not installed - expected for development
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
async isExecutable(filePath) {
|
|
85
|
+
try {
|
|
86
|
+
await plugins.fs.promises.access(filePath, plugins.fs.constants.X_OK);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async findInPath(binaryName) {
|
|
94
|
+
const pathDirs = (process.env.PATH || '').split(plugins.path.delimiter);
|
|
95
|
+
for (const dir of pathDirs) {
|
|
96
|
+
const fullPath = plugins.path.join(dir, binaryName);
|
|
97
|
+
if (await this.isExecutable(fullPath)) {
|
|
98
|
+
return fullPath;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVzdC1iaW5hcnktbG9jYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3hpZXMvc21hcnQtcHJveHkvcnVzdC1iaW5hcnktbG9jYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVwRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8saUJBQWlCO0lBQTlCO1FBQ1UsZUFBVSxHQUFrQixJQUFJLENBQUM7SUFvRzNDLENBQUM7SUFsR0M7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLFVBQVU7UUFDckIsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzdCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUN6QixDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDdkIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxVQUFVO1FBQ2YsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUVPLEtBQUssQ0FBQyxZQUFZO1FBQ3hCLG1DQUFtQztRQUNuQyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDO1FBQ25ELElBQUksT0FBTyxFQUFFLENBQUM7WUFDWixJQUFJLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxzREFBc0QsT0FBTyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztnQkFDbkgsT0FBTyxPQUFPLENBQUM7WUFDakIsQ0FBQztZQUNELE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGtEQUFrRCxPQUFPLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQ2pILENBQUM7UUFFRCw0Q0FBNEM7UUFDNUMsTUFBTSxjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUM5RCxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLCtDQUErQyxjQUFjLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1lBQ25ILE9BQU8sY0FBYyxDQUFDO1FBQ3hCLENBQUM7UUFFRCw2QkFBNkI7UUFDN0IsTUFBTSxVQUFVLEdBQUc7WUFDakIsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLCtCQUErQixDQUFDO1lBQ3BFLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSw2QkFBNkIsQ0FBQztTQUNuRSxDQUFDO1FBQ0YsS0FBSyxNQUFNLFNBQVMsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNuQyxJQUFJLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUN2QyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSx5Q0FBeUMsU0FBUyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztnQkFDeEcsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztRQUNILENBQUM7UUFFRCxpQkFBaUI7UUFDakIsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3RELElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSwwQ0FBMEMsVUFBVSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztZQUMxRyxPQUFPLFVBQVUsQ0FBQztRQUNwQixDQUFDO1FBRUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsc0lBQXNJLEVBQUUsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztRQUMzTCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxLQUFLLENBQUMseUJBQXlCO1FBQ3JDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDbEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztRQUMxQixNQUFNLFdBQVcsR0FBRywwQkFBMEIsUUFBUSxJQUFJLElBQUksRUFBRSxDQUFDO1FBRWpFLElBQUksQ0FBQztZQUNILCtDQUErQztZQUMvQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsV0FBVyxZQUFZLENBQUMsQ0FBQztZQUNoRSxJQUFJLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO2dCQUN6QyxPQUFPLFdBQVcsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLG1EQUFtRDtRQUNyRCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU8sS0FBSyxDQUFDLFlBQVksQ0FBQyxRQUFnQjtRQUN6QyxJQUFJLENBQUM7WUFDSCxNQUFNLE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdEUsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxVQUFVLENBQUMsVUFBa0I7UUFDekMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4RSxLQUFLLE1BQU0sR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQzNCLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNwRCxJQUFJLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUN0QyxPQUFPLFFBQVEsQ0FBQztZQUNsQixDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztDQUNGIn0=
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { IMetrics, IThroughputData, IThroughputHistoryPoint } from './models/metrics-types.js';
|
|
2
|
+
import type { RustProxyBridge } from './rust-proxy-bridge.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adapts Rust JSON metrics to the IMetrics interface.
|
|
5
|
+
*
|
|
6
|
+
* Polls the Rust binary periodically via the bridge and caches the result.
|
|
7
|
+
* All IMetrics getters read from the cache synchronously.
|
|
8
|
+
*
|
|
9
|
+
* Rust Metrics JSON fields (camelCase via serde):
|
|
10
|
+
* activeConnections, totalConnections, bytesIn, bytesOut,
|
|
11
|
+
* throughputInBytesPerSec, throughputOutBytesPerSec,
|
|
12
|
+
* routes: { [routeName]: { activeConnections, totalConnections, bytesIn, bytesOut, ... } }
|
|
13
|
+
*/
|
|
14
|
+
export declare class RustMetricsAdapter implements IMetrics {
|
|
15
|
+
private bridge;
|
|
16
|
+
private cache;
|
|
17
|
+
private pollTimer;
|
|
18
|
+
private pollIntervalMs;
|
|
19
|
+
constructor(bridge: RustProxyBridge, pollIntervalMs?: number);
|
|
20
|
+
/**
|
|
21
|
+
* Poll Rust for metrics once. Can be awaited to ensure cache is fresh.
|
|
22
|
+
*/
|
|
23
|
+
poll(): Promise<void>;
|
|
24
|
+
startPolling(): void;
|
|
25
|
+
stopPolling(): void;
|
|
26
|
+
connections: {
|
|
27
|
+
active: () => number;
|
|
28
|
+
total: () => number;
|
|
29
|
+
byRoute: () => Map<string, number>;
|
|
30
|
+
byIP: () => Map<string, number>;
|
|
31
|
+
topIPs: (_limit?: number) => Array<{
|
|
32
|
+
ip: string;
|
|
33
|
+
count: number;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
throughput: {
|
|
37
|
+
instant: () => IThroughputData;
|
|
38
|
+
recent: () => IThroughputData;
|
|
39
|
+
average: () => IThroughputData;
|
|
40
|
+
custom: (_seconds: number) => IThroughputData;
|
|
41
|
+
history: (_seconds: number) => Array<IThroughputHistoryPoint>;
|
|
42
|
+
byRoute: (_windowSeconds?: number) => Map<string, IThroughputData>;
|
|
43
|
+
byIP: (_windowSeconds?: number) => Map<string, IThroughputData>;
|
|
44
|
+
};
|
|
45
|
+
requests: {
|
|
46
|
+
perSecond: () => number;
|
|
47
|
+
perMinute: () => number;
|
|
48
|
+
total: () => number;
|
|
49
|
+
};
|
|
50
|
+
totals: {
|
|
51
|
+
bytesIn: () => number;
|
|
52
|
+
bytesOut: () => number;
|
|
53
|
+
connections: () => number;
|
|
54
|
+
};
|
|
55
|
+
percentiles: {
|
|
56
|
+
connectionDuration: () => {
|
|
57
|
+
p50: number;
|
|
58
|
+
p95: number;
|
|
59
|
+
p99: number;
|
|
60
|
+
};
|
|
61
|
+
bytesTransferred: () => {
|
|
62
|
+
in: {
|
|
63
|
+
p50: number;
|
|
64
|
+
p95: number;
|
|
65
|
+
p99: number;
|
|
66
|
+
};
|
|
67
|
+
out: {
|
|
68
|
+
p50: number;
|
|
69
|
+
p95: number;
|
|
70
|
+
p99: number;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}
|