@push.rocks/smartproxy 7.1.1 → 7.2.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.
@@ -13,8 +13,9 @@ import * as fs from 'fs';
13
13
  /**
14
14
  * SmartProxy - Main class that coordinates all components
15
15
  */
16
- export class SmartProxy {
16
+ export class SmartProxy extends plugins.EventEmitter {
17
17
  constructor(settingsArg) {
18
+ super();
18
19
  this.netServers = [];
19
20
  this.connectionLogger = null;
20
21
  this.isShuttingDown = false;
@@ -137,26 +138,68 @@ export class SmartProxy {
137
138
  console.log(`Registered domain forwarding for ${forward.domain}`);
138
139
  }
139
140
  }
140
- // Register all non-wildcard domains from domain configs
141
+ // Provision certificates per domain via certProvider or HTTP-01
141
142
  for (const domainConfig of this.settings.domainConfigs) {
142
143
  for (const domain of domainConfig.domains) {
143
- // Skip wildcards
144
+ // Skip wildcard domains
144
145
  if (domain.includes('*'))
145
146
  continue;
146
- this.port80Handler.addDomain({
147
- domainName: domain,
148
- sslRedirect: true,
149
- acmeMaintenance: true
150
- });
151
- console.log(`Registered domain ${domain} with Port80Handler`);
147
+ // Determine provisioning method
148
+ let provision = 'http01';
149
+ if (this.settings.certProvider) {
150
+ try {
151
+ provision = await this.settings.certProvider(domain);
152
+ }
153
+ catch (err) {
154
+ console.log(`certProvider error for ${domain}: ${err}`);
155
+ }
156
+ }
157
+ if (provision === 'http01') {
158
+ this.port80Handler.addDomain({
159
+ domainName: domain,
160
+ sslRedirect: true,
161
+ acmeMaintenance: true
162
+ });
163
+ console.log(`Registered domain ${domain} with Port80Handler for HTTP-01`);
164
+ }
165
+ else {
166
+ // Static certificate provided
167
+ const certObj = provision;
168
+ const certData = {
169
+ domain: certObj.domainName,
170
+ certificate: certObj.publicKey,
171
+ privateKey: certObj.privateKey,
172
+ expiryDate: new Date(certObj.validUntil)
173
+ };
174
+ this.networkProxyBridge.applyExternalCertificate(certData);
175
+ console.log(`Applied static certificate for ${domain} from certProvider`);
176
+ }
152
177
  }
153
178
  }
154
179
  // Set up event listeners
155
180
  this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, (certData) => {
156
181
  console.log(`Certificate issued for ${certData.domain}, valid until ${certData.expiryDate.toISOString()}`);
182
+ // Re-emit on SmartProxy
183
+ this.emit('certificate', {
184
+ domain: certData.domain,
185
+ publicKey: certData.certificate,
186
+ privateKey: certData.privateKey,
187
+ expiryDate: certData.expiryDate,
188
+ source: 'http01',
189
+ isRenewal: false
190
+ });
157
191
  });
158
192
  this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, (certData) => {
159
193
  console.log(`Certificate renewed for ${certData.domain}, valid until ${certData.expiryDate.toISOString()}`);
194
+ // Re-emit on SmartProxy
195
+ this.emit('certificate', {
196
+ domain: certData.domain,
197
+ publicKey: certData.certificate,
198
+ privateKey: certData.privateKey,
199
+ expiryDate: certData.expiryDate,
200
+ source: 'http01',
201
+ isRenewal: true
202
+ });
160
203
  });
