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