@push.rocks/smartproxy 10.2.0 → 12.0.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 (59) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/common/port80-adapter.d.ts +11 -0
  3. package/dist_ts/common/port80-adapter.js +61 -0
  4. package/dist_ts/examples/forwarding-example.d.ts +1 -0
  5. package/dist_ts/examples/forwarding-example.js +96 -0
  6. package/dist_ts/index.d.ts +1 -0
  7. package/dist_ts/index.js +3 -1
  8. package/dist_ts/smartproxy/classes.pp.connectionhandler.js +179 -30
  9. package/dist_ts/smartproxy/classes.pp.domainconfigmanager.d.ts +39 -0
  10. package/dist_ts/smartproxy/classes.pp.domainconfigmanager.js +172 -20
  11. package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +3 -11
  12. package/dist_ts/smartproxy/classes.pp.portrangemanager.js +17 -10
  13. package/dist_ts/smartproxy/classes.pp.securitymanager.d.ts +19 -2
  14. package/dist_ts/smartproxy/classes.pp.securitymanager.js +27 -4
  15. package/dist_ts/smartproxy/classes.pp.timeoutmanager.js +3 -3
  16. package/dist_ts/smartproxy/classes.smartproxy.js +45 -13
  17. package/dist_ts/smartproxy/forwarding/domain-config.d.ts +12 -0
  18. package/dist_ts/smartproxy/forwarding/domain-config.js +12 -0
  19. package/dist_ts/smartproxy/forwarding/domain-manager.d.ts +86 -0
  20. package/dist_ts/smartproxy/forwarding/domain-manager.js +241 -0
  21. package/dist_ts/smartproxy/forwarding/forwarding.factory.d.ts +24 -0
  22. package/dist_ts/smartproxy/forwarding/forwarding.factory.js +137 -0
  23. package/dist_ts/smartproxy/forwarding/forwarding.handler.d.ts +55 -0
  24. package/dist_ts/smartproxy/forwarding/forwarding.handler.js +94 -0
  25. package/dist_ts/smartproxy/forwarding/http.handler.d.ts +25 -0
  26. package/dist_ts/smartproxy/forwarding/http.handler.js +123 -0
  27. package/dist_ts/smartproxy/forwarding/https-passthrough.handler.d.ts +24 -0
  28. package/dist_ts/smartproxy/forwarding/https-passthrough.handler.js +154 -0
  29. package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.d.ts +36 -0
  30. package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.js +229 -0
  31. package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.d.ts +35 -0
  32. package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.js +254 -0
  33. package/dist_ts/smartproxy/forwarding/index.d.ts +16 -0
  34. package/dist_ts/smartproxy/forwarding/index.js +23 -0
  35. package/dist_ts/smartproxy/types/forwarding.types.d.ts +104 -0
  36. package/dist_ts/smartproxy/types/forwarding.types.js +50 -0
  37. package/package.json +2 -2
  38. package/readme.md +158 -8
  39. package/readme.plan.md +471 -42
  40. package/ts/00_commitinfo_data.ts +1 -1
  41. package/ts/common/port80-adapter.ts +87 -0
  42. package/ts/index.ts +3 -0
  43. package/ts/smartproxy/classes.pp.connectionhandler.ts +231 -44
  44. package/ts/smartproxy/classes.pp.domainconfigmanager.ts +198 -24
  45. package/ts/smartproxy/classes.pp.interfaces.ts +3 -11
  46. package/ts/smartproxy/classes.pp.portrangemanager.ts +17 -10
  47. package/ts/smartproxy/classes.pp.securitymanager.ts +29 -5
  48. package/ts/smartproxy/classes.pp.timeoutmanager.ts +3 -3
  49. package/ts/smartproxy/classes.smartproxy.ts +68 -15
  50. package/ts/smartproxy/forwarding/domain-config.ts +28 -0
  51. package/ts/smartproxy/forwarding/domain-manager.ts +283 -0
  52. package/ts/smartproxy/forwarding/forwarding.factory.ts +155 -0
  53. package/ts/smartproxy/forwarding/forwarding.handler.ts +127 -0
  54. package/ts/smartproxy/forwarding/http.handler.ts +140 -0
  55. package/ts/smartproxy/forwarding/https-passthrough.handler.ts +182 -0
  56. package/ts/smartproxy/forwarding/https-terminate-to-http.handler.ts +264 -0
  57. package/ts/smartproxy/forwarding/https-terminate-to-https.handler.ts +292 -0
  58. package/ts/smartproxy/forwarding/index.ts +52 -0
  59. package/ts/smartproxy/types/forwarding.types.ts +162 -0
