@push.rocks/smartproxy 12.0.0 → 13.1.2
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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/certificate/acme/acme-factory.d.ts +17 -0
- package/dist_ts/certificate/acme/acme-factory.js +40 -0
- package/dist_ts/certificate/acme/challenge-handler.d.ts +44 -0
- package/dist_ts/certificate/acme/challenge-handler.js +92 -0
- package/dist_ts/certificate/acme/index.d.ts +4 -0
- package/dist_ts/certificate/acme/index.js +5 -0
- package/dist_ts/certificate/events/certificate-events.d.ts +33 -0
- package/dist_ts/certificate/events/certificate-events.js +38 -0
- package/dist_ts/certificate/index.d.ts +24 -0
- package/dist_ts/certificate/index.js +39 -0
- package/dist_ts/certificate/models/certificate-types.d.ts +77 -0
- package/dist_ts/certificate/models/certificate-types.js +2 -0
- package/dist_ts/certificate/providers/cert-provisioner.d.ts +93 -0
- package/dist_ts/certificate/providers/cert-provisioner.js +262 -0
- package/dist_ts/certificate/providers/index.d.ts +4 -0
- package/dist_ts/certificate/providers/index.js +5 -0
- package/dist_ts/certificate/storage/file-storage.d.ts +66 -0
- package/dist_ts/certificate/storage/file-storage.js +194 -0
- package/dist_ts/certificate/storage/index.d.ts +4 -0
- package/dist_ts/certificate/storage/index.js +5 -0
- package/dist_ts/certificate/utils/certificate-helpers.d.ts +17 -0
- package/dist_ts/certificate/utils/certificate-helpers.js +45 -0
- package/dist_ts/common/eventUtils.d.ts +1 -1
- package/dist_ts/common/port80-adapter.d.ts +1 -1
- package/dist_ts/core/events/index.d.ts +4 -0
- package/dist_ts/core/events/index.js +5 -0
- package/dist_ts/core/index.d.ts +6 -0
- package/dist_ts/core/index.js +8 -0
- package/dist_ts/core/models/common-types.d.ts +82 -0
- package/dist_ts/core/models/common-types.js +15 -0
- package/dist_ts/core/models/index.d.ts +4 -0
- package/dist_ts/core/models/index.js +5 -0
- package/dist_ts/core/utils/event-utils.d.ts +15 -0
- package/dist_ts/core/utils/event-utils.js +19 -0
- package/dist_ts/core/utils/index.d.ts +6 -0
- package/dist_ts/core/utils/index.js +7 -0
- package/dist_ts/core/utils/ip-utils.d.ts +53 -0
- package/dist_ts/core/utils/ip-utils.js +153 -0
- package/dist_ts/core/utils/validation-utils.d.ts +61 -0
- package/dist_ts/core/utils/validation-utils.js +149 -0
- package/dist_ts/forwarding/config/domain-config.d.ts +12 -0
- package/dist_ts/forwarding/config/domain-config.js +12 -0
- package/dist_ts/forwarding/config/domain-manager.d.ts +86 -0
- package/dist_ts/forwarding/config/domain-manager.js +242 -0
- package/dist_ts/forwarding/config/forwarding-types.d.ts +104 -0
- package/dist_ts/forwarding/config/forwarding-types.js +50 -0
- package/dist_ts/forwarding/config/index.d.ts +6 -0
- package/dist_ts/forwarding/config/index.js +7 -0
- package/dist_ts/forwarding/factory/forwarding-factory.d.ts +25 -0
- package/dist_ts/forwarding/factory/forwarding-factory.js +138 -0
- package/dist_ts/forwarding/factory/index.d.ts +4 -0
- package/dist_ts/forwarding/factory/index.js +5 -0
- package/dist_ts/forwarding/handlers/base-handler.d.ts +55 -0
- package/dist_ts/forwarding/handlers/base-handler.js +94 -0
- package/dist_ts/forwarding/handlers/http-handler.d.ts +30 -0
- package/dist_ts/forwarding/handlers/http-handler.js +131 -0
- package/dist_ts/forwarding/handlers/https-passthrough-handler.d.ts +29 -0
- package/dist_ts/forwarding/handlers/https-passthrough-handler.js +162 -0
- package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.d.ts +36 -0
- package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.js +229 -0
- package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.d.ts +35 -0
- package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.js +254 -0
- package/dist_ts/forwarding/handlers/index.d.ts +8 -0
- package/dist_ts/forwarding/handlers/index.js +9 -0
- package/dist_ts/forwarding/index.d.ts +19 -0
- package/dist_ts/forwarding/index.js +25 -0
- package/dist_ts/http/index.d.ts +15 -0
- package/dist_ts/http/index.js +20 -0
- package/dist_ts/http/models/http-types.d.ts +81 -0
- package/dist_ts/http/models/http-types.js +62 -0
- package/dist_ts/http/port80/acme-interfaces.d.ts +78 -0
- package/dist_ts/http/port80/acme-interfaces.js +6 -0
- package/dist_ts/http/port80/challenge-responder.d.ts +53 -0
- package/dist_ts/http/port80/challenge-responder.js +203 -0
- package/dist_ts/http/port80/index.d.ts +6 -0
- package/dist_ts/http/port80/index.js +9 -0
- package/dist_ts/http/port80/port80-handler.d.ts +121 -0
- package/dist_ts/http/port80/port80-handler.js +554 -0
- package/dist_ts/http/redirects/index.d.ts +4 -0
- package/dist_ts/http/redirects/index.js +5 -0
- package/dist_ts/http/router/index.d.ts +4 -0
- package/dist_ts/http/router/index.js +5 -0
- package/dist_ts/http/router/proxy-router.d.ts +115 -0
- package/dist_ts/http/router/proxy-router.js +325 -0
- package/dist_ts/index.d.ts +15 -8
- package/dist_ts/index.js +26 -10
- package/dist_ts/networkproxy/classes.np.certificatemanager.js +2 -2
- package/dist_ts/networkproxy/index.d.ts +1 -6
- package/dist_ts/networkproxy/index.js +4 -8
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/dist_ts/port80handler/classes.port80handler.d.ts +8 -136
- package/dist_ts/port80handler/classes.port80handler.js +14 -567
- package/dist_ts/proxies/index.d.ts +6 -0
- package/dist_ts/proxies/index.js +8 -0
- package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +77 -0
- package/dist_ts/proxies/network-proxy/certificate-manager.js +373 -0
- package/dist_ts/proxies/network-proxy/connection-pool.d.ts +47 -0
- package/dist_ts/proxies/network-proxy/connection-pool.js +210 -0
- package/dist_ts/proxies/network-proxy/index.d.ts +10 -0
- package/dist_ts/proxies/network-proxy/index.js +12 -0
- package/dist_ts/proxies/network-proxy/models/index.d.ts +4 -0
- package/dist_ts/proxies/network-proxy/models/index.js +5 -0
- package/dist_ts/proxies/network-proxy/models/types.d.ts +80 -0
- package/dist_ts/proxies/network-proxy/models/types.js +35 -0
- package/dist_ts/proxies/network-proxy/network-proxy.d.ts +118 -0
- package/dist_ts/proxies/network-proxy/network-proxy.js +387 -0
- package/dist_ts/proxies/network-proxy/request-handler.d.ts +57 -0
- package/dist_ts/proxies/network-proxy/request-handler.js +394 -0
- package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +38 -0
- package/dist_ts/proxies/network-proxy/websocket-handler.js +188 -0
- package/dist_ts/proxies/nftables-proxy/index.d.ts +5 -0
- package/dist_ts/proxies/nftables-proxy/index.js +6 -0
- package/dist_ts/proxies/nftables-proxy/models/errors.d.ts +15 -0
- package/dist_ts/proxies/nftables-proxy/models/errors.js +28 -0
- package/dist_ts/proxies/nftables-proxy/models/index.d.ts +5 -0
- package/dist_ts/proxies/nftables-proxy/models/index.js +6 -0
- package/dist_ts/proxies/nftables-proxy/models/interfaces.d.ts +75 -0
- package/dist_ts/proxies/nftables-proxy/models/interfaces.js +5 -0
- package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +136 -0
- package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +1516 -0
- package/dist_ts/proxies/smart-proxy/connection-handler.d.ts +39 -0
- package/dist_ts/proxies/smart-proxy/connection-handler.js +894 -0
- package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +78 -0
- package/dist_ts/proxies/smart-proxy/connection-manager.js +378 -0
- package/dist_ts/proxies/smart-proxy/domain-config-manager.d.ts +95 -0
- package/dist_ts/proxies/smart-proxy/domain-config-manager.js +255 -0
- package/dist_ts/proxies/smart-proxy/index.d.ts +13 -0
- package/dist_ts/proxies/smart-proxy/index.js +17 -0
- package/dist_ts/proxies/smart-proxy/models/index.d.ts +4 -0
- package/dist_ts/proxies/smart-proxy/models/index.js +5 -0
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +107 -0
- package/dist_ts/proxies/smart-proxy/models/interfaces.js +2 -0
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +62 -0
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +316 -0
- package/dist_ts/proxies/smart-proxy/port-range-manager.d.ts +56 -0
- package/dist_ts/proxies/smart-proxy/port-range-manager.js +176 -0
- package/dist_ts/proxies/smart-proxy/security-manager.d.ts +64 -0
- package/dist_ts/proxies/smart-proxy/security-manager.js +149 -0
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +63 -0
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +523 -0
- package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +47 -0
- package/dist_ts/proxies/smart-proxy/timeout-manager.js +154 -0
- package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +57 -0
- package/dist_ts/proxies/smart-proxy/tls-manager.js +132 -0
- package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +2 -2
- package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +1 -1
- package/dist_ts/smartproxy/classes.pp.tlsmanager.js +2 -2
- package/dist_ts/smartproxy/classes.smartproxy.js +3 -3
- package/dist_ts/tls/alerts/index.d.ts +4 -0
- package/dist_ts/tls/alerts/index.js +5 -0
- package/dist_ts/tls/alerts/tls-alert.d.ts +150 -0
- package/dist_ts/tls/alerts/tls-alert.js +226 -0
- package/dist_ts/tls/index.d.ts +18 -0
- package/dist_ts/tls/index.js +27 -0
- package/dist_ts/tls/sni/client-hello-parser.d.ts +100 -0
- package/dist_ts/tls/sni/client-hello-parser.js +463 -0
- package/dist_ts/tls/sni/index.d.ts +4 -0
- package/dist_ts/tls/sni/index.js +5 -0
- package/dist_ts/tls/sni/sni-extraction.d.ts +58 -0
- package/dist_ts/tls/sni/sni-extraction.js +275 -0
- package/dist_ts/tls/sni/sni-handler.d.ts +154 -0
- package/dist_ts/tls/sni/sni-handler.js +191 -0
- package/dist_ts/tls/utils/index.d.ts +4 -0
- package/dist_ts/tls/utils/index.js +5 -0
- package/dist_ts/tls/utils/tls-utils.d.ts +158 -0
- package/dist_ts/tls/utils/tls-utils.js +187 -0
- package/package.json +1 -1
- package/readme.md +89 -21
- package/readme.plan.md +253 -469
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/certificate/acme/acme-factory.ts +48 -0
- package/ts/certificate/acme/challenge-handler.ts +110 -0
- package/ts/certificate/acme/index.ts +3 -0
- package/ts/certificate/events/certificate-events.ts +36 -0
- package/ts/certificate/index.ts +67 -0
- package/ts/certificate/models/certificate-types.ts +88 -0
- package/ts/certificate/providers/cert-provisioner.ts +326 -0
- package/ts/certificate/providers/index.ts +3 -0
- package/ts/certificate/storage/file-storage.ts +234 -0
- package/ts/certificate/storage/index.ts +3 -0
- package/ts/certificate/utils/certificate-helpers.ts +50 -0
- package/ts/common/eventUtils.ts +1 -1
- package/ts/common/port80-adapter.ts +1 -1
- package/ts/core/events/index.ts +3 -0
- package/ts/core/index.ts +8 -0
- package/ts/core/models/common-types.ts +91 -0
- package/ts/core/models/index.ts +5 -0
- package/ts/core/utils/event-utils.ts +34 -0
- package/ts/core/utils/index.ts +7 -0
- package/ts/core/utils/ip-utils.ts +175 -0
- package/ts/core/utils/validation-utils.ts +177 -0
- package/ts/{smartproxy/forwarding → forwarding/config}/domain-config.ts +1 -1
- package/ts/{smartproxy/forwarding → forwarding/config}/domain-manager.ts +8 -8
- package/ts/{smartproxy/types/forwarding.types.ts → forwarding/config/forwarding-types.ts} +6 -6
- package/ts/forwarding/config/index.ts +7 -0
- package/ts/{smartproxy/forwarding/forwarding.factory.ts → forwarding/factory/forwarding-factory.ts} +12 -11
- package/ts/forwarding/factory/index.ts +5 -0
- package/ts/{smartproxy/forwarding/forwarding.handler.ts → forwarding/handlers/base-handler.ts} +2 -2
- package/ts/{smartproxy/forwarding/http.handler.ts → forwarding/handlers/http-handler.ts} +13 -4
- package/ts/{smartproxy/forwarding/https-passthrough.handler.ts → forwarding/handlers/https-passthrough-handler.ts} +13 -4
- package/ts/{smartproxy/forwarding/https-terminate-to-http.handler.ts → forwarding/handlers/https-terminate-to-http-handler.ts} +3 -3
- package/ts/{smartproxy/forwarding/https-terminate-to-https.handler.ts → forwarding/handlers/https-terminate-to-https-handler.ts} +3 -3
- package/ts/forwarding/handlers/index.ts +9 -0
- package/ts/forwarding/index.ts +34 -0
- package/ts/http/index.ts +23 -0
- package/ts/http/models/http-types.ts +105 -0
- package/ts/http/port80/acme-interfaces.ts +85 -0
- package/ts/http/port80/challenge-responder.ts +246 -0
- package/ts/http/port80/index.ts +13 -0
- package/ts/{port80handler/classes.port80handler.ts → http/port80/port80-handler.ts} +164 -161
- package/ts/http/redirects/index.ts +3 -0
- package/ts/http/router/index.ts +5 -0
- package/ts/{classes.router.ts → http/router/proxy-router.ts} +27 -20
- package/ts/index.ts +32 -9
- package/ts/plugins.ts +2 -1
- package/ts/proxies/index.ts +8 -0
- package/ts/{networkproxy/classes.np.certificatemanager.ts → proxies/network-proxy/certificate-manager.ts} +17 -16
- package/ts/{networkproxy/classes.np.connectionpool.ts → proxies/network-proxy/connection-pool.ts} +3 -3
- package/ts/proxies/network-proxy/index.ts +13 -0
- package/ts/proxies/network-proxy/models/index.ts +4 -0
- package/ts/{networkproxy/classes.np.types.ts → proxies/network-proxy/models/types.ts} +7 -11
- package/ts/{networkproxy/classes.np.networkproxy.ts → proxies/network-proxy/network-proxy.ts} +31 -24
- package/ts/{networkproxy/classes.np.requesthandler.ts → proxies/network-proxy/request-handler.ts} +12 -7
- package/ts/{networkproxy/classes.np.websockethandler.ts → proxies/network-proxy/websocket-handler.ts} +6 -6
- package/ts/proxies/nftables-proxy/index.ts +5 -0
- package/ts/proxies/nftables-proxy/models/errors.ts +30 -0
- package/ts/proxies/nftables-proxy/models/index.ts +5 -0
- package/ts/proxies/nftables-proxy/models/interfaces.ts +94 -0
- package/ts/{nfttablesproxy/classes.nftablesproxy.ts → proxies/nftables-proxy/nftables-proxy.ts} +24 -126
- package/ts/{smartproxy/classes.pp.connectionhandler.ts → proxies/smart-proxy/connection-handler.ts} +12 -12
- package/ts/{smartproxy/classes.pp.connectionmanager.ts → proxies/smart-proxy/connection-manager.ts} +8 -8
- package/ts/{smartproxy/classes.pp.domainconfigmanager.ts → proxies/smart-proxy/domain-config-manager.ts} +15 -14
- package/ts/proxies/smart-proxy/index.ts +18 -0
- package/ts/proxies/smart-proxy/models/index.ts +4 -0
- package/ts/{smartproxy/classes.pp.interfaces.ts → proxies/smart-proxy/models/interfaces.ts} +12 -8
- package/ts/{smartproxy/classes.pp.networkproxybridge.ts → proxies/smart-proxy/network-proxy-bridge.ts} +14 -14
- package/ts/{smartproxy/classes.pp.portrangemanager.ts → proxies/smart-proxy/port-range-manager.ts} +1 -1
- package/ts/{smartproxy/classes.pp.securitymanager.ts → proxies/smart-proxy/security-manager.ts} +3 -3
- package/ts/{smartproxy/classes.smartproxy.ts → proxies/smart-proxy/smart-proxy.ts} +29 -24
- package/ts/{smartproxy/classes.pp.timeoutmanager.ts → proxies/smart-proxy/timeout-manager.ts} +3 -3
- package/ts/{smartproxy/classes.pp.tlsmanager.ts → proxies/smart-proxy/tls-manager.ts} +3 -3
- package/ts/tls/alerts/index.ts +3 -0
- package/ts/{smartproxy/classes.pp.tlsalert.ts → tls/alerts/tls-alert.ts} +44 -43
- package/ts/tls/index.ts +33 -0
- package/ts/tls/sni/client-hello-parser.ts +629 -0
- package/ts/tls/sni/index.ts +3 -0
- package/ts/tls/sni/sni-extraction.ts +353 -0
- package/ts/tls/sni/sni-handler.ts +264 -0
- package/ts/tls/utils/index.ts +3 -0
- package/ts/tls/utils/tls-utils.ts +201 -0
- package/ts/common/acmeFactory.ts +0 -23
- package/ts/helpers.certificates.ts +0 -30
- package/ts/networkproxy/index.ts +0 -7
- package/ts/smartproxy/classes.pp.certprovisioner.ts +0 -200
- package/ts/smartproxy/classes.pp.snihandler.ts +0 -1281
- package/ts/smartproxy/forwarding/index.ts +0 -52
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import { createLogger } from './models/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Manages a pool of backend connections for efficient reuse
|
|
5
|
+
*/
|
|
6
|
+
export class ConnectionPool {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.options = options;
|
|
9
|
+
this.connectionPool = new Map();
|
|
10
|
+
this.roundRobinPositions = new Map();
|
|
11
|
+
this.logger = createLogger(options.logLevel || 'info');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get a connection from the pool or create a new one
|
|
15
|
+
*/
|
|
16
|
+
getConnection(host, port) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const poolKey = `${host}:${port}`;
|
|
19
|
+
const connectionList = this.connectionPool.get(poolKey) || [];
|
|
20
|
+
// Look for an idle connection
|
|
21
|
+
const idleConnectionIndex = connectionList.findIndex(c => c.isIdle);
|
|
22
|
+
if (idleConnectionIndex >= 0) {
|
|
23
|
+
// Get existing connection from pool
|
|
24
|
+
const connection = connectionList[idleConnectionIndex];
|
|
25
|
+
connection.isIdle = false;
|
|
26
|
+
connection.lastUsed = Date.now();
|
|
27
|
+
this.logger.debug(`Reusing connection from pool for ${poolKey}`);
|
|
28
|
+
// Update the pool
|
|
29
|
+
this.connectionPool.set(poolKey, connectionList);
|
|
30
|
+
resolve(connection.socket);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// No idle connection available, create a new one if pool isn't full
|
|
34
|
+
const poolSize = this.options.connectionPoolSize || 50;
|
|
35
|
+
if (connectionList.length < poolSize) {
|
|
36
|
+
this.logger.debug(`Creating new connection to ${host}:${port}`);
|
|
37
|
+
try {
|
|
38
|
+
const socket = plugins.net.connect({
|
|
39
|
+
host,
|
|
40
|
+
port,
|
|
41
|
+
keepAlive: true,
|
|
42
|
+
keepAliveInitialDelay: 30000 // 30 seconds
|
|
43
|
+
});
|
|
44
|
+
socket.once('connect', () => {
|
|
45
|
+
// Add to connection pool
|
|
46
|
+
const connection = {
|
|
47
|
+
socket,
|
|
48
|
+
lastUsed: Date.now(),
|
|
49
|
+
isIdle: false
|
|
50
|
+
};
|
|
51
|
+
connectionList.push(connection);
|
|
52
|
+
this.connectionPool.set(poolKey, connectionList);
|
|
53
|
+
// Setup cleanup when the connection is closed
|
|
54
|
+
socket.once('close', () => {
|
|
55
|
+
const idx = connectionList.findIndex(c => c.socket === socket);
|
|
56
|
+
if (idx >= 0) {
|
|
57
|
+
connectionList.splice(idx, 1);
|
|
58
|
+
this.connectionPool.set(poolKey, connectionList);
|
|
59
|
+
this.logger.debug(`Removed closed connection from pool for ${poolKey}`);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
resolve(socket);
|
|
63
|
+
});
|
|
64
|
+
socket.once('error', (err) => {
|
|
65
|
+
this.logger.error(`Error creating connection to ${host}:${port}`, err);
|
|
66
|
+
reject(err);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
this.logger.error(`Failed to create connection to ${host}:${port}`, err);
|
|
71
|
+
reject(err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// Pool is full, wait for an idle connection or reject
|
|
76
|
+
this.logger.warn(`Connection pool for ${poolKey} is full (${connectionList.length})`);
|
|
77
|
+
reject(new Error(`Connection pool for ${poolKey} is full`));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Return a connection to the pool for reuse
|
|
83
|
+
*/
|
|
84
|
+
returnConnection(socket, host, port) {
|
|
85
|
+
const poolKey = `${host}:${port}`;
|
|
86
|
+
const connectionList = this.connectionPool.get(poolKey) || [];
|
|
87
|
+
// Find this connection in the pool
|
|
88
|
+
const connectionIndex = connectionList.findIndex(c => c.socket === socket);
|
|
89
|
+
if (connectionIndex >= 0) {
|
|
90
|
+
// Mark as idle and update last used time
|
|
91
|
+
connectionList[connectionIndex].isIdle = true;
|
|
92
|
+
connectionList[connectionIndex].lastUsed = Date.now();
|
|
93
|
+
this.logger.debug(`Returned connection to pool for ${poolKey}`);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.logger.warn(`Attempted to return unknown connection to pool for ${poolKey}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Cleanup the connection pool by removing idle connections
|
|
101
|
+
* or reducing pool size if it exceeds the configured maximum
|
|
102
|
+
*/
|
|
103
|
+
cleanupConnectionPool() {
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
const idleTimeout = this.options.keepAliveTimeout || 120000; // 2 minutes default
|
|
106
|
+
for (const [host, connections] of this.connectionPool.entries()) {
|
|
107
|
+
// Sort by last used time (oldest first)
|
|
108
|
+
connections.sort((a, b) => a.lastUsed - b.lastUsed);
|
|
109
|
+
// Remove idle connections older than the idle timeout
|
|
110
|
+
let removed = 0;
|
|
111
|
+
while (connections.length > 0) {
|
|
112
|
+
const connection = connections[0];
|
|
113
|
+
// Remove if idle and exceeds timeout, or if pool is too large
|
|
114
|
+
if ((connection.isIdle && now - connection.lastUsed > idleTimeout) ||
|
|
115
|
+
connections.length > (this.options.connectionPoolSize || 50)) {
|
|
116
|
+
try {
|
|
117
|
+
if (!connection.socket.destroyed) {
|
|
118
|
+
connection.socket.end();
|
|
119
|
+
connection.socket.destroy();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
this.logger.error(`Error destroying pooled connection to ${host}`, err);
|
|
124
|
+
}
|
|
125
|
+
connections.shift(); // Remove from pool
|
|
126
|
+
removed++;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
break; // Stop removing if we've reached active or recent connections
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (removed > 0) {
|
|
133
|
+
this.logger.debug(`Removed ${removed} idle connections from pool for ${host}, ${connections.length} remaining`);
|
|
134
|
+
}
|
|
135
|
+
// Update the pool with the remaining connections
|
|
136
|
+
if (connections.length === 0) {
|
|
137
|
+
this.connectionPool.delete(host);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.connectionPool.set(host, connections);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Close all connections in the pool
|
|
146
|
+
*/
|
|
147
|
+
closeAllConnections() {
|
|
148
|
+
for (const [host, connections] of this.connectionPool.entries()) {
|
|
149
|
+
this.logger.debug(`Closing ${connections.length} connections to ${host}`);
|
|
150
|
+
for (const connection of connections) {
|
|
151
|
+
try {
|
|
152
|
+
if (!connection.socket.destroyed) {
|
|
153
|
+
connection.socket.end();
|
|
154
|
+
connection.socket.destroy();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
this.logger.error(`Error closing connection to ${host}:`, error);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
this.connectionPool.clear();
|
|
163
|
+
this.roundRobinPositions.clear();
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get load balancing target using round-robin
|
|
167
|
+
*/
|
|
168
|
+
getNextTarget(targets, port) {
|
|
169
|
+
const targetKey = targets.join(',');
|
|
170
|
+
// Initialize position if not exists
|
|
171
|
+
if (!this.roundRobinPositions.has(targetKey)) {
|
|
172
|
+
this.roundRobinPositions.set(targetKey, 0);
|
|
173
|
+
}
|
|
174
|
+
// Get current position and increment for next time
|
|
175
|
+
const currentPosition = this.roundRobinPositions.get(targetKey);
|
|
176
|
+
const nextPosition = (currentPosition + 1) % targets.length;
|
|
177
|
+
this.roundRobinPositions.set(targetKey, nextPosition);
|
|
178
|
+
// Return the selected target
|
|
179
|
+
return {
|
|
180
|
+
host: targets[currentPosition],
|
|
181
|
+
port
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Gets the connection pool status
|
|
186
|
+
*/
|
|
187
|
+
getPoolStatus() {
|
|
188
|
+
return Object.fromEntries(Array.from(this.connectionPool.entries()).map(([host, connections]) => [
|
|
189
|
+
host,
|
|
190
|
+
{
|
|
191
|
+
total: connections.length,
|
|
192
|
+
idle: connections.filter(c => c.isIdle).length
|
|
193
|
+
}
|
|
194
|
+
]));
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Setup a periodic cleanup task
|
|
198
|
+
*/
|
|
199
|
+
setupPeriodicCleanup(interval = 60000) {
|
|
200
|
+
const timer = setInterval(() => {
|
|
201
|
+
this.cleanupConnectionPool();
|
|
202
|
+
}, interval);
|
|
203
|
+
// Don't prevent process exit
|
|
204
|
+
if (timer.unref) {
|
|
205
|
+
timer.unref();
|
|
206
|
+
}
|
|
207
|
+
return timer;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdGlvbi1wb29sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcHJveGllcy9uZXR3b3JrLXByb3h5L2Nvbm5lY3Rpb24tcG9vbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBa0UsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFakg7O0dBRUc7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUt6QixZQUFvQixPQUE2QjtRQUE3QixZQUFPLEdBQVAsT0FBTyxDQUFzQjtRQUp6QyxtQkFBYyxHQUF5QyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2pFLHdCQUFtQixHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBSTNELElBQUksQ0FBQyxNQUFNLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksTUFBTSxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksYUFBYSxDQUFDLElBQVksRUFBRSxJQUFZO1FBQzdDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckMsTUFBTSxPQUFPLEdBQUcsR0FBRyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7WUFDbEMsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1lBRTlELDhCQUE4QjtZQUM5QixNQUFNLG1CQUFtQixHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFcEUsSUFBSSxtQkFBbUIsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDN0Isb0NBQW9DO2dCQUNwQyxNQUFNLFVBQVUsR0FBRyxjQUFjLENBQUMsbUJBQW1CLENBQUMsQ0FBQztnQkFDdkQsVUFB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
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NetworkProxy implementation
|
|
3
|
+
*/
|
|
4
|
+
export * from './models/index.js';
|
|
5
|
+
export { NetworkProxy } from './network-proxy.js';
|
|
6
|
+
export { CertificateManager } from './certificate-manager.js';
|
|
7
|
+
export { ConnectionPool } from './connection-pool.js';
|
|
8
|
+
export { RequestHandler } from './request-handler.js';
|
|
9
|
+
export type { IMetricsTracker, MetricsTracker } from './request-handler.js';
|
|
10
|
+
export { WebSocketHandler } from './websocket-handler.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NetworkProxy implementation
|
|
3
|
+
*/
|
|
4
|
+
// Re-export models
|
|
5
|
+
export * from './models/index.js';
|
|
6
|
+
// Export NetworkProxy and supporting classes
|
|
7
|
+
export { NetworkProxy } from './network-proxy.js';
|
|
8
|
+
export { CertificateManager } from './certificate-manager.js';
|
|
9
|
+
export { ConnectionPool } from './connection-pool.js';
|
|
10
|
+
export { RequestHandler } from './request-handler.js';
|
|
11
|
+
export { WebSocketHandler } from './websocket-handler.js';
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9wcm94aWVzL25ldHdvcmstcHJveHkvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxtQkFBbUI7QUFDbkIsY0FBYyxtQkFBbUIsQ0FBQztBQUVsQyw2Q0FBNkM7QUFDN0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzlELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFdEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUMifQ==
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NetworkProxy models
|
|
3
|
+
*/
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9wcm94aWVzL25ldHdvcmstcHJveHkvbW9kZWxzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsY0FBYyxZQUFZLENBQUMifQ==
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as plugins from '../../../plugins.js';
|
|
2
|
+
import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for NetworkProxy
|
|
5
|
+
*/
|
|
6
|
+
export interface INetworkProxyOptions {
|
|
7
|
+
port: number;
|
|
8
|
+
maxConnections?: number;
|
|
9
|
+
keepAliveTimeout?: number;
|
|
10
|
+
headersTimeout?: number;
|
|
11
|
+
logLevel?: 'error' | 'warn' | 'info' | 'debug';
|
|
12
|
+
cors?: {
|
|
13
|
+
allowOrigin?: string;
|
|
14
|
+
allowMethods?: string;
|
|
15
|
+
allowHeaders?: string;
|
|
16
|
+
maxAge?: number;
|
|
17
|
+
};
|
|
18
|
+
connectionPoolSize?: number;
|
|
19
|
+
portProxyIntegration?: boolean;
|
|
20
|
+
useExternalPort80Handler?: boolean;
|
|
21
|
+
backendProtocol?: 'http1' | 'http2';
|
|
22
|
+
acme?: IAcmeOptions;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Interface for a certificate entry in the cache
|
|
26
|
+
*/
|
|
27
|
+
export interface ICertificateEntry {
|
|
28
|
+
key: string;
|
|
29
|
+
cert: string;
|
|
30
|
+
expires?: Date;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Interface for reverse proxy configuration
|
|
34
|
+
*/
|
|
35
|
+
export interface IReverseProxyConfig {
|
|
36
|
+
destinationIps: string[];
|
|
37
|
+
destinationPorts: number[];
|
|
38
|
+
hostName: string;
|
|
39
|
+
privateKey: string;
|
|
40
|
+
publicKey: string;
|
|
41
|
+
authentication?: {
|
|
42
|
+
type: 'Basic';
|
|
43
|
+
user: string;
|
|
44
|
+
pass: string;
|
|
45
|
+
};
|
|
46
|
+
rewriteHostHeader?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Protocol to use when proxying to this backend: 'http1' or 'http2'.
|
|
49
|
+
* Overrides the global backendProtocol option if set.
|
|
50
|
+
*/
|
|
51
|
+
backendProtocol?: 'http1' | 'http2';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Interface for connection tracking in the pool
|
|
55
|
+
*/
|
|
56
|
+
export interface IConnectionEntry {
|
|
57
|
+
socket: plugins.net.Socket;
|
|
58
|
+
lastUsed: number;
|
|
59
|
+
isIdle: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* WebSocket with heartbeat interface
|
|
63
|
+
*/
|
|
64
|
+
export interface IWebSocketWithHeartbeat extends plugins.wsDefault {
|
|
65
|
+
lastPong: number;
|
|
66
|
+
isAlive: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Logger interface for consistent logging across components
|
|
70
|
+
*/
|
|
71
|
+
export interface ILogger {
|
|
72
|
+
debug(message: string, data?: any): void;
|
|
73
|
+
info(message: string, data?: any): void;
|
|
74
|
+
warn(message: string, data?: any): void;
|
|
75
|
+
error(message: string, data?: any): void;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Creates a logger based on the specified log level
|
|
79
|
+
*/
|
|
80
|
+
export declare function createLogger(logLevel?: string): ILogger;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as plugins from '../../../plugins.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a logger based on the specified log level
|
|
4
|
+
*/
|
|
5
|
+
export function createLogger(logLevel = 'info') {
|
|
6
|
+
const logLevels = {
|
|
7
|
+
error: 0,
|
|
8
|
+
warn: 1,
|
|
9
|
+
info: 2,
|
|
10
|
+
debug: 3
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
debug: (message, data) => {
|
|
14
|
+
if (logLevels[logLevel] >= logLevels.debug) {
|
|
15
|
+
console.log(`[DEBUG] ${message}`, data || '');
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
info: (message, data) => {
|
|
19
|
+
if (logLevels[logLevel] >= logLevels.info) {
|
|
20
|
+
console.log(`[INFO] ${message}`, data || '');
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
warn: (message, data) => {
|
|
24
|
+
if (logLevels[logLevel] >= logLevels.warn) {
|
|
25
|
+
console.warn(`[WARN] ${message}`, data || '');
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
error: (message, data) => {
|
|
29
|
+
if (logLevels[logLevel] >= logLevels.error) {
|
|
30
|
+
console.error(`[ERROR] ${message}`, data || '');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9wcm94aWVzL25ldHdvcmstcHJveHkvbW9kZWxzL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUF3Ri9DOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxXQUFtQixNQUFNO0lBQ3BELE1BQU0sU0FBUyxHQUFHO1FBQ2hCLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxFQUFFLENBQUM7UUFDUCxJQUFJLEVBQUUsQ0FBQztRQUNQLEtBQUssRUFBRSxDQUFDO0tBQ1QsQ0FBQztJQUVGLE9BQU87UUFDTCxLQUFLLEVBQUUsQ0FBQyxPQUFlLEVBQUUsSUFBVSxFQUFFLEVBQUU7WUFDckMsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUMzQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ2hELENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxFQUFFLENBQUMsT0FBZSxFQUFFLElBQVUsRUFBRSxFQUFFO1lBQ3BDLElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDMUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztZQUMvQyxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksRUFBRSxDQUFDLE9BQWUsRUFBRSxJQUFVLEVBQUUsRUFBRTtZQUNwQyxJQUFJLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQzFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUM7UUFDRCxLQUFLLEVBQUUsQ0FBQyxPQUFlLEVBQUUsSUFBVSxFQUFFLEVBQUU7WUFDckMsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUMzQyxPQUFPLENBQUMsS0FBSyxDQUFDLFdBQVcsT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ2xELENBQUM7UUFDSCxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUMifQ==
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import type { INetworkProxyOptions, IReverseProxyConfig } from './models/types.js';
|
|
3
|
+
import { type IMetricsTracker } from './request-handler.js';
|
|
4
|
+
import { Port80Handler } from '../../http/port80/port80-handler.js';
|
|
5
|
+
/**
|
|
6
|
+
* NetworkProxy provides a reverse proxy with TLS termination, WebSocket support,
|
|
7
|
+
* automatic certificate management, and high-performance connection pooling.
|
|
8
|
+
*/
|
|
9
|
+
export declare class NetworkProxy implements IMetricsTracker {
|
|
10
|
+
toJSON(): any;
|
|
11
|
+
options: INetworkProxyOptions;
|
|
12
|
+
proxyConfigs: IReverseProxyConfig[];
|
|
13
|
+
httpsServer: any;
|
|
14
|
+
private certificateManager;
|
|
15
|
+
private connectionPool;
|
|
16
|
+
private requestHandler;
|
|
17
|
+
private webSocketHandler;
|
|
18
|
+
private router;
|
|
19
|
+
socketMap: plugins.lik.ObjectMap<plugins.net.Socket>;
|
|
20
|
+
activeContexts: Set<string>;
|
|
21
|
+
connectedClients: number;
|
|
22
|
+
startTime: number;
|
|
23
|
+
requestsServed: number;
|
|
24
|
+
failedRequests: number;
|
|
25
|
+
private portProxyConnections;
|
|
26
|
+
private tlsTerminatedConnections;
|
|
27
|
+
private metricsInterval;
|
|
28
|
+
private connectionPoolCleanupInterval;
|
|
29
|
+
private logger;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new NetworkProxy instance
|
|
32
|
+
*/
|
|
33
|
+
constructor(optionsArg: INetworkProxyOptions);
|
|
34
|
+
/**
|
|
35
|
+
* Implements IMetricsTracker interface to increment request counters
|
|
36
|
+
*/
|
|
37
|
+
incrementRequestsServed(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Implements IMetricsTracker interface to increment failed request counters
|
|
40
|
+
*/
|
|
41
|
+
incrementFailedRequests(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Returns the port number this NetworkProxy is listening on
|
|
44
|
+
* Useful for SmartProxy to determine where to forward connections
|
|
45
|
+
*/
|
|
46
|
+
getListeningPort(): number;
|
|
47
|
+
/**
|
|
48
|
+
* Updates the server capacity settings
|
|
49
|
+
* @param maxConnections Maximum number of simultaneous connections
|
|
50
|
+
* @param keepAliveTimeout Keep-alive timeout in milliseconds
|
|
51
|
+
* @param connectionPoolSize Size of the connection pool per backend
|
|
52
|
+
*/
|
|
53
|
+
updateCapacity(maxConnections?: number, keepAliveTimeout?: number, connectionPoolSize?: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* Returns current server metrics
|
|
56
|
+
* Useful for SmartProxy to determine which NetworkProxy to use for load balancing
|
|
57
|
+
*/
|
|
58
|
+
getMetrics(): any;
|
|
59
|
+
/**
|
|
60
|
+
* Sets an external Port80Handler for certificate management
|
|
61
|
+
* This allows the NetworkProxy to use a centrally managed Port80Handler
|
|
62
|
+
* instead of creating its own
|
|
63
|
+
*
|
|
64
|
+
* @param handler The Port80Handler instance to use
|
|
65
|
+
*/
|
|
66
|
+
setExternalPort80Handler(handler: Port80Handler): void;
|
|
67
|
+
/**
|
|
68
|
+
* Starts the proxy server
|
|
69
|
+
*/
|
|
70
|
+
start(): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Sets up tracking of TCP connections
|
|
73
|
+
*/
|
|
74
|
+
private setupConnectionTracking;
|
|
75
|
+
/**
|
|
76
|
+
* Sets up metrics collection
|
|
77
|
+
*/
|
|
78
|
+
private setupMetricsCollection;
|
|
79
|
+
/**
|
|
80
|
+
* Updates proxy configurations
|
|
81
|
+
*/
|
|
82
|
+
updateProxyConfigs(proxyConfigsArg: IReverseProxyConfig[]): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Converts SmartProxy domain configurations to NetworkProxy configs
|
|
85
|
+
* @param domainConfigs SmartProxy domain configs
|
|
86
|
+
* @param sslKeyPair Default SSL key pair to use if not specified
|
|
87
|
+
* @returns Array of NetworkProxy configs
|
|
88
|
+
*/
|
|
89
|
+
convertSmartProxyConfigs(domainConfigs: Array<{
|
|
90
|
+
domains: string[];
|
|
91
|
+
targetIPs?: string[];
|
|
92
|
+
allowedIPs?: string[];
|
|
93
|
+
}>, sslKeyPair?: {
|
|
94
|
+
key: string;
|
|
95
|
+
cert: string;
|
|
96
|
+
}): IReverseProxyConfig[];
|
|
97
|
+
/**
|
|
98
|
+
* Adds default headers to be included in all responses
|
|
99
|
+
*/
|
|
100
|
+
addDefaultHeaders(headersArg: {
|
|
101
|
+
[key: string]: string;
|
|
102
|
+
}): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Stops the proxy server
|
|
105
|
+
*/
|
|
106
|
+
stop(): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Requests a new certificate for a domain
|
|
109
|
+
* This can be used to manually trigger certificate issuance
|
|
110
|
+
* @param domain The domain to request a certificate for
|
|
111
|
+
* @returns A promise that resolves when the request is submitted (not when the certificate is issued)
|
|
112
|
+
*/
|
|
113
|
+
requestCertificate(domain: string): Promise<boolean>;
|
|
114
|
+
/**
|
|
115
|
+
* Gets all proxy configurations currently in use
|
|
116
|
+
*/
|
|
117
|
+
getProxyConfigs(): IReverseProxyConfig[];
|
|
118
|
+
}
|