@push.rocks/smartproxy 22.6.0 → 23.1.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.
Files changed (196) hide show
  1. package/changelog.md +18 -0
  2. package/dist_rust/{rustproxy → rustproxy_linux_amd64} +0 -0
  3. package/dist_rust/rustproxy_linux_arm64 +0 -0
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/index.d.ts +0 -1
  6. package/dist_ts/index.js +1 -3
  7. package/dist_ts/plugins.d.ts +2 -1
  8. package/dist_ts/plugins.js +3 -2
  9. package/dist_ts/proxies/index.d.ts +0 -1
  10. package/dist_ts/proxies/index.js +1 -3
  11. package/dist_ts/proxies/smart-proxy/models/route-types.js +1 -1
  12. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.d.ts +9 -21
  13. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +83 -212
  14. package/dist_ts/proxies/smart-proxy/smart-proxy.js +2 -3
  15. package/npmextra.json +3 -0
  16. package/package.json +13 -11
  17. package/readme.md +35 -31
  18. package/ts/00_commitinfo_data.ts +1 -1
  19. package/ts/index.ts +0 -3
  20. package/ts/plugins.ts +2 -0
  21. package/ts/proxies/index.ts +0 -3
  22. package/ts/proxies/smart-proxy/models/route-types.ts +0 -2
  23. package/ts/proxies/smart-proxy/rust-proxy-bridge.ts +102 -233
  24. package/ts/proxies/smart-proxy/smart-proxy.ts +1 -2
  25. package/dist_ts/common/eventUtils.d.ts +0 -14
  26. package/dist_ts/common/eventUtils.js +0 -20
  27. package/dist_ts/common/types.d.ts +0 -82
  28. package/dist_ts/common/types.js +0 -15
  29. package/dist_ts/core/utils/event-system.d.ts +0 -200
  30. package/dist_ts/core/utils/event-system.js +0 -224
  31. package/dist_ts/core/utils/event-utils.d.ts +0 -15
  32. package/dist_ts/core/utils/event-utils.js +0 -11
  33. package/dist_ts/core/utils/route-manager.d.ts +0 -88
  34. package/dist_ts/core/utils/route-manager.js +0 -342
  35. package/dist_ts/core/utils/route-utils.d.ts +0 -28
  36. package/dist_ts/core/utils/route-utils.js +0 -67
  37. package/dist_ts/detection/detectors/http-detector-v2.d.ts +0 -33
  38. package/dist_ts/detection/detectors/http-detector-v2.js +0 -87
  39. package/dist_ts/detection/detectors/tls-detector-v2.d.ts +0 -33
  40. package/dist_ts/detection/detectors/tls-detector-v2.js +0 -80
  41. package/dist_ts/detection/protocol-detector-v2.d.ts +0 -46
  42. package/dist_ts/detection/protocol-detector-v2.js +0 -116
  43. package/dist_ts/forwarding/config/forwarding-types.d.ts +0 -42
  44. package/dist_ts/forwarding/config/forwarding-types.js +0 -18
  45. package/dist_ts/forwarding/config/index.d.ts +0 -9
  46. package/dist_ts/forwarding/config/index.js +0 -10
  47. package/dist_ts/forwarding/factory/forwarding-factory.d.ts +0 -25
  48. package/dist_ts/forwarding/factory/forwarding-factory.js +0 -172
  49. package/dist_ts/forwarding/factory/index.d.ts +0 -4
  50. package/dist_ts/forwarding/factory/index.js +0 -5
  51. package/dist_ts/forwarding/handlers/base-handler.d.ts +0 -62
  52. package/dist_ts/forwarding/handlers/base-handler.js +0 -121
  53. package/dist_ts/forwarding/handlers/http-handler.d.ts +0 -30
  54. package/dist_ts/forwarding/handlers/http-handler.js +0 -143
  55. package/dist_ts/forwarding/handlers/https-passthrough-handler.d.ts +0 -29
  56. package/dist_ts/forwarding/handlers/https-passthrough-handler.js +0 -156
  57. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.d.ts +0 -36
  58. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.js +0 -276
  59. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.d.ts +0 -35
  60. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.js +0 -261
  61. package/dist_ts/forwarding/handlers/index.d.ts +0 -8
  62. package/dist_ts/forwarding/handlers/index.js +0 -9
  63. package/dist_ts/forwarding/index.d.ts +0 -13
  64. package/dist_ts/forwarding/index.js +0 -16
  65. package/dist_ts/http/index.d.ts +0 -5
  66. package/dist_ts/http/index.js +0 -8
  67. package/dist_ts/http/models/http-types.d.ts +0 -6
  68. package/dist_ts/http/models/http-types.js +0 -7
  69. package/dist_ts/http/router/index.d.ts +0 -8
  70. package/dist_ts/http/router/index.js +0 -7
  71. package/dist_ts/http/router/proxy-router.d.ts +0 -115
  72. package/dist_ts/http/router/proxy-router.js +0 -325
  73. package/dist_ts/http/router/route-router.d.ts +0 -108
  74. package/dist_ts/http/router/route-router.js +0 -393
  75. package/dist_ts/protocols/tls/constants.d.ts +0 -122
  76. package/dist_ts/protocols/tls/constants.js +0 -135
  77. package/dist_ts/protocols/tls/parser.d.ts +0 -53
  78. package/dist_ts/protocols/tls/parser.js +0 -294
  79. package/dist_ts/protocols/tls/types.d.ts +0 -65
  80. package/dist_ts/protocols/tls/types.js +0 -5
  81. package/dist_ts/proxies/http-proxy/certificate-manager.d.ts +0 -95
  82. package/dist_ts/proxies/http-proxy/certificate-manager.js +0 -214
  83. package/dist_ts/proxies/http-proxy/connection-pool.d.ts +0 -47
  84. package/dist_ts/proxies/http-proxy/connection-pool.js +0 -195
  85. package/dist_ts/proxies/http-proxy/context-creator.d.ts +0 -34
  86. package/dist_ts/proxies/http-proxy/context-creator.js +0 -108
  87. package/dist_ts/proxies/http-proxy/default-certificates.d.ts +0 -54
  88. package/dist_ts/proxies/http-proxy/default-certificates.js +0 -127
  89. package/dist_ts/proxies/http-proxy/function-cache.d.ts +0 -95
  90. package/dist_ts/proxies/http-proxy/function-cache.js +0 -215
  91. package/dist_ts/proxies/http-proxy/handlers/index.d.ts +0 -4
  92. package/dist_ts/proxies/http-proxy/handlers/index.js +0 -6
  93. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.d.ts +0 -18
  94. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.js +0 -78
  95. package/dist_ts/proxies/http-proxy/handlers/static-handler.d.ts +0 -19
  96. package/dist_ts/proxies/http-proxy/handlers/static-handler.js +0 -211
  97. package/dist_ts/proxies/http-proxy/http-proxy.d.ts +0 -117
  98. package/dist_ts/proxies/http-proxy/http-proxy.js +0 -521
  99. package/dist_ts/proxies/http-proxy/http-request-handler.d.ts +0 -40
  100. package/dist_ts/proxies/http-proxy/http-request-handler.js +0 -257
  101. package/dist_ts/proxies/http-proxy/http2-request-handler.d.ts +0 -24
  102. package/dist_ts/proxies/http-proxy/http2-request-handler.js +0 -201
  103. package/dist_ts/proxies/http-proxy/index.d.ts +0 -14
  104. package/dist_ts/proxies/http-proxy/index.js +0 -16
  105. package/dist_ts/proxies/http-proxy/models/http-types.d.ts +0 -117
  106. package/dist_ts/proxies/http-proxy/models/http-types.js +0 -92
  107. package/dist_ts/proxies/http-proxy/models/index.d.ts +0 -5
  108. package/dist_ts/proxies/http-proxy/models/index.js +0 -6
  109. package/dist_ts/proxies/http-proxy/models/types.d.ts +0 -75
  110. package/dist_ts/proxies/http-proxy/models/types.js +0 -35
  111. package/dist_ts/proxies/http-proxy/request-handler.d.ts +0 -97
  112. package/dist_ts/proxies/http-proxy/request-handler.js +0 -737
  113. package/dist_ts/proxies/http-proxy/security-manager.d.ts +0 -98
  114. package/dist_ts/proxies/http-proxy/security-manager.js +0 -341
  115. package/dist_ts/proxies/http-proxy/websocket-handler.d.ts +0 -50
  116. package/dist_ts/proxies/http-proxy/websocket-handler.js +0 -505
  117. package/dist_ts/proxies/nftables-proxy/index.d.ts +0 -6
  118. package/dist_ts/proxies/nftables-proxy/index.js +0 -7
  119. package/dist_ts/proxies/nftables-proxy/models/errors.d.ts +0 -15
  120. package/dist_ts/proxies/nftables-proxy/models/errors.js +0 -28
  121. package/dist_ts/proxies/nftables-proxy/models/index.d.ts +0 -5
  122. package/dist_ts/proxies/nftables-proxy/models/index.js +0 -6
  123. package/dist_ts/proxies/nftables-proxy/models/interfaces.d.ts +0 -75
  124. package/dist_ts/proxies/nftables-proxy/models/interfaces.js +0 -5
  125. package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +0 -124
  126. package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +0 -1374
  127. package/dist_ts/proxies/nftables-proxy/utils/index.d.ts +0 -9
  128. package/dist_ts/proxies/nftables-proxy/utils/index.js +0 -12
  129. package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.d.ts +0 -66
  130. package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.js +0 -131
  131. package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.d.ts +0 -39
  132. package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.js +0 -112
  133. package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.d.ts +0 -59
  134. package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.js +0 -130
  135. package/dist_ts/proxies/smart-proxy/acme-state-manager.d.ts +0 -42
  136. package/dist_ts/proxies/smart-proxy/acme-state-manager.js +0 -101
  137. package/dist_ts/proxies/smart-proxy/cert-store.d.ts +0 -10
  138. package/dist_ts/proxies/smart-proxy/cert-store.js +0 -72
  139. package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +0 -164
  140. package/dist_ts/proxies/smart-proxy/certificate-manager.js +0 -745
  141. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +0 -128
  142. package/dist_ts/proxies/smart-proxy/connection-manager.js +0 -689
  143. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +0 -43
  144. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +0 -180
  145. package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +0 -98
  146. package/dist_ts/proxies/smart-proxy/metrics-collector.js +0 -355
  147. package/dist_ts/proxies/smart-proxy/nftables-manager.d.ts +0 -82
  148. package/dist_ts/proxies/smart-proxy/nftables-manager.js +0 -237
  149. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +0 -117
  150. package/dist_ts/proxies/smart-proxy/port-manager.js +0 -318
  151. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +0 -60
  152. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +0 -1407
  153. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +0 -112
  154. package/dist_ts/proxies/smart-proxy/route-manager.js +0 -453
  155. package/dist_ts/proxies/smart-proxy/route-orchestrator.d.ts +0 -56
  156. package/dist_ts/proxies/smart-proxy/route-orchestrator.js +0 -204
  157. package/dist_ts/proxies/smart-proxy/rust-binary-locator.d.ts +0 -23
  158. package/dist_ts/proxies/smart-proxy/rust-binary-locator.js +0 -104
  159. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +0 -74
  160. package/dist_ts/proxies/smart-proxy/security-manager.js +0 -227
  161. package/dist_ts/proxies/smart-proxy/throughput-tracker.d.ts +0 -36
  162. package/dist_ts/proxies/smart-proxy/throughput-tracker.js +0 -115
  163. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +0 -48
  164. package/dist_ts/proxies/smart-proxy/timeout-manager.js +0 -158
  165. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +0 -50
  166. package/dist_ts/proxies/smart-proxy/tls-manager.js +0 -110
  167. package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +0 -161
  168. package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +0 -282
  169. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +0 -73
  170. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +0 -259
  171. package/dist_ts/routing/router/proxy-router.d.ts +0 -115
  172. package/dist_ts/routing/router/proxy-router.js +0 -325
  173. package/dist_ts/routing/router/route-router.d.ts +0 -108
  174. package/dist_ts/routing/router/route-router.js +0 -393
  175. package/dist_ts/tls/alerts/index.d.ts +0 -4
  176. package/dist_ts/tls/alerts/index.js +0 -5
  177. package/dist_ts/tls/alerts/tls-alert.d.ts +0 -150
  178. package/dist_ts/tls/alerts/tls-alert.js +0 -226
  179. package/dist_ts/tls/sni/client-hello-parser.d.ts +0 -100
  180. package/dist_ts/tls/sni/client-hello-parser.js +0 -464
  181. package/dist_ts/tls/sni/sni-extraction.d.ts +0 -58
  182. package/dist_ts/tls/sni/sni-extraction.js +0 -275
  183. package/dist_ts/tls/utils/index.d.ts +0 -4
  184. package/dist_ts/tls/utils/index.js +0 -5
  185. package/dist_ts/tls/utils/tls-utils.d.ts +0 -49
  186. package/dist_ts/tls/utils/tls-utils.js +0 -75
  187. package/ts/proxies/nftables-proxy/index.ts +0 -6
  188. package/ts/proxies/nftables-proxy/models/errors.ts +0 -30
  189. package/ts/proxies/nftables-proxy/models/index.ts +0 -5
  190. package/ts/proxies/nftables-proxy/models/interfaces.ts +0 -94
  191. package/ts/proxies/nftables-proxy/nftables-proxy.ts +0 -1754
  192. package/ts/proxies/nftables-proxy/utils/index.ts +0 -38
  193. package/ts/proxies/nftables-proxy/utils/nft-command-executor.ts +0 -162
  194. package/ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.ts +0 -125
  195. package/ts/proxies/nftables-proxy/utils/nft-rule-validator.ts +0 -156
  196. package/ts/proxies/smart-proxy/rust-binary-locator.ts +0 -112