@@ -0,0 +1,36 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { ForwardingHandler } from './forwarding.handler.js';
3
+ import type { IForwardConfig } from '../types/forwarding.types.js';
4
+ /**
5
+ * Handler for HTTPS termination with HTTP backend
6
+ */
7
+ export declare class HttpsTerminateToHttpHandler extends ForwardingHandler {
8
+ private tlsServer;
9
+ private secureContext;
10
+ /**
11
+ * Create a new HTTPS termination with HTTP backend handler
12
+ * @param config The forwarding configuration
13
+ */
14
+ constructor(config: IForwardConfig);
15
+ /**
16
+ * Initialize the handler, setting up TLS context
17
+ */
18
+ initialize(): Promise<void>;
19
+ /**
20
+ * Set the secure context for TLS termination
21
+ * Called when a certificate is available
22
+ * @param context The secure context
23
+ */
24
+ setSecureContext(context: plugins.tls.SecureContext): void;
25
+ /**
26
+ * Handle a TLS/SSL socket connection by terminating TLS and forwarding to HTTP backend
27
+ * @param clientSocket The incoming socket from the client
28
+ */
29
+ handleConnection(clientSocket: plugins.net.Socket): void;
30
+ /**
31
+ * Handle an HTTP request by forwarding to the HTTP backend
32
+ * @param req The HTTP request
33
+ * @param res The HTTP response
34
+ */
35
+ handleHttpRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse): void;
36
+ }
@@ -0,0 +1,229 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { ForwardingHandler } from './forwarding.handler.js';
3
+ import { ForwardingHandlerEvents } from '../types/forwarding.types.js';
4
+ /**
5
+ * Handler for HTTPS termination with HTTP backend
6
+ */
7
+ export class HttpsTerminateToHttpHandler extends ForwardingHandler {
8
+ /**
9
+ * Create a new HTTPS termination with HTTP backend handler
10
+ * @param config The forwarding configuration
11
+ */
12
+ constructor(config) {
13
+ super(config);
14
+ this.tlsServer = null;
15
+ this.secureContext = null;
16
+ // Validate that this is an HTTPS terminate to HTTP configuration
17
+ if (config.type !== 'https-terminate-to-http') {
18
+ throw new Error(`Invalid configuration type for HttpsTerminateToHttpHandler: ${config.type}`);
19
+ }
20
+ }
21
+ /**
22
+ * Initialize the handler, setting up TLS context
23
+ */
24
+ async initialize() {
25
+ // We need to load or create TLS certificates
26
+ if (this.config.https?.customCert) {
27
+ // Use custom certificate from configuration
28
+ this.secureContext = plugins.tls.createSecureContext({
29
+ key: this.config.https.customCert.key,
30
+ cert: this.config.https.customCert.cert
31
+ });
32
+ this.emit(ForwardingHandlerEvents.CERTIFICATE_LOADED, {
33
+ source: 'config',
34
+ domain: this.config.target.host
35
+ });
36
+ }
37
+ else if (this.config.acme?.enabled) {
38
+ // Request certificate through ACME if needed
39
+ this.emit(ForwardingHandlerEvents.CERTIFICATE_NEEDED, {
40
+ domain: Array.isArray(this.config.target.host)
41
+ ? this.config.target.host[0]
42
+ : this.config.target.host,
43
+ useProduction: this.config.acme.production || false
44
+ });
45
+ // In a real implementation, we would wait for the certificate to be issued
46
+ // For now, we'll use a dummy context
47
+ this.secureContext = plugins.tls.createSecureContext({
48
+ key: '-----BEGIN PRIVATE KEY-----\nDummy key\n-----END PRIVATE KEY-----',
49
+ cert: '-----BEGIN CERTIFICATE-----\nDummy cert\n-----END CERTIFICATE-----'
50
+ });
51
+ }
52
+ else {
53
+ throw new Error('HTTPS termination requires either a custom certificate or ACME enabled');
54
+ }
55
+ }
56
+ /**
57
+ * Set the secure context for TLS termination
58
+ * Called when a certificate is available
59
+ * @param context The secure context
60
+ */
61
+ setSecureContext(context) {
62
+ this.secureContext = context;
63
+ }
64
+ /**
65
+ * Handle a TLS/SSL socket connection by terminating TLS and forwarding to HTTP backend
66
+ * @param clientSocket The incoming socket from the client
67
+ */
68
+ handleConnection(clientSocket) {
69
+ // Make sure we have a secure context
70
+ if (!this.secureContext) {
71
+ clientSocket.destroy(new Error('TLS secure context not initialized'));
72
+ return;
73
+ }
74
+ const remoteAddress = clientSocket.remoteAddress || 'unknown';
75
+ const remotePort = clientSocket.remotePort || 0;
76
+ // Create a TLS socket using our secure context
77
+ const tlsSocket = new plugins.tls.TLSSocket(clientSocket, {
78
+ secureContext: this.secureContext,
79
+ isServer: true,
80
+ server: this.tlsServer || undefined
81
+ });
82
+ this.emit(ForwardingHandlerEvents.CONNECTED, {
83
+ remoteAddress,
84
+ remotePort,
85
+ tls: true
86
+ });
87
+ // Handle TLS errors
88
+ tlsSocket.on('error', (error) => {
89
+ this.emit(ForwardingHandlerEvents.ERROR, {
90
+ remoteAddress,
91
+ error: `TLS error: ${error.message}`
92
+ });
93
+ if (!tlsSocket.destroyed) {
94
+ tlsSocket.destroy();
95
+ }
96
+ });
97
+ // The TLS socket will now emit HTTP traffic that can be processed
98
+ // In a real implementation, we would create an HTTP parser and handle
99
+ // the requests here, but for simplicity, we'll just log the data
100
+ let dataBuffer = Buffer.alloc(0);
101
+ tlsSocket.on('data', (data) => {
102
+ // Append to buffer
103
+ dataBuffer = Buffer.concat([dataBuffer, data]);
104
+ // Very basic HTTP parsing - in a real implementation, use http-parser
105
+ if (dataBuffer.includes(Buffer.from('\r\n\r\n'))) {
106
+ const target = this.getTargetFromConfig();
107
+ // Simple example: forward the data to an HTTP server
108
+ const socket = plugins.net.connect(target.port, target.host, () => {
109
+ socket.write(dataBuffer);
110
+ dataBuffer = Buffer.alloc(0);
111
+ // Set up bidirectional data flow
112
+ tlsSocket.pipe(socket);
113
+ socket.pipe(tlsSocket);
114
+ });
115
+ socket.on('error', (error) => {
116
+ this.emit(ForwardingHandlerEvents.ERROR, {
117
+ remoteAddress,
118
+ error: `Target connection error: ${error.message}`
119
+ });
120
+ if (!tlsSocket.destroyed) {
121
+ tlsSocket.destroy();
122
+ }
123
+ });
124
+ }
125
+ });
126
+ // Handle close
127
+ tlsSocket.on('close', () => {
128
+ this.emit(ForwardingHandlerEvents.DISCONNECTED, {
129
+ remoteAddress
130
+ });
131
+ });
132
+ // Set timeout
133
+ const timeout = this.getTimeout();
134
+ tlsSocket.setTimeout(timeout);
135
+ tlsSocket.on('timeout', () => {
136
+ this.emit(ForwardingHandlerEvents.ERROR, {
137
+ remoteAddress,
138
+ error: 'TLS connection timeout'
139
+ });
140
+ if (!tlsSocket.destroyed) {
141
+ tlsSocket.destroy();
142
+ }
143
+ });
144
+ }
145
+ /**
146
+ * Handle an HTTP request by forwarding to the HTTP backend
147
+ * @param req The HTTP request
148
+ * @param res The HTTP response
149
+ */
150
+ handleHttpRequest(req, res) {
151
+ // Check if we should redirect to HTTPS
152
+ if (this.config.http?.redirectToHttps) {
153
+ this.redirectToHttps(req, res);
154
+ return;
155
+ }
156
+ // Get the target from configuration
157
+ const target = this.getTargetFromConfig();
158
+ // Create custom headers with variable substitution
159
+ const variables = {
160
+ clientIp: req.socket.remoteAddress || 'unknown'
161
+ };
162
+ // Prepare headers, merging with any custom headers from config
163
+ const headers = this.applyCustomHeaders(req.headers, variables);
164
+ // Create the proxy request options
165
+ const options = {
166
+ hostname: target.host,
167
+ port: target.port,
168
+ path: req.url,
169
+ method: req.method,
170
+ headers
171
+ };
172
+ // Create the proxy request
173
+ const proxyReq = plugins.http.request(options, (proxyRes) => {
174
+ // Copy status code and headers from the proxied response
175
+ res.writeHead(proxyRes.statusCode || 500, proxyRes.headers);
176
+ // Pipe the proxy response to the client response
177
+ proxyRes.pipe(res);
178
+ // Track response size for logging
179
+ let responseSize = 0;
180
+ proxyRes.on('data', (chunk) => {
181
+ responseSize += chunk.length;
182
+ });
183
+ proxyRes.on('end', () => {
184
+ this.emit(ForwardingHandlerEvents.HTTP_RESPONSE, {
185
+ statusCode: proxyRes.statusCode,
186
+ headers: proxyRes.headers,
187
+ size: responseSize
188
+ });
189
+ });
190
+ });
191
+ // Handle errors in the proxy request
192
+ proxyReq.on('error', (error) => {
193
+ this.emit(ForwardingHandlerEvents.ERROR, {
194
+ remoteAddress: req.socket.remoteAddress,
195
+ error: `Proxy request error: ${error.message}`
196
+ });
197
+ // Send an error response if headers haven't been sent yet
198
+ if (!res.headersSent) {
199
+ res.writeHead(502, { 'Content-Type': 'text/plain' });
200
+ res.end(`Error forwarding request: ${error.message}`);
201
+ }
202
+ else {
203
+ // Just end the response if headers have already been sent
204
+ res.end();
205
+ }
206
+ });
207
+ // Track request details for logging
208
+ let requestSize = 0;
209
+ req.on('data', (chunk) => {
210
+ requestSize += chunk.length;
211
+ });
212
+ // Log the request
213
+ this.emit(ForwardingHandlerEvents.HTTP_REQUEST, {
214
+ method: req.method,
215
+ url: req.url,
216
+ headers: req.headers,
217
+ remoteAddress: req.socket.remoteAddress,
218
+ target: `${target.host}:${target.port}`
219
+ });
220
+ // Pipe the client request to the proxy request
221
+ if (req.readable) {
222
+ req.pipe(proxyReq);
223
+ }
224
+ else {
225
+ proxyReq.end();
226
+ }
227
+ }
228
+ }
229
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cHMtdGVybWluYXRlLXRvLWh0dHAuaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3NtYXJ0cHJveHkvZm9yd2FyZGluZy9odHRwcy10ZXJtaW5hdGUtdG8taHR0cC5oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFNUQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFdkU7O0dBRUc7QUFDSCxNQUFNLE9BQU8sMkJBQTRCLFNBQVEsaUJBQWlCO0lBSWhFOzs7T0FHRztJQUNILFlBQVksTUFBc0I7UUFDaEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBUlIsY0FBUyxHQUE4QixJQUFJLENBQUM7UUFDNUMsa0JBQWEsR0FBcUMsSUFBSSxDQUFDO1FBUzdELGlFQUFpRTtRQUNqRSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUsseUJBQXlCLEVBQUUsQ0FBQztZQUM5QyxNQUFNLElBQUksS0FBSyxDQUFDLCtEQUErRCxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRyxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFVBQVU7UUFDckIsNkNBQTZDO1FBQzdDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUM7WUFDbEMsNENBQTRDO1lBQzVDLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQztnQkFDbkQsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHO2dCQUNyQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFD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
@@ -0,0 +1,35 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { ForwardingHandler } from './forwarding.handler.js';
3
+ import type { IForwardConfig } from '../types/forwarding.types.js';
4
+ /**
5
+ * Handler for HTTPS termination with HTTPS backend
6
+ */
7
+ export declare class HttpsTerminateToHttpsHandler extends ForwardingHandler {
8
+ private secureContext;
9
+ /**
10
+ * Create a new HTTPS termination with HTTPS backend handler
11
+ * @param config The forwarding configuration
12
+ */
13
+ constructor(config: IForwardConfig);
14
+ /**
15
+ * Initialize the handler, setting up TLS context
16
+ */
17
+ initialize(): Promise<void>;
18
+ /**
19
+ * Set the secure context for TLS termination
20
+ * Called when a certificate is available
21
+ * @param context The secure context
22
+ */
23
+ setSecureContext(context: plugins.tls.SecureContext): void;
24
+ /**
25
+ * Handle a TLS/SSL socket connection by terminating TLS and creating a new TLS connection to backend
26
+ * @param clientSocket The incoming socket from the client
27
+ */
28
+ handleConnection(clientSocket: plugins.net.Socket): void;
29
+ /**
30
+ * Handle an HTTP request by forwarding to the HTTPS backend
31
+ * @param req The HTTP request
32
+ * @param res The HTTP response
33
+ */
34
+ handleHttpRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse): void;
35
+ }
@@ -0,0 +1,254 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { ForwardingHandler } from './forwarding.handler.js';
3
+ import { ForwardingHandlerEvents } from '../types/forwarding.types.js';
4
+ /**
5
+ * Handler for HTTPS termination with HTTPS backend
6
+ */
7
+ export class HttpsTerminateToHttpsHandler extends ForwardingHandler {
8
+ /**
9
+ * Create a new HTTPS termination with HTTPS backend handler
10
+ * @param config The forwarding configuration
11
+ */
12
+ constructor(config) {
13
+ super(config);
14
+ this.secureContext = null;
15
+ // Validate that this is an HTTPS terminate to HTTPS configuration
16
+ if (config.type !== 'https-terminate-to-https') {
17
+ throw new Error(`Invalid configuration type for HttpsTerminateToHttpsHandler: ${config.type}`);
18
+ }
19
+ }
20
+ /**
21
+ * Initialize the handler, setting up TLS context
22
+ */
23
+ async initialize() {
24
+ // We need to load or create TLS certificates for termination
25
+ if (this.config.https?.customCert) {
26
+ // Use custom certificate from configuration
27
+ this.secureContext = plugins.tls.createSecureContext({
28
+ key: this.config.https.customCert.key,
29
+ cert: this.config.https.customCert.cert
30
+ });
31
+ this.emit(ForwardingHandlerEvents.CERTIFICATE_LOADED, {
32
+ source: 'config',
33
+ domain: this.config.target.host
34
+ });
35
+ }
36
+ else if (this.config.acme?.enabled) {
37
+ // Request certificate through ACME if needed
38
+ this.emit(ForwardingHandlerEvents.CERTIFICATE_NEEDED, {
39
+ domain: Array.isArray(this.config.target.host)
40
+ ? this.config.target.host[0]
41
+ : this.config.target.host,
42
+ useProduction: this.config.acme.production || false
43
+ });
44
+ // In a real implementation, we would wait for the certificate to be issued
45
+ // For now, we'll use a dummy context
46
+ this.secureContext = plugins.tls.createSecureContext({
47
+ key: '-----BEGIN PRIVATE KEY-----\nDummy key\n-----END PRIVATE KEY-----',
48
+ cert: '-----BEGIN CERTIFICATE-----\nDummy cert\n-----END CERTIFICATE-----'
49
+ });
50
+ }
51
+ else {
52
+ throw new Error('HTTPS termination requires either a custom certificate or ACME enabled');
53
+ }
54
+ }
55
+ /**
56
+ * Set the secure context for TLS termination
57
+ * Called when a certificate is available
58
+ * @param context The secure context
59
+ */
60
+ setSecureContext(context) {
61
+ this.secureContext = context;
62
+ }
63
+ /**
64
+ * Handle a TLS/SSL socket connection by terminating TLS and creating a new TLS connection to backend
65
+ * @param clientSocket The incoming socket from the client
66
+ */
67
+ handleConnection(clientSocket) {
68
+ // Make sure we have a secure context
69
+ if (!this.secureContext) {
70
+ clientSocket.destroy(new Error('TLS secure context not initialized'));
71
+ return;
72
+ }
73
+ const remoteAddress = clientSocket.remoteAddress || 'unknown';
74
+ const remotePort = clientSocket.remotePort || 0;
75
+ // Create a TLS socket using our secure context
76
+ const tlsSocket = new plugins.tls.TLSSocket(clientSocket, {
77
+ secureContext: this.secureContext,
78
+ isServer: true
79
+ });
80
+ this.emit(ForwardingHandlerEvents.CONNECTED, {
81
+ remoteAddress,
82
+ remotePort,
83
+ tls: true
84
+ });
85
+ // Handle TLS errors
86
+ tlsSocket.on('error', (error) => {
87
+ this.emit(ForwardingHandlerEvents.ERROR, {
88
+ remoteAddress,
89
+ error: `TLS error: ${error.message}`
90
+ });
91
+ if (!tlsSocket.destroyed) {
92
+ tlsSocket.destroy();
93
+ }
94
+ });
95
+ // The TLS socket will now emit HTTP traffic that can be processed
96
+ // In a real implementation, we would create an HTTP parser and handle
97
+ // the requests here, but for simplicity, we'll just forward the data
98
+ // Get the target from configuration
99
+ const target = this.getTargetFromConfig();
100
+ // Set up the connection to the HTTPS backend
101
+ const connectToBackend = () => {
102
+ const backendSocket = plugins.tls.connect({
103
+ host: target.host,
104
+ port: target.port,
105
+ // In a real implementation, we would configure TLS options
106
+ rejectUnauthorized: false // For testing only, never use in production
107
+ }, () => {
108
+ this.emit(ForwardingHandlerEvents.DATA_FORWARDED, {
109
+ direction: 'outbound',
110
+ target: `${target.host}:${target.port}`,
111
+ tls: true
112
+ });
113
+ // Set up bidirectional data flow
114
+ tlsSocket.pipe(backendSocket);
115
+ backendSocket.pipe(tlsSocket);
116
+ });
117
+ backendSocket.on('error', (error) => {
118
+ this.emit(ForwardingHandlerEvents.ERROR, {
119
+ remoteAddress,
120
+ error: `Backend connection error: ${error.message}`
121
+ });
122
+ if (!tlsSocket.destroyed) {
123
+ tlsSocket.destroy();
124
+ }
125
+ });
126
+ // Handle close
127
+ backendSocket.on('close', () => {
128
+ if (!tlsSocket.destroyed) {
129
+ tlsSocket.destroy();
130
+ }
131
+ });
132
+ // Set timeout
133
+ const timeout = this.getTimeout();
134
+ backendSocket.setTimeout(timeout);
135
+ backendSocket.on('timeout', () => {
136
+ this.emit(ForwardingHandlerEvents.ERROR, {
137
+ remoteAddress,
138
+ error: 'Backend connection timeout'
139
+ });
140
+ if (!backendSocket.destroyed) {
141
+ backendSocket.destroy();
142
+ }
143
+ });
144
+ };
145
+ // Wait for the TLS handshake to complete before connecting to backend
146
+ tlsSocket.on('secure', () => {
147
+ connectToBackend();
148
+ });
149
+ // Handle close
150
+ tlsSocket.on('close', () => {
151
+ this.emit(ForwardingHandlerEvents.DISCONNECTED, {
152
+ remoteAddress
153
+ });
154
+ });
155
+ // Set timeout
156
+ const timeout = this.getTimeout();
157
+ tlsSocket.setTimeout(timeout);
158
+ tlsSocket.on('timeout', () => {
159
+ this.emit(ForwardingHandlerEvents.ERROR, {
160
+ remoteAddress,
161
+ error: 'TLS connection timeout'
162
+ });
163
+ if (!tlsSocket.destroyed) {
164
+ tlsSocket.destroy();
165
+ }
166
+ });
167
+ }
168
+ /**
169
+ * Handle an HTTP request by forwarding to the HTTPS backend
170
+ * @param req The HTTP request
171
+ * @param res The HTTP response
172
+ */
173
+ handleHttpRequest(req, res) {
174
+ // Check if we should redirect to HTTPS
175
+ if (this.config.http?.redirectToHttps) {
176
+ this.redirectToHttps(req, res);
177
+ return;
178
+ }
179
+ // Get the target from configuration
180
+ const target = this.getTargetFromConfig();
181
+ // Create custom headers with variable substitution
182
+ const variables = {
183
+ clientIp: req.socket.remoteAddress || 'unknown'
184
+ };
185
+ // Prepare headers, merging with any custom headers from config
186
+ const headers = this.applyCustomHeaders(req.headers, variables);
187
+ // Create the proxy request options
188
+ const options = {
189
+ hostname: target.host,
190
+ port: target.port,
191
+ path: req.url,
192
+ method: req.method,
193
+ headers,
194
+ // In a real implementation, we would configure TLS options
195
+ rejectUnauthorized: false // For testing only, never use in production
196
+ };
197
+ // Create the proxy request using HTTPS
198
+ const proxyReq = plugins.https.request(options, (proxyRes) => {
199
+ // Copy status code and headers from the proxied response
200
+ res.writeHead(proxyRes.statusCode || 500, proxyRes.headers);
201
+ // Pipe the proxy response to the client response
202
+ proxyRes.pipe(res);
203
+ // Track response size for logging
204
+ let responseSize = 0;
205
+ proxyRes.on('data', (chunk) => {
206
+ responseSize += chunk.length;
207
+ });
208
+ proxyRes.on('end', () => {
209
+ this.emit(ForwardingHandlerEvents.HTTP_RESPONSE, {
210
+ statusCode: proxyRes.statusCode,
211
+ headers: proxyRes.headers,
212
+ size: responseSize
213
+ });
214
+ });
215
+ });
216
+ // Handle errors in the proxy request
217
+ proxyReq.on('error', (error) => {
218
+ this.emit(ForwardingHandlerEvents.ERROR, {
219
+ remoteAddress: req.socket.remoteAddress,
220
+ error: `Proxy request error: ${error.message}`
221
+ });
222
+ // Send an error response if headers haven't been sent yet
223
+ if (!res.headersSent) {
224
+ res.writeHead(502, { 'Content-Type': 'text/plain' });
225
+ res.end(`Error forwarding request: ${error.message}`);
226
+ }
227
+ else {
228
+ // Just end the response if headers have already been sent
229
+ res.end();
230
+ }
231
+ });
232
+ // Track request details for logging
233
+ let requestSize = 0;
234
+ req.on('data', (chunk) => {
235
+ requestSize += chunk.length;
236
+ });
237
+ // Log the request
238
+ this.emit(ForwardingHandlerEvents.HTTP_REQUEST, {
239
+ method: req.method,
240
+ url: req.url,
241
+ headers: req.headers,
242
+ remoteAddress: req.socket.remoteAddress,
243
+ target: `${target.host}:${target.port}`
244
+ });
245
+ // Pipe the client request to the proxy request
246
+ if (req.readable) {
247
+ req.pipe(proxyReq);
248
+ }
249
+ else {
250
+ proxyReq.end();
251
+ }
252
+ }
253
+ }
254
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cHMtdGVybWluYXRlLXRvLWh0dHBzLmhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zbWFydHByb3h5L2ZvcndhcmRpbmcvaHR0cHMtdGVybWluYXRlLXRvLWh0dHBzLmhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUU1RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUV2RTs7R0FFRztBQUNILE1BQU0sT0FBTyw0QkFBNkIsU0FBUSxpQkFBaUI7SUFHakU7OztPQUdHO0lBQ0gsWUFBWSxNQUFzQjtRQUNoQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFQUixrQkFBYSxHQUFxQyxJQUFJLENBQUM7UUFTN0Qsa0VBQWtFO1FBQ2xFLElBQUksTUFBTSxDQUFDLElBQUksS0FBSywwQkFBMEIsRUFBRSxDQUFDO1lBQy9DLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsVUFBVTtRQUNyQiw2REFBNkQ7UUFDN0QsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztZQUNsQyw0Q0FBNEM7WUFDNUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDO2dCQUNuRCxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUc7Z0JBQ3JDLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSTthQUN4QyxDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGtCQUFrQixFQUFFO2dCQUNwRCxNQUFNLEVBQUUsUUFBUTtnQkFDaEIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUk7YUFDaEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDckMsNkNBQTZDO1lBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsa0JBQWtCLEVBQUU7Z0JBQ3BELE1BQU0sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztvQkFDNUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQzVCLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJO2dCQUMzQixhQUFhLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLEtBQUs7YUFDcEQsQ0FBQyxDQUFDO1lBRUgsMkVBQTJFO1lBQzNFLHFDQUFxQztZQUNyQyxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUM7Z0JBQ25ELEdBQUcsRUFBRSxtRUFBbUU7Z0JBQ3hFLElBQUksRUFBRSxvRUFBb0U7YUFDM0UsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLElBQUksS0FBSyxDQUFDLHdFQUF3RSxDQUFDLENBQUM7UUFDNUYsQ0FBQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksZ0JBQWdCLENBQUMsT0FBa0M7UUFDeEQsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7T0FHRztJQUNJLGdCQUFnQixDQUFDLFlBQWdDO1FBQ3RELHFDQUFxQztRQUNyQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3hCLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQyxDQUFDO1lBQ3RFLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDLGFBQWEsSUFBSSxTQUFTLENBQUM7UUFDOUQsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUM7UUFFaEQsK0NBQStDO1FBQy9DLE1BQU0sU0FBUyxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFO1lBQ3hELGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtZQUNqQyxRQUFRLEVBQUUsSUFBSTtTQUNmLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsU0FBUyxFQUFFO1lBQzNDLGFBQWE7WUFDYixVQUFVO1lBQ1YsR0FBRyxFQUFFLElBQUk7U0FDVixDQUFDLENBQUM7UUFFSCxvQkFBb0I7UUFDcEIsU0FBUyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssRUFBRTtnQkFDdkMsYUFBYTtnQkFDYixLQUFLLEVBQUUsY0FBYyxLQUFLLENBQUMsT0FBTyxFQUFFO2FBQ3JDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ3pCLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxrRUFBa0U7UUFDbEUsc0VBQXNFO1FBQ3RFLHFFQUFxRTtRQUVyRSxvQ0FBb0M7UUFDcEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFFMUMsNkNBQTZDO1FBQzdDLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxFQUFFO1lBQzVCLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDO2dCQUN4QyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7Z0JBQ2pCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtnQkFDakIsMkRBQTJEO2dCQUMzRCxrQkFBa0IsRUFBRSxLQUFLLENBQUMsNENBQTRDO2FBQ3ZFLEVBQUUsR0FBRyxFQUFFO2dCQUNOLElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsY0FBYyxFQUFFO29CQUNoRCxTQUFTLEVBQUUsVUFBVTtvQkFDckIsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFO29CQUN2QyxHQUFHLEVBQUUsSUFBSTtpQkFDVixDQUFDLENBQUM7Z0JBRUgsaUNBQWlDO2dCQUNqQyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUM5QixhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2hDLENBQUMsQ0FBQyxDQUFDO1lBRUgsYUFBYSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLEVBQUU7b0JBQ3ZDLGFBQWE7b0JBQ2IsS0FBSyxFQUFFLDZCQUE2QixLQUFLLENBQUMsT0FBTyxFQUFFO2lCQUNwRCxDQUFDLENBQUM7Z0JBRUgsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztvQkFDekIsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN0QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFFSCxlQUFlO1lBQ2YsYUFBYSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO2dCQUM3QixJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDO29CQUN6QixTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3RCLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztZQUVILGNBQWM7WUFDZCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVsQyxhQUFhLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7Z0JBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxFQUFFO29CQUN2QyxhQUFhO29CQUNiLEtBQUssRUFBRSw0QkFBNEI7aUJBQ3BDLENBQUMsQ0FBQztnQkFFSCxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO29CQUM3QixhQUFhLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzFCLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGLHNFQUFzRTtRQUN0RSxTQUFTLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUU7WUFDMUIsZ0JBQWdCLEVBQUUsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztRQUVILGVBQWU7UUFDZixTQUFTLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7WUFDekIsSUFBSSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUU7Z0JBQzlDLGFBQWE7YUFDZCxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILGNBQWM7UUFDZCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUU5QixTQUFTLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7WUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLEVBQUU7Z0JBQ3ZDLGFBQWE7Z0JBQ2IsS0FBSyxFQUFFLHdCQUF3QjthQUNoQyxDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUN6QixTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdEIsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxpQkFBaUIsQ0FBQyxHQUFpQyxFQUFFLEdBQWdDO1FBQzFGLHVDQUF1QztRQUN2QyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLE9BQU87UUFDVCxDQUFDO1FBRUQsb0NBQW9DO1FBQ3BDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBRTFDLG1EQUFtRDtRQUNuRCxNQUFNLFNBQVMsR0FBRztZQUNoQixRQUFRLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLElBQUksU0FBUztTQUNoRCxDQUFDO1FBRUYsK0RBQStEO1FBQy9ELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRWhFLG1DQUFtQztRQUNuQyxNQUFNLE9BQU8sR0FBRztZQUNkLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSTtZQUNyQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7WUFDakIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHO1lBQ2IsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNO1lBQ2xCLE9BQU87WUFDUCwyREFBMkQ7WUFDM0Qsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLDRDQUE0QztTQUN2RSxDQUFDO1FBRUYsdUNBQXVDO1FBQ3ZDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQzNELHlEQUF5RDtZQUN6RCxHQUFHLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxVQUFVLElBQUksR0FBRyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUU1RCxpREFBaUQ7WUFDakQsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVuQixrQ0FBa0M7WUFDbEMsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLFFBQVEsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQzVCLFlBQVksSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQy9CLENBQUMsQ0FBQyxDQUFDO1lBRUgsUUFBUSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFO2dCQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGFBQWEsRUFBRTtvQkFDL0MsVUFBVSxFQUFFLFFBQVEsQ0FBQyxVQUFVO29CQUMvQixPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87b0JBQ3pCLElBQUksRUFBRSxZQUFZO2lCQUNuQixDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgscUNBQXFDO1FBQ3JDLFFBQVEsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLEVBQUU7Z0JBQ3ZDLGFBQWEsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLGFBQWE7Z0JBQ3ZDLEtBQUssRUFBRSx3QkFBd0IsS0FBSyxDQUFDLE9BQU8sRUFBRTthQUMvQyxDQUFDLENBQUM7WUFFSCwwREFBMEQ7WUFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDckIsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztnQkFDckQsR0FBRyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDeEQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLDBEQUEwRDtnQkFDMUQsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1osQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsb0NBQW9DO1FBQ3BDLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNwQixHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3ZCLFdBQVcsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO1FBRUgsa0JBQWtCO1FBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsWUFBWSxFQUFFO1lBQzlDLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTTtZQUNsQixHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUc7WUFDWixPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU87WUFDcEIsYUFBYSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsYUFBYTtZQUN2QyxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUU7U0FDeEMsQ0FBQyxDQUFDO1FBRUgsK0NBQStDO1FBQy9DLElBQUksR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2pCLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckIsQ0FBQzthQUFNLENBQUM7WUFDTixRQUFRLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDakIsQ0FBQztJQUNILENBQUM7Q0FDRiJ9
@@ -0,0 +1,16 @@
1
+ export type { ForwardingType, IForwardConfig, IForwardingHandler, ITargetConfig, IHttpOptions, IHttpsOptions, IAcmeForwardingOptions, ISecurityOptions, IAdvancedOptions } from '../types/forwarding.types.js';
2
+ export { ForwardingHandlerEvents, httpOnly, tlsTerminateToHttp, tlsTerminateToHttps, httpsPassthrough } from '../types/forwarding.types.js';
3
+ export * from './domain-config.js';
4
+ export { ForwardingHandler } from './forwarding.handler.js';
5
+ export { HttpForwardingHandler } from './http.handler.js';
6
+ export { HttpsPassthroughHandler } from './https-passthrough.handler.js';
7
+ export { HttpsTerminateToHttpHandler } from './https-terminate-to-http.handler.js';
8
+ export { HttpsTerminateToHttpsHandler } from './https-terminate-to-https.handler.js';
9
+ export { ForwardingHandlerFactory } from './forwarding.factory.js';
10
+ export { DomainManager, DomainManagerEvents } from './domain-manager.js';
11
+ export declare const helpers: {
12
+ httpOnly: (partialConfig: Partial<import("../types/forwarding.types.js").IForwardConfig> & Pick<import("../types/forwarding.types.js").IForwardConfig, "target">) => import("../types/forwarding.types.js").IForwardConfig;
13
+ tlsTerminateToHttp: (partialConfig: Partial<import("../types/forwarding.types.js").IForwardConfig> & Pick<import("../types/forwarding.types.js").IForwardConfig, "target">) => import("../types/forwarding.types.js").IForwardConfig;
14
+ tlsTerminateToHttps: (partialConfig: Partial<import("../types/forwarding.types.js").IForwardConfig> & Pick<import("../types/forwarding.types.js").IForwardConfig, "target">) => import("../types/forwarding.types.js").IForwardConfig;
15
+ httpsPassthrough: (partialConfig: Partial<import("../types/forwarding.types.js").IForwardConfig> & Pick<import("../types/forwarding.types.js").IForwardConfig, "target">) => import("../types/forwarding.types.js").IForwardConfig;
16
+ };
@@ -0,0 +1,23 @@
1
+ // Export values
2
+ export { ForwardingHandlerEvents, httpOnly, tlsTerminateToHttp, tlsTerminateToHttps, httpsPassthrough } from '../types/forwarding.types.js';
3
+ // Export domain configuration
4
+ export * from './domain-config.js';
5
+ // Export handlers
6
+ export { ForwardingHandler } from './forwarding.handler.js';
7
+ export { HttpForwardingHandler } from './http.handler.js';
8
+ export { HttpsPassthroughHandler } from './https-passthrough.handler.js';
9
+ export { HttpsTerminateToHttpHandler } from './https-terminate-to-http.handler.js';
10
+ export { HttpsTerminateToHttpsHandler } from './https-terminate-to-https.handler.js';
11
+ // Export factory
12
+ export { ForwardingHandlerFactory } from './forwarding.factory.js';
13
+ // Export manager
14
+ export { DomainManager, DomainManagerEvents } from './domain-manager.js';
15
+ // Helper functions as a convenience object
16
+ import { httpOnly, tlsTerminateToHttp, tlsTerminateToHttps, httpsPassthrough } from '../types/forwarding.types.js';
17
+ export const helpers = {
18
+ httpOnly,
19
+ tlsTerminateToHttp,
20
+ tlsTerminateToHttps,
21
+ httpsPassthrough
22
+ };
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zbWFydHByb3h5L2ZvcndhcmRpbmcvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBYUEsZ0JBQWdCO0FBQ2hCLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsUUFBUSxFQUNSLGtCQUFrQixFQUNsQixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2pCLE1BQU0sOEJBQThCLENBQUM7QUFFdEMsOEJBQThCO0FBQzlCLGNBQWMsb0JBQW9CLENBQUM7QUFFbkMsa0JBQWtCO0FBQ2xCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzVELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzFELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ25GLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBRXJGLGlCQUFpQjtBQUNqQixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVuRSxpQkFBaUI7QUFDakIsT0FBTyxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXpFLDJDQUEyQztBQUMzQyxPQUFPLEVBQ0wsUUFBUSxFQUNSLGtCQUFrQixFQUNsQixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2pCLE1BQU0sOEJBQThCLENBQUM7QUFFdEMsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHO0lBQ3JCLFFBQVE7SUFDUixrQkFBa0I7SUFDbEIsbUJBQW1CO0lBQ25CLGdCQUFnQjtDQUNqQixDQUFDIn0=