@push.rocks/smartproxy 19.5.4 → 19.5.6

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 (62) hide show
  1. package/dist_ts/core/utils/async-utils.d.ts +81 -0
  2. package/dist_ts/core/utils/async-utils.js +216 -0
  3. package/dist_ts/core/utils/binary-heap.d.ts +73 -0
  4. package/dist_ts/core/utils/binary-heap.js +193 -0
  5. package/dist_ts/core/utils/enhanced-connection-pool.d.ts +110 -0
  6. package/dist_ts/core/utils/enhanced-connection-pool.js +320 -0
  7. package/dist_ts/core/utils/fs-utils.d.ts +144 -0
  8. package/dist_ts/core/utils/fs-utils.js +252 -0
  9. package/dist_ts/core/utils/index.d.ts +6 -2
  10. package/dist_ts/core/utils/index.js +7 -3
  11. package/dist_ts/core/utils/lifecycle-component.d.ts +59 -0
  12. package/dist_ts/core/utils/lifecycle-component.js +195 -0
  13. package/dist_ts/core/utils/socket-utils.d.ts +28 -0
  14. package/dist_ts/core/utils/socket-utils.js +77 -0
  15. package/dist_ts/forwarding/handlers/http-handler.js +7 -4
  16. package/dist_ts/forwarding/handlers/https-passthrough-handler.js +14 -55
  17. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.js +52 -40
  18. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.js +31 -43
  19. package/dist_ts/plugins.d.ts +2 -1
  20. package/dist_ts/plugins.js +3 -2
  21. package/dist_ts/proxies/http-proxy/certificate-manager.d.ts +15 -0
  22. package/dist_ts/proxies/http-proxy/certificate-manager.js +49 -2
  23. package/dist_ts/proxies/http-proxy/connection-pool.js +4 -19
  24. package/dist_ts/proxies/http-proxy/http-proxy.js +3 -7
  25. package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +10 -0
  26. package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +53 -43
  27. package/dist_ts/proxies/smart-proxy/cert-store.js +22 -20
  28. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +35 -9
  29. package/dist_ts/proxies/smart-proxy/connection-manager.js +243 -189
  30. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +13 -2
  31. package/dist_ts/proxies/smart-proxy/port-manager.js +3 -3
  32. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +35 -4
  33. package/package.json +2 -2
  34. package/readme.hints.md +96 -1
  35. package/readme.plan.md +1135 -221
  36. package/readme.problems.md +167 -83
  37. package/ts/core/utils/async-utils.ts +275 -0
  38. package/ts/core/utils/binary-heap.ts +225 -0
  39. package/ts/core/utils/enhanced-connection-pool.ts +420 -0
  40. package/ts/core/utils/fs-utils.ts +270 -0
  41. package/ts/core/utils/index.ts +6 -2
  42. package/ts/core/utils/lifecycle-component.ts +231 -0
  43. package/ts/core/utils/socket-utils.ts +96 -0
  44. package/ts/forwarding/handlers/http-handler.ts +7 -3
  45. package/ts/forwarding/handlers/https-passthrough-handler.ts +13 -62
  46. package/ts/forwarding/handlers/https-terminate-to-http-handler.ts +58 -46
  47. package/ts/forwarding/handlers/https-terminate-to-https-handler.ts +38 -53
  48. package/ts/plugins.ts +2 -1
  49. package/ts/proxies/http-proxy/certificate-manager.ts +52 -1
  50. package/ts/proxies/http-proxy/connection-pool.ts +3 -16
  51. package/ts/proxies/http-proxy/http-proxy.ts +2 -5
  52. package/ts/proxies/nftables-proxy/nftables-proxy.ts +64 -79
  53. package/ts/proxies/smart-proxy/cert-store.ts +26 -20
  54. package/ts/proxies/smart-proxy/connection-manager.ts +277 -197
  55. package/ts/proxies/smart-proxy/http-proxy-bridge.ts +15 -1
  56. package/ts/proxies/smart-proxy/port-manager.ts +2 -2
  57. package/ts/proxies/smart-proxy/route-connection-handler.ts +39 -4
  58. package/readme.plan2.md +0 -764
  59. package/ts/common/eventUtils.ts +0 -34
  60. package/ts/common/types.ts +0 -91
  61. package/ts/core/utils/event-system.ts +0 -376
  62. package/ts/core/utils/event-utils.ts +0 -25
