@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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/common/port80-adapter.d.ts +11 -0
- package/dist_ts/common/port80-adapter.js +61 -0
- package/dist_ts/examples/forwarding-example.d.ts +1 -0
- package/dist_ts/examples/forwarding-example.js +96 -0
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/smartproxy/classes.pp.connectionhandler.js +179 -30
- package/dist_ts/smartproxy/classes.pp.domainconfigmanager.d.ts +39 -0
- package/dist_ts/smartproxy/classes.pp.domainconfigmanager.js +172 -20
- package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +3 -11
- package/dist_ts/smartproxy/classes.pp.portrangemanager.js +17 -10
- package/dist_ts/smartproxy/classes.pp.securitymanager.d.ts +19 -2
- package/dist_ts/smartproxy/classes.pp.securitymanager.js +27 -4
- package/dist_ts/smartproxy/classes.pp.timeoutmanager.js +3 -3
- package/dist_ts/smartproxy/classes.smartproxy.js +45 -13
- package/dist_ts/smartproxy/forwarding/domain-config.d.ts +12 -0
- package/dist_ts/smartproxy/forwarding/domain-config.js +12 -0
- package/dist_ts/smartproxy/forwarding/domain-manager.d.ts +86 -0
- package/dist_ts/smartproxy/forwarding/domain-manager.js +241 -0
- package/dist_ts/smartproxy/forwarding/forwarding.factory.d.ts +24 -0
- package/dist_ts/smartproxy/forwarding/forwarding.factory.js +137 -0
- package/dist_ts/smartproxy/forwarding/forwarding.handler.d.ts +55 -0
- package/dist_ts/smartproxy/forwarding/forwarding.handler.js +94 -0
- package/dist_ts/smartproxy/forwarding/http.handler.d.ts +25 -0
- package/dist_ts/smartproxy/forwarding/http.handler.js +123 -0
- package/dist_ts/smartproxy/forwarding/https-passthrough.handler.d.ts +24 -0
- package/dist_ts/smartproxy/forwarding/https-passthrough.handler.js +154 -0
- package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.d.ts +36 -0
- package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.js +229 -0
- package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.d.ts +35 -0
- package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.js +254 -0
- package/dist_ts/smartproxy/forwarding/index.d.ts +16 -0
- package/dist_ts/smartproxy/forwarding/index.js +23 -0
- package/dist_ts/smartproxy/types/forwarding.types.d.ts +104 -0
- package/dist_ts/smartproxy/types/forwarding.types.js +50 -0
- package/package.json +2 -2
- package/readme.md +158 -8
- package/readme.plan.md +471 -42
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/common/port80-adapter.ts +87 -0
- package/ts/index.ts +3 -0
- package/ts/smartproxy/classes.pp.connectionhandler.ts +231 -44
- package/ts/smartproxy/classes.pp.domainconfigmanager.ts +198 -24
- package/ts/smartproxy/classes.pp.interfaces.ts +3 -11
- package/ts/smartproxy/classes.pp.portrangemanager.ts +17 -10
- package/ts/smartproxy/classes.pp.securitymanager.ts +29 -5
- package/ts/smartproxy/classes.pp.timeoutmanager.ts +3 -3
- package/ts/smartproxy/classes.smartproxy.ts +68 -15
- package/ts/smartproxy/forwarding/domain-config.ts +28 -0
- package/ts/smartproxy/forwarding/domain-manager.ts +283 -0
- package/ts/smartproxy/forwarding/forwarding.factory.ts +155 -0
- package/ts/smartproxy/forwarding/forwarding.handler.ts +127 -0
- package/ts/smartproxy/forwarding/http.handler.ts +140 -0
- package/ts/smartproxy/forwarding/https-passthrough.handler.ts +182 -0
- package/ts/smartproxy/forwarding/https-terminate-to-http.handler.ts +264 -0
- package/ts/smartproxy/forwarding/https-terminate-to-https.handler.ts +292 -0
- package/ts/smartproxy/forwarding/index.ts +52 -0
- package/ts/smartproxy/types/forwarding.types.ts +162 -0
package/readme.plan.md
CHANGED
|
@@ -1,42 +1,471 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
1
|
+
# SmartProxy Unified Forwarding Configuration Plan
|
|
2
|
+
|
|
3
|
+
## Project Goal
|
|
4
|
+
Create a clean, use-case driven forwarding configuration interface for SmartProxy that elegantly handles all forwarding scenarios: SNI-based forwarding, termination-based forwarding (NetworkProxy), HTTP forwarding, and ACME challenge forwarding.
|
|
5
|
+
|
|
6
|
+
## Current State
|
|
7
|
+
Currently, SmartProxy has several different forwarding mechanisms configured separately:
|
|
8
|
+
1. **HTTPS/SNI forwarding** via `IDomainConfig` properties
|
|
9
|
+
2. **NetworkProxy forwarding** via `useNetworkProxy` in domain configs
|
|
10
|
+
3. **HTTP forwarding** via Port80Handler's `forward` configuration
|
|
11
|
+
4. **ACME challenge forwarding** via `acmeForward` configuration
|
|
12
|
+
|
|
13
|
+
This separation creates configuration complexity and reduced cohesion between related settings.
|
|
14
|
+
|
|
15
|
+
## Proposed Solution: Clean Use-Case Driven Forwarding Interface
|
|
16
|
+
|
|
17
|
+
### Phase 1: Design Streamlined Forwarding Interface
|
|
18
|
+
|
|
19
|
+
- [ ] Create a use-case driven `IForwardConfig` interface that simplifies configuration:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
export interface IForwardConfig {
|
|
23
|
+
// Define the primary forwarding type - use-case driven approach
|
|
24
|
+
type: 'http-only' | 'https-passthrough' | 'https-terminate-to-http' | 'https-terminate-to-https';
|
|
25
|
+
|
|
26
|
+
// Target configuration
|
|
27
|
+
target: {
|
|
28
|
+
host: string | string[]; // Support single host or round-robin
|
|
29
|
+
port: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// HTTP-specific options
|
|
33
|
+
http?: {
|
|
34
|
+
enabled?: boolean; // Defaults to true for http-only, optional for others
|
|
35
|
+
redirectToHttps?: boolean; // Redirect HTTP to HTTPS
|
|
36
|
+
headers?: Record<string, string>; // Custom headers for HTTP responses
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// HTTPS-specific options
|
|
40
|
+
https?: {
|
|
41
|
+
customCert?: { // Use custom cert instead of auto-provisioned
|
|
42
|
+
key: string;
|
|
43
|
+
cert: string;
|
|
44
|
+
};
|
|
45
|
+
forwardSni?: boolean; // Forward SNI info in passthrough mode
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// ACME certificate handling
|
|
49
|
+
acme?: {
|
|
50
|
+
enabled?: boolean; // Enable ACME certificate provisioning
|
|
51
|
+
maintenance?: boolean; // Auto-renew certificates
|
|
52
|
+
production?: boolean; // Use production ACME servers
|
|
53
|
+
forwardChallenges?: { // Forward ACME challenges
|
|
54
|
+
host: string;
|
|
55
|
+
port: number;
|
|
56
|
+
useTls?: boolean;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Security options
|
|
61
|
+
security?: {
|
|
62
|
+
allowedIps?: string[]; // IPs allowed to connect
|
|
63
|
+
blockedIps?: string[]; // IPs blocked from connecting
|
|
64
|
+
maxConnections?: number; // Max simultaneous connections
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Advanced options
|
|
68
|
+
advanced?: {
|
|
69
|
+
portRanges?: Array<{ from: number; to: number }>; // Allowed port ranges
|
|
70
|
+
networkProxyPort?: number; // Custom NetworkProxy port if using terminate mode
|
|
71
|
+
keepAlive?: boolean; // Enable TCP keepalive
|
|
72
|
+
timeout?: number; // Connection timeout in ms
|
|
73
|
+
headers?: Record<string, string>; // Custom headers with support for variables like {sni}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Phase 2: Create New Domain Configuration Interface
|
|
79
|
+
|
|
80
|
+
- [ ] Replace existing `IDomainConfig` interface with a new one using the forwarding pattern:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
export interface IDomainConfig {
|
|
84
|
+
// Core properties
|
|
85
|
+
domains: string[]; // Domain patterns to match
|
|
86
|
+
|
|
87
|
+
// Unified forwarding configuration
|
|
88
|
+
forwarding: IForwardConfig;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Phase 3: Implement Forwarding Handler System
|
|
93
|
+
|
|
94
|
+
- [ ] Create an implementation strategy focused on the new forwarding types:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
/**
|
|
98
|
+
* Base class for all forwarding handlers
|
|
99
|
+
*/
|
|
100
|
+
abstract class ForwardingHandler {
|
|
101
|
+
constructor(protected config: IForwardConfig) {}
|
|
102
|
+
|
|
103
|
+
abstract handleConnection(socket: Socket): void;
|
|
104
|
+
abstract handleHttpRequest(req: IncomingMessage, res: ServerResponse): void;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Factory for creating the appropriate handler based on forwarding type
|
|
109
|
+
*/
|
|
110
|
+
class ForwardingHandlerFactory {
|
|
111
|
+
public static createHandler(config: IForwardConfig): ForwardingHandler {
|
|
112
|
+
switch (config.type) {
|
|
113
|
+
case 'http-only':
|
|
114
|
+
return new HttpForwardingHandler(config);
|
|
115
|
+
|
|
116
|
+
case 'https-passthrough':
|
|
117
|
+
return new HttpsPassthroughHandler(config);
|
|
118
|
+
|
|
119
|
+
case 'https-terminate-to-http':
|
|
120
|
+
return new HttpsTerminateToHttpHandler(config);
|
|
121
|
+
|
|
122
|
+
case 'https-terminate-to-https':
|
|
123
|
+
return new HttpsTerminateToHttpsHandler(config);
|
|
124
|
+
|
|
125
|
+
default:
|
|
126
|
+
throw new Error(`Unknown forwarding type: ${config.type}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Usage Examples for Common Scenarios
|
|
133
|
+
|
|
134
|
+
### 1. Basic HTTP Server
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
{
|
|
138
|
+
domains: ['example.com'],
|
|
139
|
+
forwarding: {
|
|
140
|
+
type: 'http-only',
|
|
141
|
+
target: {
|
|
142
|
+
host: 'localhost',
|
|
143
|
+
port: 3000
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 2. HTTPS Termination with HTTP Backend
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
{
|
|
153
|
+
domains: ['secure.example.com'],
|
|
154
|
+
forwarding: {
|
|
155
|
+
type: 'https-terminate-to-http',
|
|
156
|
+
target: {
|
|
157
|
+
host: 'localhost',
|
|
158
|
+
port: 3000
|
|
159
|
+
},
|
|
160
|
+
acme: {
|
|
161
|
+
production: true // Use production Let's Encrypt
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 3. HTTPS Termination with HTTPS Backend
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
{
|
|
171
|
+
domains: ['secure-backend.example.com'],
|
|
172
|
+
forwarding: {
|
|
173
|
+
type: 'https-terminate-to-https',
|
|
174
|
+
target: {
|
|
175
|
+
host: 'internal-api',
|
|
176
|
+
port: 8443
|
|
177
|
+
},
|
|
178
|
+
http: {
|
|
179
|
+
redirectToHttps: true // Redirect HTTP requests to HTTPS
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 4. SNI Passthrough
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
{
|
|
189
|
+
domains: ['passthrough.example.com'],
|
|
190
|
+
forwarding: {
|
|
191
|
+
type: 'https-passthrough',
|
|
192
|
+
target: {
|
|
193
|
+
host: '10.0.0.5',
|
|
194
|
+
port: 443
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 5. Mixed HTTP/HTTPS with Custom ACME Forwarding
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
{
|
|
204
|
+
domains: ['mixed.example.com'],
|
|
205
|
+
forwarding: {
|
|
206
|
+
type: 'https-terminate-to-http',
|
|
207
|
+
target: {
|
|
208
|
+
host: 'localhost',
|
|
209
|
+
port: 3000
|
|
210
|
+
},
|
|
211
|
+
http: {
|
|
212
|
+
redirectToHttps: false // Allow both HTTP and HTTPS access
|
|
213
|
+
},
|
|
214
|
+
acme: {
|
|
215
|
+
enabled: true,
|
|
216
|
+
maintenance: true,
|
|
217
|
+
forwardChallenges: {
|
|
218
|
+
host: '192.168.1.100',
|
|
219
|
+
port: 8080
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 6. Load-Balanced Backend
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
{
|
|
230
|
+
domains: ['api.example.com'],
|
|
231
|
+
forwarding: {
|
|
232
|
+
type: 'https-terminate-to-https',
|
|
233
|
+
target: {
|
|
234
|
+
host: ['10.0.0.10', '10.0.0.11', '10.0.0.12'], // Round-robin
|
|
235
|
+
port: 8443
|
|
236
|
+
},
|
|
237
|
+
security: {
|
|
238
|
+
allowedIps: ['10.0.0.*', '192.168.1.*'] // Restrict access
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### 7. Advanced Proxy Chain with Custom Headers
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
{
|
|
248
|
+
domains: ['secure-chain.example.com'],
|
|
249
|
+
forwarding: {
|
|
250
|
+
type: 'https-terminate-to-https',
|
|
251
|
+
target: {
|
|
252
|
+
host: 'backend-gateway.internal',
|
|
253
|
+
port: 443
|
|
254
|
+
},
|
|
255
|
+
advanced: {
|
|
256
|
+
// Pass original client info to backend
|
|
257
|
+
headers: {
|
|
258
|
+
'X-Original-SNI': '{sni}',
|
|
259
|
+
'X-Client-IP': '{clientIp}'
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Implementation Plan
|
|
267
|
+
|
|
268
|
+
### Task 1: Core Types and Interfaces (Week 1)
|
|
269
|
+
- [ ] Create the new `IForwardConfig` interface in `classes.pp.interfaces.ts`
|
|
270
|
+
- [ ] Design the new `IDomainConfig` interface using the forwarding property
|
|
271
|
+
- [ ] Define the internal data types for expanded configuration
|
|
272
|
+
|
|
273
|
+
### Task 2: Forwarding Handlers (Week 1-2)
|
|
274
|
+
- [ ] Create abstract `ForwardingHandler` base class
|
|
275
|
+
- [ ] Implement concrete handlers for each forwarding type:
|
|
276
|
+
- [ ] `HttpForwardingHandler` - For HTTP-only configurations
|
|
277
|
+
- [ ] `HttpsPassthroughHandler` - For SNI passthrough
|
|
278
|
+
- [ ] `HttpsTerminateToHttpHandler` - For TLS termination to HTTP backends
|
|
279
|
+
- [ ] `HttpsTerminateToHttpsHandler` - For TLS termination to HTTPS backends
|
|
280
|
+
- [ ] Implement `ForwardingHandlerFactory` to create the appropriate handler
|
|
281
|
+
|
|
282
|
+
### Task 3: SmartProxy Integration (Week 2-3)
|
|
283
|
+
- [ ] Update `SmartProxy` class to use the new forwarding system
|
|
284
|
+
- [ ] Modify `ConnectionHandler` to delegate to forwarding handlers
|
|
285
|
+
- [ ] Refactor domain configuration processing to use forwarding types
|
|
286
|
+
- [ ] Update `Port80Handler` integration to work with the new system
|
|
287
|
+
|
|
288
|
+
### Task 4: Certificate Management (Week 3)
|
|
289
|
+
- [ ] Create a certificate management system that works with forwarding types
|
|
290
|
+
- [ ] Implement automatic ACME provisioning based on forwarding type
|
|
291
|
+
- [ ] Add custom certificate support
|
|
292
|
+
|
|
293
|
+
### Task 5: Testing & Helper Functions (Week 4)
|
|
294
|
+
- [ ] Create helper functions for common forwarding patterns
|
|
295
|
+
- [ ] Implement comprehensive test suite for each forwarding handler
|
|
296
|
+
- [ ] Add validation for forwarding configurations
|
|
297
|
+
|
|
298
|
+
### Task 6: Documentation (Week 4)
|
|
299
|
+
- [ ] Create detailed documentation for the new forwarding system
|
|
300
|
+
- [ ] Document the forwarding types and their use cases
|
|
301
|
+
- [ ] Update README with the new configuration examples
|
|
302
|
+
|
|
303
|
+
## Detailed Type Documentation
|
|
304
|
+
|
|
305
|
+
### Core Forwarding Types
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
/**
|
|
309
|
+
* The primary forwarding types supported by SmartProxy
|
|
310
|
+
*/
|
|
311
|
+
export type ForwardingType =
|
|
312
|
+
| 'http-only' // HTTP forwarding only (no HTTPS)
|
|
313
|
+
| 'https-passthrough' // Pass-through TLS traffic (SNI forwarding)
|
|
314
|
+
| 'https-terminate-to-http' // Terminate TLS and forward to HTTP backend
|
|
315
|
+
| 'https-terminate-to-https'; // Terminate TLS and forward to HTTPS backend
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Type-Specific Behavior
|
|
319
|
+
|
|
320
|
+
Each forwarding type has specific default behavior:
|
|
321
|
+
|
|
322
|
+
#### HTTP-Only
|
|
323
|
+
- Handles only HTTP traffic
|
|
324
|
+
- No TLS/HTTPS support
|
|
325
|
+
- No certificate management
|
|
326
|
+
|
|
327
|
+
#### HTTPS Passthrough
|
|
328
|
+
- Forwards raw TLS traffic to backend (no termination)
|
|
329
|
+
- Passes SNI information through
|
|
330
|
+
- No HTTP support (TLS only)
|
|
331
|
+
- No certificate management
|
|
332
|
+
|
|
333
|
+
#### HTTPS Terminate to HTTP
|
|
334
|
+
- Terminates TLS at SmartProxy
|
|
335
|
+
- Connects to backend using HTTP (non-TLS)
|
|
336
|
+
- Manages certificates automatically (ACME)
|
|
337
|
+
- Supports HTTP requests with option to redirect to HTTPS
|
|
338
|
+
|
|
339
|
+
#### HTTPS Terminate to HTTPS
|
|
340
|
+
- Terminates client TLS at SmartProxy
|
|
341
|
+
- Creates new TLS connection to backend
|
|
342
|
+
- Manages certificates automatically (ACME)
|
|
343
|
+
- Supports HTTP requests with option to redirect to HTTPS
|
|
344
|
+
|
|
345
|
+
## Handler Implementation Strategy
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
/**
|
|
349
|
+
* Handler for HTTP-only forwarding
|
|
350
|
+
*/
|
|
351
|
+
class HttpForwardingHandler extends ForwardingHandler {
|
|
352
|
+
public handleConnection(socket: Socket): void {
|
|
353
|
+
// Process HTTP connection
|
|
354
|
+
// For HTTP-only, we'll mostly defer to handleHttpRequest
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
public handleHttpRequest(req: IncomingMessage, res: ServerResponse): void {
|
|
358
|
+
// Forward HTTP request to target
|
|
359
|
+
const target = this.getTargetFromConfig();
|
|
360
|
+
this.proxyRequest(req, res, target);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Handler for HTTPS passthrough (SNI forwarding)
|
|
366
|
+
*/
|
|
367
|
+
class HttpsPassthroughHandler extends ForwardingHandler {
|
|
368
|
+
public handleConnection(socket: Socket): void {
|
|
369
|
+
// Extract SNI from TLS ClientHello if needed
|
|
370
|
+
// Forward raw TLS traffic to target without termination
|
|
371
|
+
const target = this.getTargetFromConfig();
|
|
372
|
+
this.forwardTlsConnection(socket, target);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
public handleHttpRequest(req: IncomingMessage, res: ServerResponse): void {
|
|
376
|
+
// HTTP not supported in SNI passthrough mode
|
|
377
|
+
res.statusCode = 404;
|
|
378
|
+
res.end('HTTP not supported for this domain');
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Handler for HTTPS termination with HTTP backend
|
|
384
|
+
*/
|
|
385
|
+
class HttpsTerminateToHttpHandler extends ForwardingHandler {
|
|
386
|
+
private tlsContext: SecureContext;
|
|
387
|
+
|
|
388
|
+
public async initialize(): Promise<void> {
|
|
389
|
+
// Set up TLS termination context
|
|
390
|
+
this.tlsContext = await this.createTlsContext();
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
public handleConnection(socket: Socket): void {
|
|
394
|
+
// Terminate TLS
|
|
395
|
+
const tlsSocket = this.createTlsSocket(socket, this.tlsContext);
|
|
396
|
+
|
|
397
|
+
// Forward to HTTP backend after TLS termination
|
|
398
|
+
tlsSocket.on('data', (data) => {
|
|
399
|
+
this.forwardToHttpBackend(data);
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
public handleHttpRequest(req: IncomingMessage, res: ServerResponse): void {
|
|
404
|
+
if (this.config.http?.redirectToHttps) {
|
|
405
|
+
// Redirect to HTTPS if configured
|
|
406
|
+
this.redirectToHttps(req, res);
|
|
407
|
+
} else {
|
|
408
|
+
// Handle HTTP request
|
|
409
|
+
const target = this.getTargetFromConfig();
|
|
410
|
+
this.proxyRequest(req, res, target);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Handler for HTTPS termination with HTTPS backend
|
|
417
|
+
*/
|
|
418
|
+
class HttpsTerminateToHttpsHandler extends ForwardingHandler {
|
|
419
|
+
private tlsContext: SecureContext;
|
|
420
|
+
|
|
421
|
+
public async initialize(): Promise<void> {
|
|
422
|
+
// Set up TLS termination context
|
|
423
|
+
this.tlsContext = await this.createTlsContext();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
public handleConnection(socket: Socket): void {
|
|
427
|
+
// Terminate client TLS
|
|
428
|
+
const tlsSocket = this.createTlsSocket(socket, this.tlsContext);
|
|
429
|
+
|
|
430
|
+
// Create new TLS connection to backend
|
|
431
|
+
tlsSocket.on('data', (data) => {
|
|
432
|
+
this.forwardToHttpsBackend(data);
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
public handleHttpRequest(req: IncomingMessage, res: ServerResponse): void {
|
|
437
|
+
if (this.config.http?.redirectToHttps) {
|
|
438
|
+
// Redirect to HTTPS if configured
|
|
439
|
+
this.redirectToHttps(req, res);
|
|
440
|
+
} else {
|
|
441
|
+
// Handle HTTP request via HTTPS to backend
|
|
442
|
+
const target = this.getTargetFromConfig();
|
|
443
|
+
this.proxyRequestOverHttps(req, res, target);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## Benefits of This Approach
|
|
450
|
+
|
|
451
|
+
1. **Clean, Type-Driven Design**
|
|
452
|
+
- Forwarding types clearly express intent
|
|
453
|
+
- No backward compatibility compromises
|
|
454
|
+
- Code structure follows the domain model
|
|
455
|
+
|
|
456
|
+
2. **Explicit Configuration**
|
|
457
|
+
- Configuration directly maps to behavior
|
|
458
|
+
- Reduced chance of unexpected behavior
|
|
459
|
+
|
|
460
|
+
3. **Modular Implementation**
|
|
461
|
+
- Each forwarding type handled by dedicated class
|
|
462
|
+
- Clear separation of concerns
|
|
463
|
+
- Easier to test and extend
|
|
464
|
+
|
|
465
|
+
4. **Simplified Mental Model**
|
|
466
|
+
- Users think in terms of use cases, not low-level settings
|
|
467
|
+
- Configuration matches mental model
|
|
468
|
+
|
|
469
|
+
5. **Future-Proof**
|
|
470
|
+
- Easy to add new forwarding types
|
|
471
|
+
- Clean extension points for new features
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartproxy',
|
|
6
|
-
version: '
|
|
6
|
+
version: '12.0.0',
|
|
7
7
|
description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
|
|
8
8
|
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
IForwardConfig as ILegacyForwardConfig,
|
|
5
|
+
IDomainOptions
|
|
6
|
+
} from './types.js';
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
IForwardConfig
|
|
10
|
+
} from '../smartproxy/types/forwarding.types.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Converts a forwarding configuration target to the legacy format
|
|
14
|
+
* for Port80Handler
|
|
15
|
+
*/
|
|
16
|
+
export function convertToLegacyForwardConfig(
|
|
17
|
+
forwardConfig: IForwardConfig
|
|
18
|
+
): ILegacyForwardConfig {
|
|
19
|
+
// Determine host from the target configuration
|
|
20
|
+
const host = Array.isArray(forwardConfig.target.host)
|
|
21
|
+
? forwardConfig.target.host[0] // Use the first host in the array
|
|
22
|
+
: forwardConfig.target.host;
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
ip: host,
|
|
26
|
+
port: forwardConfig.target.port
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates Port80Handler domain options from a domain name and forwarding config
|
|
32
|
+
*/
|
|
33
|
+
export function createPort80HandlerOptions(
|
|
34
|
+
domain: string,
|
|
35
|
+
forwardConfig: IForwardConfig
|
|
36
|
+
): IDomainOptions {
|
|
37
|
+
// Determine if we should redirect HTTP to HTTPS
|
|
38
|
+
let sslRedirect = false;
|
|
39
|
+
if (forwardConfig.http?.redirectToHttps) {
|
|
40
|
+
sslRedirect = true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Determine if ACME maintenance should be enabled
|
|
44
|
+
// Enable by default for termination types, unless explicitly disabled
|
|
45
|
+
const requiresTls =
|
|
46
|
+
forwardConfig.type === 'https-terminate-to-http' ||
|
|
47
|
+
forwardConfig.type === 'https-terminate-to-https';
|
|
48
|
+
|
|
49
|
+
const acmeMaintenance =
|
|
50
|
+
requiresTls &&
|
|
51
|
+
forwardConfig.acme?.enabled !== false;
|
|
52
|
+
|
|
53
|
+
// Set up forwarding configuration
|
|
54
|
+
const options: IDomainOptions = {
|
|
55
|
+
domainName: domain,
|
|
56
|
+
sslRedirect,
|
|
57
|
+
acmeMaintenance
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Add ACME challenge forwarding if configured
|
|
61
|
+
if (forwardConfig.acme?.forwardChallenges) {
|
|
62
|
+
options.acmeForward = {
|
|
63
|
+
ip: Array.isArray(forwardConfig.acme.forwardChallenges.host)
|
|
64
|
+
? forwardConfig.acme.forwardChallenges.host[0]
|
|
65
|
+
: forwardConfig.acme.forwardChallenges.host,
|
|
66
|
+
port: forwardConfig.acme.forwardChallenges.port
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Add HTTP forwarding if this is an HTTP-only config or if HTTP is enabled
|
|
71
|
+
const supportsHttp =
|
|
72
|
+
forwardConfig.type === 'http-only' ||
|
|
73
|
+
(forwardConfig.http?.enabled !== false &&
|
|
74
|
+
(forwardConfig.type === 'https-terminate-to-http' ||
|
|
75
|
+
forwardConfig.type === 'https-terminate-to-https'));
|
|
76
|
+
|
|
77
|
+
if (supportsHttp) {
|
|
78
|
+
options.forward = {
|
|
79
|
+
ip: Array.isArray(forwardConfig.target.host)
|
|
80
|
+
? forwardConfig.target.host[0]
|
|
81
|
+
: forwardConfig.target.host,
|
|
82
|
+
port: forwardConfig.target.port
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return options;
|
|
87
|
+
}
|
package/ts/index.ts
CHANGED