161
204
  this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, (failureData) => {
162
205
  console.log(`Certificate ${failureData.isRenewal ? 'renewal' : 'issuance'} failed for ${failureData.domain}: ${failureData.error}`);
@@ -340,21 +383,43 @@ export class SmartProxy {
340
383
  if (this.networkProxyBridge.getNetworkProxy()) {
341
384
  await this.networkProxyBridge.syncDomainConfigsToNetworkProxy();
342
385
  }
343
- // If Port80Handler is running, register non-wildcard domains
386
+ // If Port80Handler is running, provision certificates per new domain
344
387
  if (this.port80Handler && this.settings.port80HandlerConfig?.enabled) {
345
388
  for (const domainConfig of newDomainConfigs) {
346
389
  for (const domain of domainConfig.domains) {
347
- // Skip wildcards
348
390
  if (domain.includes('*'))
349
391
  continue;
350
- this.port80Handler.addDomain({
351
- domainName: domain,
352
- sslRedirect: true,
353
- acmeMaintenance: true
354
- });
392
+ let provision = 'http01';
393
+ if (this.settings.certProvider) {
394
+ try {
395
+ provision = await this.settings.certProvider(domain);
396
+ }
397
+ catch (err) {
398
+ console.log(`certProvider error for ${domain}: ${err}`);
399
+ }
400
+ }
401
+ if (provision === 'http01') {
402
+ this.port80Handler.addDomain({
403
+ domainName: domain,
404
+ sslRedirect: true,
405
+ acmeMaintenance: true
406
+ });
407
+ console.log(`Registered domain ${domain} with Port80Handler for HTTP-01`);
408
+ }
409
+ else {
410
+ const certObj = provision;
411
+ const certData = {
412
+ domain: certObj.domainName,
413
+ certificate: certObj.publicKey,
414
+ privateKey: certObj.privateKey,
415
+ expiryDate: new Date(certObj.validUntil)
416
+ };
417
+ this.networkProxyBridge.applyExternalCertificate(certData);
418
+ console.log(`Applied static certificate for ${domain} from certProvider`);
419
+ }
355
420
  }
356
421
  }
357
- console.log('Registered non-wildcard domains with Port80Handler');
422
+ console.log('Provisioned certificates for new domains');
358
423
  }
359
424
  }
360
425
  /**
@@ -564,4 +629,4 @@ export class SmartProxy {
564
629
  };
565
630
  }
566
631
  }
567
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydHByb3h5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc21hcnRwcm94eS9jbGFzc2VzLnNtYXJ0cHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN4RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDaEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDcEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQy9GLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBRXpCOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFrQnJCLFlBQVksV0FBK0I7UUFqQm5DLGVBQVUsR0FBeUIsRUFBRSxDQUFDO1FBQ3RDLHFCQUFnQixHQUEwQixJQUFJLENBQUM7UUFDL0MsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFZeEMsZ0RBQWdEO1FBQ3hDLGtCQUFhLEdBQXlCLElBQUksQ0FBQztRQUdqRCwyQ0FBMkM7UUFDM0MsSUFBSSxDQUFDLFFBQVEsR0FBRztZQUNkLEdBQUcsV0FBVztZQUNkLFFBQVEsRUFBRSxX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
632
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydHByb3h5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc21hcnRwcm94eS9jbGFzc2VzLnNtYXJ0cHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN4RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDaEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDcEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBeUIsTUFBTSwyQ0FBMkMsQ0FBQztBQUN0SCxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUV6Qjs7R0FFRztBQUNILE1BQU0sT0FBTyxVQUFXLFNBQVEsT0FBTyxDQUFDLFlBQVk7SUFrQmxELFlBQVksV0FBK0I7UUFDekMsS0FBSyxFQUFFLENBQUM7UUFsQkYsZUFBVSxHQUF5QixFQUFFLENBQUM7UUFDdEMscUJBQWdCLEdBQTBCLElBQUksQ0FBQztRQUMvQyxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQVl4QyxnREFBZ0Q7UUFDeEMsa0JBQWEsR0FBeUIsSUFBSSxDQUFDO1FBSWpELDJDQUEyQztRQUMzQyxJQUFJLENBQUMs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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartproxy",
3
- "version": "7.1.1",
3
+ "version": "7.2.0",
4
4
  "private": false,
5
5
  "description": "A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.",
6
6
  "main": "dist_ts/index.js",
@@ -9,23 +9,24 @@
9
9
  "author": "Lossless GmbH",
10
10
  "license": "MIT",
11
11
  "devDependencies": {
12
- "@git.zone/tsbuild": "^2.2.6",
12
+ "@git.zone/tsbuild": "^2.3.2",
13
13
  "@git.zone/tsrun": "^1.2.44",
14
14
  "@git.zone/tstest": "^1.0.77",
15
- "@push.rocks/tapbundle": "^5.5.10",
16
- "@types/node": "^22.13.10",
17
- "typescript": "^5.8.2"
15
+ "@push.rocks/tapbundle": "^6.0.3",
16
+ "@types/node": "^22.15.3",
17
+ "typescript": "^5.8.3"
18
18
  },
19
19
  "dependencies": {
20
- "@push.rocks/lik": "^6.1.0",
20
+ "@push.rocks/lik": "^6.2.2",
21
+ "@push.rocks/smartacme": "^7.2.3",
21
22
  "@push.rocks/smartdelay": "^3.0.5",
23
+ "@push.rocks/smartnetwork": "^4.0.0",
22
24
  "@push.rocks/smartpromise": "^4.2.3",
23
- "@push.rocks/smartrequest": "^2.0.23",
25
+ "@push.rocks/smartrequest": "^2.1.0",
24
26
  "@push.rocks/smartstring": "^4.0.15",
25
- "@tsclass/tsclass": "^5.0.0",
27
+ "@tsclass/tsclass": "^9.1.0",
26
28
  "@types/minimatch": "^5.1.2",
27
- "@types/ws": "^8.18.0",
28
- "acme-client": "^5.4.0",
29
+ "@types/ws": "^8.18.1",
29
30
  "minimatch": "^10.0.1",
30
31
  "pretty-ms": "^9.2.0",
31
32
  "ws": "^8.18.1"
package/readme.hints.md CHANGED
@@ -1 +1,64 @@
1
-
1
+ # SmartProxy Project Hints
2
+
3
+ ## Project Overview
4
+ - Package: `@push.rocks/smartproxy` – high-performance proxy supporting HTTP(S), TCP, WebSocket, and ACME integration.
5
+ - Written in TypeScript, compiled output in `dist_ts/`, uses ESM with NodeNext resolution.
6
+
7
+ ## Repository Structure
8
+ - `ts/` – TypeScript source files:
9
+ - `index.ts` exports main modules.
10
+ - `plugins.ts` centralizes native and third-party imports.
11
+ - Subdirectories: `networkproxy/`, `nftablesproxy/`, `port80handler/`, `redirect/`, `smartproxy/`.
12
+ - Key classes: `ProxyRouter` (`classes.router.ts`), `SmartProxy` (`classes.smartproxy.ts`), plus handlers/managers.
13
+ - `dist_ts/` – transpiled `.js` and `.d.ts` files mirroring `ts/` structure.
14
+ - `test/` – test suites in TypeScript:
15
+ - `test.router.ts` – routing logic (hostname matching, wildcards, path parameters, config management).
16
+ - `test.smartproxy.ts` – proxy behavior tests (TCP forwarding, SNI handling, concurrency, chaining, timeouts).
17
+ - `test/helpers/` – utilities (e.g., certificates).
18
+ - `assets/certs/` – placeholder certificates for ACME and TLS.
19
+
20
+ ## Development Setup
21
+ - Requires `pnpm` (v10+).
22
+ - Install dependencies: `pnpm install`.
23
+ - Build: `pnpm build` (runs `tsbuild --web --allowimplicitany`).
24
+ - Test: `pnpm test` (runs `tstest test/`).
25
+ - Format: `pnpm format` (runs `gitzone format`).
26
+
27
+ ## Testing Framework
28
+ - Uses `@push.rocks/tapbundle` (`tap`, `expect`, `expactAsync`).
29
+ - Test files: must start with `test.` and use `.ts` extension.
30
+ - Run specific tests via `tsx`, e.g., `tsx test/test.router.ts`.
31
+
32
+ ## Coding Conventions
33
+ - Import modules via `plugins.ts`:
34
+ ```ts
35
+ import * as plugins from './plugins.ts';
36
+ const server = new plugins.http.Server();
37
+ ```
38
+ - Reference plugins with full path: `plugins.acme`, `plugins.smartdelay`, `plugins.minimatch`, etc.
39
+ - Path patterns support globs (`*`) and parameters (`:param`) in `ProxyRouter`.
40
+ - Wildcard hostname matching leverages `minimatch` patterns.
41
+
42
+ ## Key Components
43
+ - **ProxyRouter**
44
+ - Methods: `routeReq`, `routeReqWithDetails`.
45
+ - Hostname matching: case-insensitive, strips port, supports exact, wildcard, TLD, complex patterns.
46
+ - Path routing: exact, wildcard, parameter extraction (`pathParams`), returns `pathMatch` and `pathRemainder`.
47
+ - Config API: `setNewProxyConfigs`, `addProxyConfig`, `removeProxyConfig`, `getHostnames`, `getProxyConfigs`.
48
+ - **SmartProxy**
49
+ - Manages one or more `net.Server` instances to forward TCP streams.
50
+ - Options: `preserveSourceIP`, `defaultAllowedIPs`, `globalPortRanges`, `sniEnabled`.
51
+ - DomainConfigManager: round-robin selection for multiple target IPs.
52
+ - Graceful shutdown in `stop()`, ensures no lingering servers or sockets.
53
+
54
+ ## Notable Points
55
+ - **TSConfig**: `module: NodeNext`, `verbatimModuleSyntax`, allows `.js` extension imports in TS.
56
+ - Mermaid diagrams and architecture flows in `readme.md` illustrate component interactions and protocol flows.
57
+ - CLI entrypoint (`cli.js`) supports command-line usage (ACME, proxy controls).
58
+ - ACME and certificate handling via `Port80Handler` and `helpers.certificates.ts`.
59
+
60
+ ## TODOs / Considerations
61
+ - Ensure import extensions in source match build outputs (`.ts` vs `.js`).
62
+ - Update `plugins.ts` when adding new dependencies.
63
+ - Maintain test coverage for new routing or proxy features.
64
+ - Keep `ts/` and `dist_ts/` in sync after refactors.
package/readme.md CHANGED
@@ -199,6 +199,50 @@ sequenceDiagram
199
199
  - **IP Filtering** - Control access with IP allow/block lists using glob patterns
200
200
  - **NfTables Integration** - Direct manipulation of nftables for advanced low-level port forwarding
201
201
 
202
+ ## Certificate Provider Hook & Events
203
+
204
+ You can customize how certificates are provisioned per domain by using the `certProvider` callback and listen for certificate events emitted by `SmartProxy`.
205
+
206
+ ```typescript
207
+ import { SmartProxy } from '@push.rocks/smartproxy';
208
+ import * as fs from 'fs';
209
+
210
+ // Example certProvider: static for a specific domain, HTTP-01 otherwise
211
+ const certProvider = async (domain: string) => {
212
+ if (domain === 'static.example.com') {
213
+ // Load from disk or vault
214
+ return {
215
+ id: 'static-cert',
216
+ domainName: domain,
217
+ created: Date.now(),
218
+ validUntil: Date.now() + 90 * 24 * 60 * 60 * 1000,
219
+ privateKey: fs.readFileSync('/etc/ssl/private/static.key', 'utf8'),
220
+ publicKey: fs.readFileSync('/etc/ssl/certs/static.crt', 'utf8'),
221
+ csr: ''
222
+ };
223
+ }
224
+ // Fallback to ACME HTTP-01 challenge
225
+ return 'http01';
226
+ };
227
+
228
+ const proxy = new SmartProxy({
229
+ fromPort: 80,
230
+ toPort: 8080,
231
+ domainConfigs: [{
232
+ domains: ['static.example.com', 'dynamic.example.com'],
233
+ allowedIPs: ['*']
234
+ }],
235
+ certProvider
236
+ });
237
+
238
+ // Listen for certificate issuance or renewal
239
+ proxy.on('certificate', (evt) => {
240
+ console.log(`Certificate for ${evt.domain} ready, expires on ${evt.expiryDate}`);
241
+ });
242
+
243
+ await proxy.start();
244
+ ```
245
+
202
246
  ## Configuration Options
203
247
 
204
248
  ### backendProtocol
package/readme.plan.md ADDED
@@ -0,0 +1,31 @@
1
+ ## Plan: Integrate @push.rocks/smartacme into Port80Handler
2
+
3
+ - [x] read the complete README of @push.rocks/smartacme and understand the API.
4
+ - [x] Add imports to ts/plugins.ts:
5
+ - import * as smartacme from '@push.rocks/smartacme';
6
+ - export { smartacme };
7
+ - [x] In Port80Handler.start():
8
+ - Instantiate SmartAcme and use the in memory certmanager.
9
+ - use the DisklessHttp01Handler implemented in classes.port80handler.ts
10
+ - Call `await smartAcme.start()` before binding HTTP server.
11
+ - [x] Replace old ACME flow in `obtainCertificate()` to use `await smartAcme.getCertificateForDomain(domain)` and process returned cert object. Remove old code.
12
+ - [x] Update `handleRequest()` to let DisklessHttp01Handler serve challenges.
13
+ - [x] Remove legacy methods: `getAcmeClient()`, `handleAcmeChallenge()`, `processAuthorizations()`, and related token bookkeeping in domainInfo.
14
+
15
+ ## Plan: Certificate Provider Hook & Observable Emission
16
+
17
+ - [x] Extend IPortProxySettings (ts/smartproxy/classes.pp.interfaces.ts):
18
+ - Define type ISmartProxyCertProvisionObject = tsclass.network.ICert | 'http01'`.
19
+ - Add optional `certProvider?: (domain: string) => Promise<ISmartProxyCertProvisionObject>`.
20
+ - [x] Enhance SmartProxy (ts/smartproxy/classes.smartproxy.ts):
21
+ - Import `EventEmitter` and change class signature to `export class SmartProxy extends EventEmitter`.
22
+ - Call `super()` in constructor.
23
+ - In `initializePort80Handler` and `updateDomainConfigs`, for each non-wildcard domain:
24
+ - Invoke `certProvider(domain)` if provided, defaulting to `'http01'`.
25
+ - If result is `'http01'`, register domain with `Port80Handler` for ACME challenges.
26
+ - If static cert returned, bypass `Port80Handler`, apply via `NetworkProxyBridge`
27
+ - Subscribe to `Port80HandlerEvents.CERTIFICATE_ISSUED` and `CERTIFICATE_RENEWED` and re-emit on `SmartProxy` as `'certificate'` events (include `domain`, `publicKey`, `privateKey`, `expiryDate`, `source: 'http01'`, `isRenewal` flag).
28
+ - [x] Extend NetworkProxyBridge (ts/smartproxy/classes.pp.networkproxybridge.ts):
29
+ - Add public method `applyExternalCertificate(data: ICertificateData): void` to forward static certs into `NetworkProxy`.
30
+ - [ ] Define `SmartProxy` `'certificate'` event interface in TypeScript and update documentation.
31
+ - [ ] Update README with usage examples showing `certProvider` callback and listening for `'certificate'` events.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartproxy',
6
- version: '7.1.1',
6
+ version: '7.2.0',
7
7
  description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
8
8
  }
@@ -12,6 +12,10 @@ import { Port80Handler } from '../port80handler/classes.port80handler.js';
12
12
  * automatic certificate management, and high-performance connection pooling.
13
13
  */
14
14
  export class NetworkProxy implements IMetricsTracker {
15
+ // Provide a minimal JSON representation to avoid circular references during deep equality checks
16
+ public toJSON(): any {
17
+ return {};
18
+ }
15
19
  // Configuration
16
20
  public options: INetworkProxyOptions;
17
21
  public proxyConfigs: IReverseProxyConfig[] = [];
@@ -132,23 +132,32 @@ export class RequestHandler {
132
132
 
133
133
  // Apply default headers
134
134
  this.applyDefaultHeaders(res);
135
- // If configured to proxy to backends over HTTP/2, use HTTP/2 client sessions
136
- if (this.options.backendProtocol === 'http2') {
137
- // Route and validate config
138
- const proxyConfig = this.router.routeReq(req);
139
- if (!proxyConfig) {
140
- this.logger.warn(`No proxy configuration for host: ${req.headers.host}`);
141
- res.statusCode = 404;
142
- res.end('Not Found: No proxy configuration for this host');
143
- if (this.metricsTracker) this.metricsTracker.incrementFailedRequests();
144
- return;
145
- }
146
- // Determine backend target
135
+
136
+ // Determine routing configuration
137
+ let proxyConfig: IReverseProxyConfig | undefined;
138
+ try {
139
+ proxyConfig = this.router.routeReq(req);
140
+ } catch (err) {
141
+ this.logger.error('Error routing request', err);
142
+ res.statusCode = 500;
143
+ res.end('Internal Server Error');
144
+ if (this.metricsTracker) this.metricsTracker.incrementFailedRequests();
145
+ return;
146
+ }
147
+ if (!proxyConfig) {
148
+ this.logger.warn(`No proxy configuration for host: ${req.headers.host}`);
149
+ res.statusCode = 404;
150
+ res.end('Not Found: No proxy configuration for this host');
151
+ if (this.metricsTracker) this.metricsTracker.incrementFailedRequests();
152
+ return;
153
+ }
154
+ // Determine protocol to backend (per-domain override or global)
155
+ const backendProto = proxyConfig.backendProtocol || this.options.backendProtocol;
156
+ if (backendProto === 'http2') {
147
157
  const destination = this.connectionPool.getNextTarget(
148
158
  proxyConfig.destinationIps,
149
159
  proxyConfig.destinationPorts[0]
150
160
  );
151
- // Obtain or create HTTP/2 session
152
161
  const key = `${destination.host}:${destination.port}`;
153
162
  let session = this.h2Sessions.get(key);
154
163
  if (!session || session.closed || (session as any).destroyed) {
@@ -158,40 +167,30 @@ export class RequestHandler {
158
167
  session.on('close', () => this.h2Sessions.delete(key));
159
168
  }
160
169
  // Build headers for HTTP/2 request
161
- const h2Headers: Record<string, string> = {
162
- ':method': req.method || 'GET',
163
- ':path': req.url || '/',
170
+ const hdrs: Record<string, any> = {
171
+ ':method': req.method,
172
+ ':path': req.url,
164
173
  ':authority': `${destination.host}:${destination.port}`
165
174
  };
166
- for (const [k, v] of Object.entries(req.headers)) {
167
- if (typeof v === 'string' && !k.startsWith(':')) {
168
- h2Headers[k] = v;
169
- }
175
+ for (const [hk, hv] of Object.entries(req.headers)) {
176
+ if (typeof hv === 'string') hdrs[hk] = hv;
170
177
  }
171
- // Open HTTP/2 stream
172
- const h2Stream = session.request(h2Headers);
173
- // Pipe client request body to backend
178
+ const h2Stream = session.request(hdrs);
174
179
  req.pipe(h2Stream);
175
- // Handle backend response
176
- h2Stream.on('response', (headers, flags) => {
177
- const status = headers[':status'] as number || 502;
178
- // Map headers
179
- for (const [hk, hv] of Object.entries(headers)) {
180
- if (!hk.startsWith(':') && hv) {
181
- res.setHeader(hk, hv as string);
180
+ h2Stream.on('response', (hdrs2: any) => {
181
+ const status = (hdrs2[':status'] as number) || 502;
182
+ res.statusCode = status;
183
+ // Copy headers from HTTP/2 response to HTTP/1 response
184
+ for (const [hk, hv] of Object.entries(hdrs2)) {
185
+ if (!hk.startsWith(':') && hv != null) {
186
+ res.setHeader(hk, hv as string | string[]);
182
187
  }
183
188
  }
184
- res.statusCode = status;
185
189
  h2Stream.pipe(res);
186
190
  });
187
191
  h2Stream.on('error', (err) => {
188
- this.logger.error(`HTTP/2 proxy error: ${err.message}`);
189
- if (!res.headersSent) {
190
- res.statusCode = 502;
191
- res.end(`Bad Gateway: ${err.message}`);
192
- } else {
193
- res.end();
194
- }
192
+ res.statusCode = 502;
193
+ res.end(`Bad Gateway: ${err.message}`);
195
194
  if (this.metricsTracker) this.metricsTracker.incrementFailedRequests();
196
195
  });
197
196
  return;
@@ -60,6 +60,11 @@ export interface IReverseProxyConfig {
60
60
  pass: string;
61
61
  };
62
62
  rewriteHostHeader?: boolean;
63
+ /**
64
+ * Protocol to use when proxying to this backend: 'http1' or 'http2'.
65
+ * Overrides the global backendProtocol option if set.
66
+ */
67
+ backendProtocol?: 'http1' | 'http2';
63
68
  }
64
69
 
65
70
  /**
package/ts/plugins.ts CHANGED
@@ -22,13 +22,15 @@ import * as smartpromise from '@push.rocks/smartpromise';
22
22
  import * as smartrequest from '@push.rocks/smartrequest';
23
23
  import * as smartstring from '@push.rocks/smartstring';
24
24
 
25
- export { lik, smartdelay, smartrequest, smartpromise, smartstring };
25
+ import * as smartacme from '@push.rocks/smartacme';
26
+ import * as smartacmePlugins from '@push.rocks/smartacme/dist_ts/smartacme.plugins.js';
27
+ import * as smartacmeHandlers from '@push.rocks/smartacme/dist_ts/handlers/index.js';
28
+ export { lik, smartdelay, smartrequest, smartpromise, smartstring, smartacme, smartacmePlugins, smartacmeHandlers };
26
29
 
27
30
  // third party scope
28
- import * as acme from 'acme-client';
29
31
  import prettyMs from 'pretty-ms';
30
32
  import * as ws from 'ws';
31
33
  import wsDefault from 'ws';
32
34
  import { minimatch } from 'minimatch';
33
35
 
34
- export { acme, prettyMs, ws, wsDefault, minimatch };
36
+ export { prettyMs, ws, wsDefault, minimatch };