package/readme.plan2.md DELETED
@@ -1,764 +0,0 @@
1
- # SmartProxy Simplification Plan: Unify Action Types
2
-
3
- ## Summary
4
- Complete removal of 'redirect', 'block', and 'static' action types, leaving only 'forward' and 'socket-handler'. All old code will be deleted entirely - no migration paths or backwards compatibility. Socket handlers will be enhanced to receive IRouteContext as a second parameter.
5
-
6
- ## Goal
7
- Create a dramatically simpler SmartProxy with only two action types, where everything is either proxied (forward) or handled by custom code (socket-handler).
8
-
9
- ## Current State
10
- ```typescript
11
- export type TRouteActionType = 'forward' | 'redirect' | 'block' | 'static' | 'socket-handler';
12
- export type TSocketHandler = (socket: plugins.net.Socket) => void | Promise<void>;
13
- ```
14
-
15
- ## Target State
16
- ```typescript
17
- export type TRouteActionType = 'forward' | 'socket-handler';
18
- export type TSocketHandler = (socket: plugins.net.Socket, context: IRouteContext) => void | Promise<void>;
19
- ```
20
-
21
- ## Benefits
22
- 1. **Simpler API** - Only two action types to understand
23
- 2. **Unified handling** - Everything is either forwarding or custom socket handling
24
- 3. **More flexible** - Socket handlers can do anything the old types did and more
25
- 4. **Less code** - Remove specialized handlers and their dependencies
26
- 5. **Context aware** - Socket handlers get access to route context (domain, port, clientIp, etc.)
27
- 6. **Clean codebase** - No legacy code or migration paths
28
-
29
- ---
30
-
31
- ## Phase 1: Code to Remove
32
-
33
- ### 1.1 Action Type Handlers
34
- - `RouteConnectionHandler.handleRedirectAction()`
35
- - `RouteConnectionHandler.handleBlockAction()`
36
- - `RouteConnectionHandler.handleStaticAction()`
37
-
38
- ### 1.2 Handler Classes
39
- - `RedirectHandler` class (http-proxy/handlers/)
40
- - `StaticHandler` class (http-proxy/handlers/)
41
-
42
- ### 1.3 Type Definitions
43
- - 'redirect', 'block', 'static' from TRouteActionType
44
- - IRouteRedirect interface
45
- - IRouteStatic interface
46
- - Related properties in IRouteAction
47
-
48
- ### 1.4 Helper Functions
49
- - `createStaticFileRoute()`
50
- - Any other helpers that create redirect/block/static routes
51
-
52
- ---
53
-
54
- ## Phase 2: Create Predefined Socket Handlers
55
-
56
- ### 2.1 Block Handler
57
- ```typescript
58
- export const SocketHandlers = {
59
- // ... existing handlers
60
-
61
- /**
62
- * Block connection immediately
63
- */
64
- block: (message?: string) => (socket: plugins.net.Socket, context: IRouteContext) => {
65
- // Can use context for logging or custom messages
66
- const finalMessage = message || `Connection blocked from ${context.clientIp}`;
67
- if (finalMessage) {
68
- socket.write(finalMessage);
69
- }
70
- socket.end();
71
- },
72
-
73
- /**
74
- * HTTP block response
75
- */
76
- httpBlock: (statusCode: number = 403, message?: string) => (socket: plugins.net.Socket, context: IRouteContext) => {
77
- // Can customize message based on context
78
- const defaultMessage = `Access forbidden for ${context.domain || context.clientIp}`;
79
- const finalMessage = message || defaultMessage;
80
-
81
- const response = [
82
- `HTTP/1.1 ${statusCode} ${finalMessage}`,
83
- 'Content-Type: text/plain',
84
- `Content-Length: ${finalMessage.length}`,
85
- 'Connection: close',
86
- '',
87
- finalMessage
88
- ].join('\r\n');
89
-
90
- socket.write(response);
91
- socket.end();
92
- }
93
- };
94
- ```
95
-
96
- ### 2.2 Redirect Handler
97
- ```typescript
98
- export const SocketHandlers = {
99
- // ... existing handlers
100
-
101
- /**
102
- * HTTP redirect handler
103
- */
104
- httpRedirect: (locationTemplate: string, statusCode: number = 301) => (socket: plugins.net.Socket, context: IRouteContext) => {
105
- let buffer = '';
106
-
107
- socket.once('data', (data) => {
108
- buffer += data.toString();
109
-
110
- // Parse HTTP request
111
- const lines = buffer.split('\r\n');
112
- const requestLine = lines[0];
113
- const [method, path] = requestLine.split(' ');
114
-
115
- // Use domain from context (more reliable than Host header)
116
- const domain = context.domain || 'localhost';
117
- const port = context.port;
118
-
119
- // Replace placeholders in location using context
120
- let finalLocation = locationTemplate
121
- .replace('{domain}', domain)
122
- .replace('{port}', String(port))
123
- .replace('{path}', path)
124
- .replace('{clientIp}', context.clientIp);
125
-
126
- const message = `Redirecting to ${finalLocation}`;
127
- const response = [
128
- `HTTP/1.1 ${statusCode} ${statusCode === 301 ? 'Moved Permanently' : 'Found'}`,
129
- `Location: ${finalLocation}`,
130
- 'Content-Type: text/plain',
131
- `Content-Length: ${message.length}`,
132
- 'Connection: close',
133
- '',
134
- message
135
- ].join('\r\n');
136
-
137
- socket.write(response);
138
- socket.end();
139
- });
140
- }
141
- };
142
- ```
143
-
144
- ### 2.3 Benefits of Context in Socket Handlers
145
- With routeContext as a second parameter, socket handlers can:
146
- - Access client IP for logging or rate limiting
147
- - Use domain information for multi-tenant handling
148
- - Check if connection is TLS and what version
149
- - Access route name/ID for metrics
150
- - Build more intelligent responses based on context
151
-
152
- Example advanced handler:
153
- ```typescript
154
- const rateLimitHandler = (maxRequests: number) => {
155
- const ipCounts = new Map<string, number>();
156
-
157
- return (socket: net.Socket, context: IRouteContext) => {
158
- const count = (ipCounts.get(context.clientIp) || 0) + 1;
159
- ipCounts.set(context.clientIp, count);
160
-
161
- if (count > maxRequests) {
162
- socket.write(`Rate limit exceeded for ${context.clientIp}\n`);
163
- socket.end();
164
- return;
165
- }
166
-
167
- // Process request...
168
- };
169
- };
170
- ```
171
-
172
- ---
173
-
174
- ## Phase 3: Update Helper Functions
175
-
176
- ### 3.1 Update createHttpToHttpsRedirect
177
- ```typescript
178
- export function createHttpToHttpsRedirect(
179
- domains: string | string[],
180
- httpsPort: number = 443,
181
- options: Partial<IRouteConfig> = {}
182
- ): IRouteConfig {
183
- return {
184
- name: options.name || `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
185
- match: {
186
- ports: options.match?.ports || 80,
187
- domains
188
- },
189
- action: {
190
- type: 'socket-handler',
191
- socketHandler: SocketHandlers.httpRedirect(`https://{domain}:${httpsPort}{path}`, 301)
192
- },
193
- ...options
194
- };
195
- }
196
- ```
197
-
198
- ### 3.2 Update createSocketHandlerRoute
199
- ```typescript
200
- export function createSocketHandlerRoute(
201
- domains: string | string[],
202
- ports: TPortRange,
203
- handler: TSocketHandler,
204
- options: { name?: string; priority?: number; path?: string } = {}
205
- ): IRouteConfig {
206
- return {
207
- name: options.name || 'socket-handler-route',
208
- priority: options.priority !== undefined ? options.priority : 50,
209
- match: {
210
- domains,
211
- ports,
212
- ...(options.path && { path: options.path })
213
- },
214
- action: {
215
- type: 'socket-handler',
216
- socketHandler: handler
217
- }
218
- };
219
- }
220
-
221
- ```
222
-
223
- ---
224
-
225
- ## Phase 4: Core Implementation Changes
226
-
227
- ### 4.1 Update Route Connection Handler
228
- ```typescript
229
- // Remove these methods:
230
- // - handleRedirectAction()
231
- // - handleBlockAction()
232
- // - handleStaticAction()
233
-
234
- // Update switch statement to only have:
235
- switch (route.action.type) {
236
- case 'forward':
237
- return this.handleForwardAction(socket, record, route, initialChunk);
238
-
239
- case 'socket-handler':
240
- this.handleSocketHandlerAction(socket, record, route, initialChunk);
241
- return;
242
-
243
- default:
244
- logger.log('error', `Unknown action type '${(route.action as any).type}'`);
245
- socket.end();
246
- this.connectionManager.cleanupConnection(record, 'unknown_action');
247
- }
248
- ```
249
-
250
- ### 4.2 Update Socket Handler to Pass Context
251
- ```typescript
252
- private async handleSocketHandlerAction(
253
- socket: plugins.net.Socket,
254
- record: IConnectionRecord,
255
- route: IRouteConfig,
256
- initialChunk?: Buffer
257
- ): Promise<void> {
258
- const connectionId = record.id;
259
-
260
- // Create route context for the handler
261
- const routeContext = this.createRouteContext({
262
- connectionId: record.id,
263
- port: record.localPort,
264
- domain: record.lockedDomain,
265
- clientIp: record.remoteIP,
266
- serverIp: socket.localAddress || '',
267
- isTls: record.isTLS || false,
268
- tlsVersion: record.tlsVersion,
269
- routeName: route.name,
270
- routeId: route.id,
271
- });
272
-
273
- try {
274
- // Call the handler with socket AND context
275
- const result = route.action.socketHandler(socket, routeContext);
276
-
277
- // Rest of implementation stays the same...
278
- } catch (error) {
279
- // Error handling...
280
- }
281
- }
282
- ```
283
-
284
- ### 4.3 Clean Up Imports and Exports
285
- - Remove imports of deleted handler classes
286
- - Update index.ts files to remove exports
287
- - Clean up any unused imports
288
-
289
- ---
290
-
291
- ## Phase 5: Test Updates
292
-
293
- ### 5.1 Remove Old Tests
294
- - Delete tests for redirect action type
295
- - Delete tests for block action type
296
- - Delete tests for static action type
297
-
298
- ### 5.2 Add New Socket Handler Tests
299
- - Test block socket handler with context
300
- - Test HTTP redirect socket handler with context
301
- - Test that context is properly passed to all handlers
302
-
303
- ---
304
-
305
- ## Phase 6: Documentation Updates
306
-
307
- ### 6.1 Update README.md
308
- - Remove documentation for redirect, block, static action types
309
- - Document the two remaining action types: forward and socket-handler
310
- - Add examples using socket handlers with context
311
-
312
- ### 6.2 Update Type Documentation
313
- ```typescript
314
- /**
315
- * Route action types
316
- * - 'forward': Proxy the connection to a target host:port
317
- * - 'socket-handler': Pass the socket to a custom handler function
318
- */
319
- export type TRouteActionType = 'forward' | 'socket-handler';
320
-
321
- /**
322
- * Socket handler function
323
- * @param socket - The incoming socket connection
324
- * @param context - Route context with connection information
325
- */
326
- export type TSocketHandler = (socket: net.Socket, context: IRouteContext) => void | Promise<void>;
327
- ```
328
-
329
- ### 6.3 Example Documentation
330
- ```typescript
331
- // Example: Block connections from specific IPs
332
- const ipBlocker = (socket: net.Socket, context: IRouteContext) => {
333
- if (context.clientIp.startsWith('192.168.')) {
334
- socket.write('Internal IPs not allowed\n');
335
- socket.end();
336
- return;
337
- }
338
- // Forward to backend...
339
- };
340
-
341
- // Example: Domain-based routing
342
- const domainRouter = (socket: net.Socket, context: IRouteContext) => {
343
- const backend = context.domain === 'api.example.com' ? 'api-server' : 'web-server';
344
- // Forward to appropriate backend...
345
- };
346
- ```
347
-
348
- ---
349
-
350
- ## Implementation Steps
351
-
352
- 1. **Update TSocketHandler type** (15 minutes)
353
- - Add IRouteContext as second parameter
354
- - Update type definition in route-types.ts
355
-
356
- 2. **Update socket handler implementation** (30 minutes)
357
- - Create routeContext in handleSocketHandlerAction
358
- - Pass context to socket handler function
359
- - Update all existing socket handlers in route-helpers.ts
360
-
361
- 3. **Remove old action types** (30 minutes)
362
- - Remove 'redirect', 'block', 'static' from TRouteActionType
363
- - Remove IRouteRedirect, IRouteStatic interfaces
364
- - Clean up IRouteAction interface
365
-
366
- 4. **Delete old handlers** (45 minutes)
367
- - Delete handleRedirectAction, handleBlockAction, handleStaticAction methods
368
- - Delete RedirectHandler and StaticHandler classes
369
- - Remove imports and exports
370
-
371
- 5. **Update route connection handler** (30 minutes)
372
- - Simplify switch statement to only handle 'forward' and 'socket-handler'
373
- - Remove all references to deleted action types
374
-
375
- 6. **Create new socket handlers** (30 minutes)
376
- - Implement SocketHandlers.block() with context
377
- - Implement SocketHandlers.httpBlock() with context
378
- - Implement SocketHandlers.httpRedirect() with context
379
-
380
- 7. **Update helper functions** (30 minutes)
381
- - Update createHttpToHttpsRedirect to use socket handler
382
- - Delete createStaticFileRoute entirely
383
- - Update any other affected helpers
384
-
385
- 8. **Clean up tests** (1.5 hours)
386
- - Delete all tests for removed action types
387
- - Update socket handler tests to verify context parameter
388
- - Add new tests for block/redirect socket handlers
389
-
390
- 9. **Update documentation** (30 minutes)
391
- - Update README.md
392
- - Update type documentation
393
- - Add examples of context usage
394
-
395
- **Total estimated time: ~5 hours**
396
-
397
- ---
398
-
399
- ## Considerations
400
-
401
- ### Benefits
402
- - **Dramatically simpler API** - Only 2 action types instead of 5
403
- - **Consistent handling model** - Everything is either forwarding or custom handling
404
- - **More powerful** - Socket handlers with context can do much more than old static types
405
- - **Less code to maintain** - Removing hundreds of lines of specialized handler code
406
- - **Better extensibility** - Easy to add new socket handlers for any use case
407
- - **Context awareness** - All handlers get full connection context
408
-
409
- ### Trade-offs
410
- - Static file serving removed (users should use nginx/apache behind proxy)
411
- - HTTP-specific logic (redirects) now in socket handlers (but more flexible)
412
- - Slightly more verbose configuration for simple blocks/redirects
413
-
414
- ### Why This Approach
415
- 1. **Simplicity wins** - Two concepts are easier to understand than five
416
- 2. **Power through context** - Socket handlers with context are more capable
417
- 3. **Clean break** - No migration paths means cleaner code
418
- 4. **Future proof** - Easy to add new handlers without changing core
419
-
420
- ---
421
-
422
- ## Code Examples: Before and After
423
-
424
- ### Block Action
425
- ```typescript
426
- // BEFORE
427
- {
428
- action: { type: 'block' }
429
- }
430
-
431
- // AFTER
432
- {
433
- action: {
434
- type: 'socket-handler',
435
- socketHandler: SocketHandlers.block()
436
- }
437
- }
438
- ```
439
-
440
- ### HTTP Redirect
441
- ```typescript
442
- // BEFORE
443
- {
444
- action: {
445
- type: 'redirect',
446
- redirect: {
447
- to: 'https://{domain}:443{path}',
448
- status: 301
449
- }
450
- }
451
- }
452
-
453
- // AFTER
454
- {
455
- action: {
456
- type: 'socket-handler',
457
- socketHandler: SocketHandlers.httpRedirect('https://{domain}:443{path}', 301)
458
- }
459
- }
460
- ```
461
-
462
- ### Custom Handler with Context
463
- ```typescript
464
- // NEW CAPABILITY - Access to full context
465
- {
466
- action: {
467
- type: 'socket-handler',
468
- socketHandler: (socket, context) => {
469
- console.log(`Connection from ${context.clientIp} to ${context.domain}:${context.port}`);
470
- // Custom handling based on context...
471
- }
472
- }
473
- }
474
- ```
475
-
476
- ---
477
-
478
- ## Detailed Implementation Tasks
479
-
480
- ### Step 1: Update TSocketHandler Type (15 minutes)
481
- - [x] Open `ts/proxies/smart-proxy/models/route-types.ts`
482
- - [x] Find line 14: `export type TSocketHandler = (socket: plugins.net.Socket) => void | Promise<void>;`
483
- - [x] Import IRouteContext at top of file: `import type { IRouteContext } from '../../../core/models/route-context.js';`
484
- - [x] Update TSocketHandler to: `export type TSocketHandler = (socket: plugins.net.Socket, context: IRouteContext) => void | Promise<void>;`
485
- - [x] Save file
486
-
487
- ### Step 2: Update Socket Handler Implementation (30 minutes)
488
- - [x] Open `ts/proxies/smart-proxy/route-connection-handler.ts`
489
- - [x] Find `handleSocketHandlerAction` method (around line 790)
490
- - [x] Add route context creation after line 809:
491
- ```typescript
492
- // Create route context for the handler
493
- const routeContext = this.createRouteContext({
494
- connectionId: record.id,
495
- port: record.localPort,
496
- domain: record.lockedDomain,
497
- clientIp: record.remoteIP,
498
- serverIp: socket.localAddress || '',
499
- isTls: record.isTLS || false,
500
- tlsVersion: record.tlsVersion,
501
- routeName: route.name,
502
- routeId: route.id,
503
- });
504
- ```
505
- - [x] Update line 812 from `const result = route.action.socketHandler(socket);`
506
- - [x] To: `const result = route.action.socketHandler(socket, routeContext);`
507
- - [x] Save file
508
-
509
- ### Step 3: Update Existing Socket Handlers in route-helpers.ts (20 minutes)
510
- - [x] Open `ts/proxies/smart-proxy/utils/route-helpers.ts`
511
- - [x] Update `echo` handler (line 856):
512
- - From: `echo: (socket: plugins.net.Socket) => {`
513
- - To: `echo: (socket: plugins.net.Socket, context: IRouteContext) => {`
514
- - [x] Update `proxy` handler (line 864):
515
- - From: `proxy: (targetHost: string, targetPort: number) => (socket: plugins.net.Socket) => {`
516
- - To: `proxy: (targetHost: string, targetPort: number) => (socket: plugins.net.Socket, context: IRouteContext) => {`
517
- - [x] Update `lineProtocol` handler (line 879):
518
- - From: `lineProtocol: (handler: (line: string, socket: plugins.net.Socket) => void) => (socket: plugins.net.Socket) => {`
519
- - To: `lineProtocol: (handler: (line: string, socket: plugins.net.Socket) => void) => (socket: plugins.net.Socket, context: IRouteContext) => {`
520
- - [ ] Update `httpResponse` handler (line 896):
521
- - From: `httpResponse: (statusCode: number, body: string) => (socket: plugins.net.Socket) => {`
522
- - To: `httpResponse: (statusCode: number, body: string) => (socket: plugins.net.Socket, context: IRouteContext) => {`
523
- - [ ] Save file
524
-
525
- ### Step 4: Remove Old Action Types from Type Definitions (15 minutes)
526
- - [ ] Open `ts/proxies/smart-proxy/models/route-types.ts`
527
- - [ ] Find line with TRouteActionType (around line 10)
528
- - [ ] Change from: `export type TRouteActionType = 'forward' | 'redirect' | 'block' | 'static' | 'socket-handler';`
529
- - [ ] To: `export type TRouteActionType = 'forward' | 'socket-handler';`
530
- - [ ] Find and delete IRouteRedirect interface (around line 123-126)
531
- - [ ] Find and delete IRouteStatic interface (if exists)
532
- - [ ] Find IRouteAction interface
533
- - [ ] Remove these properties:
534
- - `redirect?: IRouteRedirect;`
535
- - `static?: IRouteStatic;`
536
- - [ ] Save file
537
-
538
- ### Step 5: Delete Handler Classes (15 minutes)
539
- - [ ] Delete file: `ts/proxies/http-proxy/handlers/redirect-handler.ts`
540
- - [ ] Delete file: `ts/proxies/http-proxy/handlers/static-handler.ts`
541
- - [ ] Open `ts/proxies/http-proxy/handlers/index.ts`
542
- - [ ] Delete all content (the file only exports RedirectHandler and StaticHandler)
543
- - [ ] Save empty file or delete it
544
-
545
- ### Step 6: Remove Handler Methods from RouteConnectionHandler (30 minutes)
546
- - [ ] Open `ts/proxies/smart-proxy/route-connection-handler.ts`
547
- - [ ] Find and delete entire `handleRedirectAction` method (around line 723)
548
- - [ ] Find and delete entire `handleBlockAction` method (around line 750)
549
- - [ ] Find and delete entire `handleStaticAction` method (around line 773)
550
- - [ ] Remove imports at top:
551
- - `import { RedirectHandler, StaticHandler } from '../http-proxy/handlers/index.js';`
552
- - [ ] Save file
553
-
554
- ### Step 7: Update Switch Statement (15 minutes)
555
- - [ ] Still in `route-connection-handler.ts`
556
- - [ ] Find switch statement (around line 388)
557
- - [ ] Remove these cases:
558
- - `case 'redirect': return this.handleRedirectAction(...)`
559
- - `case 'block': return this.handleBlockAction(...)`
560
- - `case 'static': this.handleStaticAction(...); return;`
561
- - [ ] Verify only 'forward' and 'socket-handler' cases remain
562
- - [ ] Save file
563
-
564
- ### Step 8: Add New Socket Handlers to route-helpers.ts (30 minutes)
565
- - [ ] Open `ts/proxies/smart-proxy/utils/route-helpers.ts`
566
- - [ ] Add import at top: `import type { IRouteContext } from '../../../core/models/route-context.js';`
567
- - [ ] Add to SocketHandlers object:
568
- ```typescript
569
- /**
570
- * Block connection immediately
571
- */
572
- block: (message?: string) => (socket: plugins.net.Socket, context: IRouteContext) => {
573
- const finalMessage = message || `Connection blocked from ${context.clientIp}`;
574
- if (finalMessage) {
575
- socket.write(finalMessage);
576
- }
577
- socket.end();
578
- },
579
-
580
- /**
581
- * HTTP block response
582
- */
583
- httpBlock: (statusCode: number = 403, message?: string) => (socket: plugins.net.Socket, context: IRouteContext) => {
584
- const defaultMessage = `Access forbidden for ${context.domain || context.clientIp}`;
585
- const finalMessage = message || defaultMessage;
586
-
587
- const response = [
588
- `HTTP/1.1 ${statusCode} ${finalMessage}`,
589
- 'Content-Type: text/plain',
590
- `Content-Length: ${finalMessage.length}`,
591
- 'Connection: close',
592
- '',
593
- finalMessage
594
- ].join('\r\n');
595
-
596
- socket.write(response);
597
- socket.end();
598
- },
599
-
600
- /**
601
- * HTTP redirect handler
602
- */
603
- httpRedirect: (locationTemplate: string, statusCode: number = 301) => (socket: plugins.net.Socket, context: IRouteContext) => {
604
- let buffer = '';
605
-
606
- socket.once('data', (data) => {
607
- buffer += data.toString();
608
-
609
- const lines = buffer.split('\r\n');
610
- const requestLine = lines[0];
611
- const [method, path] = requestLine.split(' ');
612
-
613
- const domain = context.domain || 'localhost';
614
- const port = context.port;
615
-
616
- let finalLocation = locationTemplate
617
- .replace('{domain}', domain)
618
- .replace('{port}', String(port))
619
- .replace('{path}', path)
620
- .replace('{clientIp}', context.clientIp);
621
-
622
- const message = `Redirecting to ${finalLocation}`;
623
- const response = [
624
- `HTTP/1.1 ${statusCode} ${statusCode === 301 ? 'Moved Permanently' : 'Found'}`,
625
- `Location: ${finalLocation}`,
626
- 'Content-Type: text/plain',
627
- `Content-Length: ${message.length}`,
628
- 'Connection: close',
629
- '',
630
- message
631
- ].join('\r\n');
632
-
633
- socket.write(response);
634
- socket.end();
635
- });
636
- }
637
- ```
638
- - [x] Save file
639
-
640
- ### Step 9: Update Helper Functions (20 minutes)
641
- - [x] Still in `route-helpers.ts`
642
- - [x] Update `createHttpToHttpsRedirect` function (around line 109):
643
- - Change the action to use socket handler:
644
- ```typescript
645
- action: {
646
- type: 'socket-handler',
647
- socketHandler: SocketHandlers.httpRedirect(`https://{domain}:${httpsPort}{path}`, 301)
648
- }
649
- ```
650
- - [x] Delete entire `createStaticFileRoute` function (lines 277-322)
651
- - [x] Save file
652
-
653
- ### Step 10: Update Test Files (1.5 hours)
654
- #### 10.1 Update Socket Handler Tests
655
- - [x] Open `test/test.socket-handler.ts`
656
- - [x] Update all handler functions to accept context parameter
657
- - [x] Open `test/test.socket-handler.simple.ts`
658
- - [x] Update handler to accept context parameter
659
- - [x] Open `test/test.socket-handler-race.ts`
660
- - [x] Update handler to accept context parameter
661
-
662
- #### 10.2 Find and Update/Delete Redirect Tests
663
- - [x] Search for files containing `type: 'redirect'` in test directory
664
- - [x] For each file:
665
- - [x] If it's a redirect-specific test, delete the file
666
- - [x] If it's a mixed test, update redirect actions to use socket handlers
667
- - [x] Files to check:
668
- - [x] `test/test.route-redirects.ts` - deleted entire file
669
- - [x] `test/test.forwarding.ts` - update any redirect tests
670
- - [x] `test/test.forwarding.examples.ts` - update any redirect tests
671
- - [x] `test/test.route-config.ts` - update any redirect tests
672
-
673
- #### 10.3 Find and Update/Delete Block Tests
674
- - [x] Search for files containing `type: 'block'` in test directory
675
- - [x] Update or delete as appropriate
676
-
677
- #### 10.4 Find and Delete Static Tests
678
- - [x] Search for files containing `type: 'static'` in test directory
679
- - [x] Delete static-specific test files
680
- - [x] Remove static tests from mixed test files
681
-
682
- ### Step 11: Clean Up Imports and Exports (20 minutes)
683
- - [x] Open `ts/proxies/smart-proxy/utils/index.ts`
684
- - [x] Ensure route-helpers.ts is exported
685
- - [x] Remove any exports of deleted functions
686
- - [x] Open `ts/index.ts`
687
- - [x] Remove any exports of deleted types/interfaces
688
- - [x] Search for any remaining imports of RedirectHandler or StaticHandler
689
- - [x] Remove any found imports
690
-
691
- ### Step 12: Documentation Updates (30 minutes)
692
- - [x] Update README.md:
693
- - [x] Remove any mention of redirect, block, static action types
694
- - [x] Add examples of socket handlers with context
695
- - [x] Document the two action types: forward and socket-handler
696
- - [x] Update any JSDoc comments in modified files
697
- - [x] Add examples showing context usage
698
-
699
- ### Step 13: Final Verification (15 minutes)
700
- - [x] Run build: `pnpm build`
701
- - [x] Fix any compilation errors
702
- - [x] Run tests: `pnpm test`
703
- - [x] Fix any failing tests
704
- - [x] Search codebase for any remaining references to:
705
- - [x] 'redirect' action type
706
- - [x] 'block' action type
707
- - [x] 'static' action type
708
- - [x] RedirectHandler
709
- - [x] StaticHandler
710
- - [x] IRouteRedirect
711
- - [x] IRouteStatic
712
-
713
- ### Step 14: Test New Functionality (30 minutes)
714
- - [x] Create test for block socket handler with context
715
- - [x] Create test for httpBlock socket handler with context
716
- - [x] Create test for httpRedirect socket handler with context
717
- - [x] Verify context is properly passed in all scenarios
718
-
719
- ---
720
-
721
- ## Files to be Modified/Deleted
722
-
723
- ### Files to Modify:
724
- 1. `ts/proxies/smart-proxy/models/route-types.ts` - Update types
725
- 2. `ts/proxies/smart-proxy/route-connection-handler.ts` - Remove handlers, update switch
726
- 3. `ts/proxies/smart-proxy/utils/route-helpers.ts` - Update handlers, add new ones
727
- 4. `ts/proxies/http-proxy/handlers/index.ts` - Remove exports
728
- 5. Various test files - Update to use socket handlers
729
-
730
- ### Files to Delete:
731
- 1. `ts/proxies/http-proxy/handlers/redirect-handler.ts`
732
- 2. `ts/proxies/http-proxy/handlers/static-handler.ts`
733
- 3. `test/test.route-redirects.ts` (likely)
734
- 4. Any static-specific test files
735
-
736
- ### Test Files Requiring Updates (15 files found):
737
- - test/test.acme-http01-challenge.ts
738
- - test/test.logger-error-handling.ts
739
- - test/test.port80-management.node.ts
740
- - test/test.route-update-callback.node.ts
741
- - test/test.acme-state-manager.node.ts
742
- - test/test.acme-route-creation.ts
743
- - test/test.forwarding.ts
744
- - test/test.route-redirects.ts
745
- - test/test.forwarding.examples.ts
746
- - test/test.acme-simple.ts
747
- - test/test.acme-http-challenge.ts
748
- - test/test.certificate-provisioning.ts
749
- - test/test.route-config.ts
750
- - test/test.route-utils.ts
751
- - test/test.certificate-simple.ts
752
-
753
- ---
754
-
755
- ## Success Criteria
756
- - ✅ Only 'forward' and 'socket-handler' action types remain
757
- - ✅ Socket handlers receive IRouteContext as second parameter
758
- - ✅ All old handler code completely removed
759
- - ✅ Redirect functionality works via context-aware socket handlers
760
- - ✅ Block functionality works via context-aware socket handlers
761
- - ✅ All tests updated and passing
762
- - ✅ Documentation updated with new examples
763
- - ✅ No performance regression
764
- - ✅ Cleaner, simpler codebase