@@ -1,310 +1,179 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import { logger } from '../../core/utils/logger.js';
3
- import { RustBinaryLocator } from './rust-binary-locator.js';
4
3
  import type { IRouteConfig } from './models/route-types.js';
5
- import { ChildProcess, spawn } from 'child_process';
6
- import { createInterface, Interface as ReadlineInterface } from 'readline';
7
4
 
8
5
  /**
9
- * Management request sent to the Rust binary via stdin.
6
+ * Type-safe command definitions for the Rust proxy IPC protocol.
10
7
  */
11
- interface IManagementRequest {
12
- id: string;
13
- method: string;
14
- params: Record<string, any>;
8
+ type TSmartProxyCommands = {
9
+ start: { params: { config: any }; result: void };
10
+ stop: { params: Record<string, never>; result: void };
11
+ updateRoutes: { params: { routes: IRouteConfig[] }; result: void };
12
+ getMetrics: { params: Record<string, never>; result: any };
13
+ getStatistics: { params: Record<string, never>; result: any };
14
+ provisionCertificate: { params: { routeName: string }; result: void };
15
+ renewCertificate: { params: { routeName: string }; result: void };
16
+ getCertificateStatus: { params: { routeName: string }; result: any };
17
+ getListeningPorts: { params: Record<string, never>; result: { ports: number[] } };
18
+ getNftablesStatus: { params: Record<string, never>; result: any };
19
+ setSocketHandlerRelay: { params: { socketPath: string }; result: void };
20
+ addListeningPort: { params: { port: number }; result: void };
21
+ removeListeningPort: { params: { port: number }; result: void };
22
+ loadCertificate: { params: { domain: string; cert: string; key: string; ca?: string }; result: void };
23
+ };
24
+
25
+ /**
26
+ * Get the package root directory using import.meta.url.
27
+ * This file is at ts/proxies/smart-proxy/, so package root is 3 levels up.
28
+ */
29
+ function getPackageRoot(): string {
30
+ const thisDir = plugins.path.dirname(plugins.url.fileURLToPath(import.meta.url));
31
+ return plugins.path.resolve(thisDir, '..', '..', '..');
15
32
  }
16
33
 
17
34
  /**
18
- * Management response received from the Rust binary via stdout.
35
+ * Map Node.js process.platform/process.arch to tsrust's friendly name suffix.
36
+ * tsrust names cross-compiled binaries as: rustproxy_linux_amd64, rustproxy_linux_arm64, etc.
19
37
  */
20
- interface IManagementResponse {
21
- id: string;
22
- success: boolean;
23
- result?: any;
24
- error?: string;
38
+ function getTsrustPlatformSuffix(): string | null {
39
+ const archMap: Record<string, string> = { x64: 'amd64', arm64: 'arm64' };
40
+ const osMap: Record<string, string> = { linux: 'linux', darwin: 'macos' };
41
+ const os = osMap[process.platform];
42
+ const arch = archMap[process.arch];
43
+ if (os && arch) {
44
+ return `${os}_${arch}`;
45
+ }
46
+ return null;
25
47
  }
26
48
 
27
49
  /**
28
- * Management event received from the Rust binary (unsolicited).
50
+ * Build local search paths for the Rust binary, including dist_rust/ candidates
51
+ * (built by tsrust) and local development build paths.
29
52
  */
30
- interface IManagementEvent {
31
- event: string;
32
- data: any;
53
+ function buildLocalPaths(): string[] {
54
+ const packageRoot = getPackageRoot();
55
+ const suffix = getTsrustPlatformSuffix();
56
+ const paths: string[] = [];
57
+
58
+ // dist_rust/ candidates (tsrust cross-compiled output)
59
+ if (suffix) {
60
+ paths.push(plugins.path.join(packageRoot, 'dist_rust', `rustproxy_${suffix}`));
61
+ }
62
+ paths.push(plugins.path.join(packageRoot, 'dist_rust', 'rustproxy'));
63
+
64
+ // Local dev build paths
65
+ paths.push(plugins.path.resolve(process.cwd(), 'rust', 'target', 'release', 'rustproxy'));
66
+ paths.push(plugins.path.resolve(process.cwd(), 'rust', 'target', 'debug', 'rustproxy'));
67
+
68
+ return paths;
33
69
  }
34
70
 
35
71
  /**
36
72
  * Bridge between TypeScript SmartProxy and the Rust binary.
37
- * Communicates via JSON-over-stdin/stdout IPC protocol.
73
+ * Wraps @push.rocks/smartrust's RustBridge with type-safe command definitions.
38
74
  */
39
75
  export class RustProxyBridge extends plugins.EventEmitter {
40
- private locator = new RustBinaryLocator();
41
- private process: ChildProcess | null = null;
42
- private readline: ReadlineInterface | null = null;
43
- private pendingRequests = new Map<string, {
44
- resolve: (value: any) => void;
45
- reject: (error: Error) => void;
46
- timer: NodeJS.Timeout;
47
- }>();
48
- private requestCounter = 0;
49
- private isRunning = false;
50
- private binaryPath: string | null = null;
51
- private readonly requestTimeoutMs = 30000;
76
+ private bridge: plugins.smartrust.RustBridge<TSmartProxyCommands>;
77
+
78
+ constructor() {
79
+ super();
80
+
81
+ this.bridge = new plugins.smartrust.RustBridge<TSmartProxyCommands>({
82
+ binaryName: 'rustproxy',
83
+ envVarName: 'SMARTPROXY_RUST_BINARY',
84
+ platformPackagePrefix: '@push.rocks/smartproxy',
85
+ localPaths: buildLocalPaths(),
86
+ logger: {
87
+ log: (level: string, message: string, data?: Record<string, any>) => {
88
+ logger.log(level as any, message, data);
89
+ },
90
+ },
91
+ });
92
+
93
+ // Forward events from the inner bridge
94
+ this.bridge.on('exit', (code: number | null, signal: string | null) => {
95
+ this.emit('exit', code, signal);
96
+ });
97
+ }
52
98
 
53
99
  /**
54
100
  * Spawn the Rust binary in management mode.
55
101
  * Returns true if the binary was found and spawned successfully.
56
102
  */
57
103
  public async spawn(): Promise<boolean> {
58
- this.binaryPath = await this.locator.findBinary();
59
- if (!this.binaryPath) {
60
- return false;
61
- }
62
-
63
- return new Promise<boolean>((resolve) => {
64
- try {
65
- this.process = spawn(this.binaryPath!, ['--management'], {
66
- stdio: ['pipe', 'pipe', 'pipe'],
67
- env: { ...process.env },
68
- });
69
-
70
- // Handle stderr (logging from Rust goes here)
71
- const stderrHandler = (data: Buffer) => {
72
- const lines = data.toString().split('\n').filter(l => l.trim());
73
- for (const line of lines) {
74
- logger.log('debug', `[rustproxy] ${line}`, { component: 'rust-bridge' });
75
- }
76
- };
77
- this.process.stderr?.on('data', stderrHandler);
78
-
79
- // Handle stdout (JSON IPC)
80
- this.readline = createInterface({ input: this.process.stdout! });
81
- this.readline.on('line', (line: string) => {
82
- this.handleLine(line.trim());
83
- });
84
-
85
- // Handle process exit
86
- this.process.on('exit', (code, signal) => {
87
- logger.log('info', `RustProxy process exited (code=${code}, signal=${signal})`, { component: 'rust-bridge' });
88
- this.cleanup();
89
- this.emit('exit', code, signal);
90
- });
91
-
92
- this.process.on('error', (err) => {
93
- logger.log('error', `RustProxy process error: ${err.message}`, { component: 'rust-bridge' });
94
- this.cleanup();
95
- resolve(false);
96
- });
97
-
98
- // Wait for the 'ready' event from Rust
99
- const readyTimeout = setTimeout(() => {
100
- logger.log('error', 'RustProxy did not send ready event within 10s', { component: 'rust-bridge' });
101
- this.kill();
102
- resolve(false);
103
- }, 10000);
104
-
105
- this.once('management:ready', () => {
106
- clearTimeout(readyTimeout);
107
- this.isRunning = true;
108
- logger.log('info', 'RustProxy bridge connected', { component: 'rust-bridge' });
109
- resolve(true);
110
- });
111
- } catch (err: any) {
112
- logger.log('error', `Failed to spawn RustProxy: ${err.message}`, { component: 'rust-bridge' });
113
- resolve(false);
114
- }
115
- });
104
+ return this.bridge.spawn();
116
105
  }
117
106
 
118
107
  /**
119
- * Send a management command to the Rust process and wait for the response.
108
+ * Kill the Rust process and clean up.
120
109
  */
121
- public async sendCommand(method: string, params: Record<string, any> = {}): Promise<any> {
122
- if (!this.process || !this.isRunning) {
123
- throw new Error('RustProxy bridge is not running');
124
- }
125
-
126
- const id = `req_${++this.requestCounter}`;
127
- const request: IManagementRequest = { id, method, params };
128
-
129
- return new Promise<any>((resolve, reject) => {
130
- const timer = setTimeout(() => {
131
- this.pendingRequests.delete(id);
132
- reject(new Error(`RustProxy command '${method}' timed out after ${this.requestTimeoutMs}ms`));
133
- }, this.requestTimeoutMs);
134
-
135
- this.pendingRequests.set(id, { resolve, reject, timer });
110
+ public kill(): void {
111
+ this.bridge.kill();
112
+ }
136
113
 
137
- const json = JSON.stringify(request) + '\n';
138
- this.process!.stdin!.write(json, (err) => {
139
- if (err) {
140
- clearTimeout(timer);
141
- this.pendingRequests.delete(id);
142
- reject(new Error(`Failed to write to RustProxy stdin: ${err.message}`));
143
- }
144
- });
145
- });
114
+ /**
115
+ * Whether the bridge is currently running.
116
+ */
117
+ public get running(): boolean {
118
+ return this.bridge.running;
146
119
  }
147
120
 
148
- // Convenience methods for each management command
121
+ // --- Convenience methods for each management command ---
149
122
 
150
123
  public async startProxy(config: any): Promise<void> {
151
- await this.sendCommand('start', { config });
124
+ await this.bridge.sendCommand('start', { config });
152
125
  }
153
126
 
154
127
  public async stopProxy(): Promise<void> {
155
- await this.sendCommand('stop');
128
+ await this.bridge.sendCommand('stop', {} as Record<string, never>);
156
129
  }
157
130
 
158
131
  public async updateRoutes(routes: IRouteConfig[]): Promise<void> {
159
- await this.sendCommand('updateRoutes', { routes });
132
+ await this.bridge.sendCommand('updateRoutes', { routes });
160
133
  }
161
134
 
162
135
  public async getMetrics(): Promise<any> {
163
- return this.sendCommand('getMetrics');
136
+ return this.bridge.sendCommand('getMetrics', {} as Record<string, never>);
164
137
  }
165
138
 
166
139
  public async getStatistics(): Promise<any> {
167
- return this.sendCommand('getStatistics');
140
+ return this.bridge.sendCommand('getStatistics', {} as Record<string, never>);
168
141
  }
169
142
 
170
143
  public async provisionCertificate(routeName: string): Promise<void> {
171
- await this.sendCommand('provisionCertificate', { routeName });
144
+ await this.bridge.sendCommand('provisionCertificate', { routeName });
172
145
  }
173
146
 
174
147
  public async renewCertificate(routeName: string): Promise<void> {
175
- await this.sendCommand('renewCertificate', { routeName });
148
+ await this.bridge.sendCommand('renewCertificate', { routeName });
176
149
  }
177
150
 
178
151
  public async getCertificateStatus(routeName: string): Promise<any> {
179
- return this.sendCommand('getCertificateStatus', { routeName });
152
+ return this.bridge.sendCommand('getCertificateStatus', { routeName });
180
153
  }
181
154
 
182
155
  public async getListeningPorts(): Promise<number[]> {
183
- const result = await this.sendCommand('getListeningPorts');
156
+ const result = await this.bridge.sendCommand('getListeningPorts', {} as Record<string, never>);
184
157
  return result?.ports ?? [];
185
158
  }
186
159
 
187
160
  public async getNftablesStatus(): Promise<any> {
188
- return this.sendCommand('getNftablesStatus');
161
+ return this.bridge.sendCommand('getNftablesStatus', {} as Record<string, never>);
189
162
  }
190
163
 
191
164
  public async setSocketHandlerRelay(socketPath: string): Promise<void> {
192
- await this.sendCommand('setSocketHandlerRelay', { socketPath });
165
+ await this.bridge.sendCommand('setSocketHandlerRelay', { socketPath });
193
166
  }
194
167
 
195
168
  public async addListeningPort(port: number): Promise<void> {
196
- await this.sendCommand('addListeningPort', { port });
169
+ await this.bridge.sendCommand('addListeningPort', { port });
197
170
  }
198
171
 
199
172
  public async removeListeningPort(port: number): Promise<void> {
200
- await this.sendCommand('removeListeningPort', { port });
173
+ await this.bridge.sendCommand('removeListeningPort', { port });
201
174
  }
202
175
 
203
176
  public async loadCertificate(domain: string, cert: string, key: string, ca?: string): Promise<void> {
204
- await this.sendCommand('loadCertificate', { domain, cert, key, ca });
205
- }
206
-
207
- /**
208
- * Kill the Rust process and clean up all stdio streams.
209
- */
210
- public kill(): void {
211
- if (this.process) {
212
- const proc = this.process;
213
- this.process = null;
214
- this.isRunning = false;
215
-
216
- // Close readline (reads from stdout)
217
- if (this.readline) {
218
- this.readline.close();
219
- this.readline = null;
220
- }
221
-
222
- // Reject pending requests
223
- for (const [, pending] of this.pendingRequests) {
224
- clearTimeout(pending.timer);
225
- pending.reject(new Error('RustProxy process killed'));
226
- }
227
- this.pendingRequests.clear();
228
-
229
- // Remove all listeners so nothing keeps references
230
- proc.removeAllListeners();
231
- proc.stdout?.removeAllListeners();
232
- proc.stderr?.removeAllListeners();
233
- proc.stdin?.removeAllListeners();
234
-
235
- // Kill the process
236
- try { proc.kill('SIGTERM'); } catch { /* already dead */ }
237
-
238
- // Destroy all stdio pipes to free handles
239
- try { proc.stdin?.destroy(); } catch { /* ignore */ }
240
- try { proc.stdout?.destroy(); } catch { /* ignore */ }
241
- try { proc.stderr?.destroy(); } catch { /* ignore */ }
242
-
243
- // Unref process so Node doesn't wait for it
244
- try { proc.unref(); } catch { /* ignore */ }
245
-
246
- // Force kill after 5 seconds
247
- setTimeout(() => {
248
- try { proc.kill('SIGKILL'); } catch { /* already dead */ }
249
- }, 5000).unref();
250
- }
251
- }
252
-
253
- /**
254
- * Whether the bridge is currently running.
255
- */
256
- public get running(): boolean {
257
- return this.isRunning;
258
- }
259
-
260
- private handleLine(line: string): void {
261
- if (!line) return;
262
-
263
- let parsed: any;
264
- try {
265
- parsed = JSON.parse(line);
266
- } catch {
267
- logger.log('warn', `Non-JSON output from RustProxy: ${line}`, { component: 'rust-bridge' });
268
- return;
269
- }
270
-
271
- // Check if it's an event (has 'event' field)
272
- if ('event' in parsed) {
273
- const event = parsed as IManagementEvent;
274
- this.emit(`management:${event.event}`, event.data);
275
- return;
276
- }
277
-
278
- // Otherwise it's a response (has 'id' field)
279
- if ('id' in parsed) {
280
- const response = parsed as IManagementResponse;
281
- const pending = this.pendingRequests.get(response.id);
282
- if (pending) {
283
- clearTimeout(pending.timer);
284
- this.pendingRequests.delete(response.id);
285
- if (response.success) {
286
- pending.resolve(response.result);
287
- } else {
288
- pending.reject(new Error(response.error || 'Unknown error from RustProxy'));
289
- }
290
- }
291
- }
292
- }
293
-
294
- private cleanup(): void {
295
- this.isRunning = false;
296
- this.process = null;
297
-
298
- if (this.readline) {
299
- this.readline.close();
300
- this.readline = null;
301
- }
302
-
303
- // Reject all pending requests
304
- for (const [id, pending] of this.pendingRequests) {
305
- clearTimeout(pending.timer);
306
- pending.reject(new Error('RustProxy process exited'));
307
- }
308
- this.pendingRequests.clear();
177
+ await this.bridge.sendCommand('loadCertificate', { domain, cert, key, ca });
309
178
  }
310
179
  }
@@ -3,7 +3,6 @@ import { logger } from '../../core/utils/logger.js';
3
3
 
4
4
  // Rust bridge and helpers
5
5
  import { RustProxyBridge } from './rust-proxy-bridge.js';
6
- import { RustBinaryLocator } from './rust-binary-locator.js';
7
6
  import { RoutePreprocessor } from './route-preprocessor.js';
8
7
  import { SocketHandlerServer } from './socket-handler-server.js';
9
8
  import { RustMetricsAdapter } from './rust-metrics-adapter.js';
@@ -120,7 +119,7 @@ export class SmartProxy extends plugins.EventEmitter {
120
119
  if (!spawned) {
121
120
  throw new Error(
122
121
  'RustProxy binary not found. Set SMARTPROXY_RUST_BINARY env var, install the platform package, ' +
123
- 'or build locally with: cd rust && cargo build --release'
122
+ 'or build locally with: pnpm build'
124
123
  );
125
124
  }
126
125
 
@@ -1,14 +0,0 @@
1
- import type { ICertificateData, ICertificateFailure, ICertificateExpiring } from './types.js';
2
- /**
3
- * Subscribers callback definitions for Port80Handler events
4
- */
5
- export interface Port80HandlerSubscribers {
6
- onCertificateIssued?: (data: ICertificateData) => void;
7
- onCertificateRenewed?: (data: ICertificateData) => void;
8
- onCertificateFailed?: (data: ICertificateFailure) => void;
9
- onCertificateExpiring?: (data: ICertificateExpiring) => void;
10
- }
11
- /**
12
- * Subscribes to Port80Handler events based on provided callbacks
13
- */
14
- export declare function subscribeToPort80Handler(handler: any, subscribers: Port80HandlerSubscribers): void;
@@ -1,20 +0,0 @@
1
- // Port80Handler removed - use SmartCertManager instead
2
- import { Port80HandlerEvents } from './types.js';
3
- /**
4
- * Subscribes to Port80Handler events based on provided callbacks
5
- */
6
- export function subscribeToPort80Handler(handler, subscribers) {
7
- if (subscribers.onCertificateIssued) {
8
- handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, subscribers.onCertificateIssued);
9
- }
10
- if (subscribers.onCertificateRenewed) {
11
- handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, subscribers.onCertificateRenewed);
12
- }
13
- if (subscribers.onCertificateFailed) {
14
- handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, subscribers.onCertificateFailed);
15
- }
16
- if (subscribers.onCertificateExpiring) {
17
- handler.on(Port80HandlerEvents.CERTIFICATE_EXPIRING, subscribers.onCertificateExpiring);
18
- }
19
- }
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRVdGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NvbW1vbi9ldmVudFV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFhakQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsd0JBQXdCLENBQ3RDLE9BQVksRUFDWixXQUFxQztJQUVyQyxJQUFJLFdBQVcsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsa0JBQWtCLEVBQUUsV0FBVyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDdEYsQ0FBQztJQUNELElBQUksV0FBVyxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDckMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN4RixDQUFDO0lBQ0QsSUFBSSxXQUFXLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUNwQyxPQUFPLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLGtCQUFrQixFQUFFLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFDRCxJQUFJLFdBQVcsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ3RDLE9BQU8sQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsb0JBQW9CLEVBQUUsV0FBVyxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDMUYsQ0FBQztBQUNILENBQUMifQ==
@@ -1,82 +0,0 @@
1
- /**
2
- * Shared types for certificate management and domain options
3
- */
4
- /**
5
- * Domain forwarding configuration
6
- */
7
- export interface IForwardConfig {
8
- ip: string;
9
- port: number;
10
- }
11
- /**
12
- * Domain configuration options
13
- */
14
- export interface IDomainOptions {
15
- domainName: string;
16
- sslRedirect: boolean;
17
- acmeMaintenance: boolean;
18
- forward?: IForwardConfig;
19
- acmeForward?: IForwardConfig;
20
- }
21
- /**
22
- * Certificate data that can be emitted via events or set from outside
23
- */
24
- export interface ICertificateData {
25
- domain: string;
26
- certificate: string;
27
- privateKey: string;
28
- expiryDate: Date;
29
- }
30
- /**
31
- * Events emitted by the Port80Handler
32
- */
33
- export declare enum Port80HandlerEvents {
34
- CERTIFICATE_ISSUED = "certificate-issued",
35
- CERTIFICATE_RENEWED = "certificate-renewed",
36
- CERTIFICATE_FAILED = "certificate-failed",
37
- CERTIFICATE_EXPIRING = "certificate-expiring",
38
- MANAGER_STARTED = "manager-started",
39
- MANAGER_STOPPED = "manager-stopped",
40
- REQUEST_FORWARDED = "request-forwarded"
41
- }
42
- /**
43
- * Certificate failure payload type
44
- */
45
- export interface ICertificateFailure {
46
- domain: string;
47
- error: string;
48
- isRenewal: boolean;
49
- }
50
- /**
51
- * Certificate expiry payload type
52
- */
53
- export interface ICertificateExpiring {
54
- domain: string;
55
- expiryDate: Date;
56
- daysRemaining: number;
57
- }
58
- /**
59
- * Forwarding configuration for specific domains in ACME setup
60
- */
61
- export interface IDomainForwardConfig {
62
- domain: string;
63
- forwardConfig?: IForwardConfig;
64
- acmeForwardConfig?: IForwardConfig;
65
- sslRedirect?: boolean;
66
- }
67
- /**
68
- * Unified ACME configuration options used across proxies and handlers
69
- */
70
- export interface IAcmeOptions {
71
- accountEmail?: string;
72
- enabled?: boolean;
73
- port?: number;
74
- useProduction?: boolean;
75
- httpsRedirectPort?: number;
76
- renewThresholdDays?: number;
77
- renewCheckIntervalHours?: number;
78
- autoRenew?: boolean;
79
- certificateStore?: string;
80
- skipConfiguredCerts?: boolean;
81
- domainForwards?: IDomainForwardConfig[];
82
- }
@@ -1,15 +0,0 @@
1
- import * as plugins from '../plugins.js';
2
- /**
3
- * Events emitted by the Port80Handler
4
- */
5
- export var Port80HandlerEvents;
6
- (function (Port80HandlerEvents) {
7
- Port80HandlerEvents["CERTIFICATE_ISSUED"] = "certificate-issued";
8
- Port80HandlerEvents["CERTIFICATE_RENEWED"] = "certificate-renewed";
9
- Port80HandlerEvents["CERTIFICATE_FAILED"] = "certificate-failed";
10
- Port80HandlerEvents["CERTIFICATE_EXPIRING"] = "certificate-expiring";
11
- Port80HandlerEvents["MANAGER_STARTED"] = "manager-started";
12
- Port80HandlerEvents["MANAGER_STOPPED"] = "manager-stopped";
13
- Port80HandlerEvents["REQUEST_FORWARDED"] = "request-forwarded";
14
- })(Port80HandlerEvents || (Port80HandlerEvents = {}));
15
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jb21tb24vdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFtQ3pDOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksbUJBUVg7QUFSRCxXQUFZLG1CQUFtQjtJQUM3QixnRUFBeUMsQ0FBQTtJQUN6QyxrRUFBMkMsQ0FBQTtJQUMzQyxnRUFBeUMsQ0FBQTtJQUN6QyxvRUFBNkMsQ0FBQTtJQUM3QywwREFBbUMsQ0FBQTtJQUNuQywwREFBbUMsQ0FBQTtJQUNuQyw4REFBdUMsQ0FBQTtBQUN6QyxDQUFDLEVBUlcsbUJBQW1CLEtBQW5CLG1CQUFtQixRQVE5QiJ9