@push.rocks/smartproxy 19.6.6 → 19.6.8

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 (48) hide show
  1. package/dist_ts/core/models/wrapped-socket.d.ts +4 -0
  2. package/dist_ts/core/models/wrapped-socket.js +18 -1
  3. package/dist_ts/core/routing/matchers/path.js +3 -2
  4. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +4 -7
  5. package/dist_ts/proxies/smart-proxy/connection-manager.js +22 -22
  6. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +4 -3
  7. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +9 -9
  8. package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +68 -56
  9. package/dist_ts/proxies/smart-proxy/metrics-collector.js +252 -176
  10. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +6 -1
  11. package/dist_ts/proxies/smart-proxy/models/metrics-types.d.ts +99 -47
  12. package/dist_ts/proxies/smart-proxy/nftables-manager.d.ts +4 -4
  13. package/dist_ts/proxies/smart-proxy/nftables-manager.js +6 -6
  14. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +4 -7
  15. package/dist_ts/proxies/smart-proxy/port-manager.js +6 -9
  16. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +4 -15
  17. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +133 -130
  18. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +3 -3
  19. package/dist_ts/proxies/smart-proxy/security-manager.js +9 -9
  20. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +20 -13
  21. package/dist_ts/proxies/smart-proxy/smart-proxy.js +16 -13
  22. package/dist_ts/proxies/smart-proxy/throughput-tracker.d.ts +36 -0
  23. package/dist_ts/proxies/smart-proxy/throughput-tracker.js +117 -0
  24. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +5 -4
  25. package/dist_ts/proxies/smart-proxy/timeout-manager.js +20 -16
  26. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +3 -3
  27. package/dist_ts/proxies/smart-proxy/tls-manager.js +12 -12
  28. package/dist_ts/routing/router/http-router.js +2 -2
  29. package/package.json +1 -1
  30. package/readme.hints.md +0 -0
  31. package/readme.md +239 -73
  32. package/readme.plan.md +364 -0
  33. package/ts/core/models/wrapped-socket.ts +18 -0
  34. package/ts/core/routing/matchers/path.ts +2 -1
  35. package/ts/proxies/smart-proxy/connection-manager.ts +23 -21
  36. package/ts/proxies/smart-proxy/http-proxy-bridge.ts +9 -8
  37. package/ts/proxies/smart-proxy/metrics-collector.ts +305 -188
  38. package/ts/proxies/smart-proxy/models/interfaces.ts +8 -1
  39. package/ts/proxies/smart-proxy/models/metrics-types.ts +99 -41
  40. package/ts/proxies/smart-proxy/nftables-manager.ts +5 -5
  41. package/ts/proxies/smart-proxy/port-manager.ts +6 -14
  42. package/ts/proxies/smart-proxy/route-connection-handler.ts +141 -138
  43. package/ts/proxies/smart-proxy/security-manager.ts +8 -8
  44. package/ts/proxies/smart-proxy/smart-proxy.ts +26 -35
  45. package/ts/proxies/smart-proxy/throughput-tracker.ts +144 -0
  46. package/ts/proxies/smart-proxy/timeout-manager.ts +22 -16
  47. package/ts/proxies/smart-proxy/tls-manager.ts +11 -11
  48. package/ts/routing/router/http-router.ts +1 -1
package/readme.plan.md ADDED
@@ -0,0 +1,364 @@
1
+ # SmartProxy Metrics Improvement Plan
2
+
3
+ ## Overview
4
+
5
+ The current `getThroughputRate()` implementation calculates cumulative throughput over a 60-second window rather than providing an actual rate, making metrics misleading for monitoring systems. This plan outlines a comprehensive redesign of the metrics system to provide accurate, time-series based metrics suitable for production monitoring.
6
+
7
+ ## 1. Core Issues with Current Implementation
8
+
9
+ - **Cumulative vs Rate**: Current method accumulates all bytes from connections in the last minute rather than calculating actual throughput rate
10
+ - **No Time-Series Data**: Cannot track throughput changes over time
11
+ - **Inaccurate Estimates**: Attempting to estimate rates for older connections is fundamentally flawed
12
+ - **No Sliding Windows**: Cannot provide different time window views (1s, 10s, 60s, etc.)
13
+ - **Limited Granularity**: Only provides a single 60-second view
14
+
15
+ ## 2. Proposed Architecture
16
+
17
+ ### A. Time-Series Throughput Tracking
18
+
19
+ ```typescript
20
+ interface IThroughputSample {
21
+ timestamp: number;
22
+ bytesIn: number;
23
+ bytesOut: number;
24
+ }
25
+
26
+ class ThroughputTracker {
27
+ private samples: IThroughputSample[] = [];
28
+ private readonly MAX_SAMPLES = 3600; // 1 hour at 1 sample/second
29
+ private lastSampleTime: number = 0;
30
+ private accumulatedBytesIn: number = 0;
31
+ private accumulatedBytesOut: number = 0;
32
+
33
+ // Called on every data transfer
34
+ public recordBytes(bytesIn: number, bytesOut: number): void {
35
+ this.accumulatedBytesIn += bytesIn;
36
+ this.accumulatedBytesOut += bytesOut;
37
+ }
38
+
39
+ // Called periodically (every second)
40
+ public takeSample(): void {
41
+ const now = Date.now();
42
+
43
+ // Record accumulated bytes since last sample
44
+ this.samples.push({
45
+ timestamp: now,
46
+ bytesIn: this.accumulatedBytesIn,
47
+ bytesOut: this.accumulatedBytesOut
48
+ });
49
+
50
+ // Reset accumulators
51
+ this.accumulatedBytesIn = 0;
52
+ this.accumulatedBytesOut = 0;
53
+
54
+ // Trim old samples
55
+ const cutoff = now - 3600000; // 1 hour
56
+ this.samples = this.samples.filter(s => s.timestamp > cutoff);
57
+ }
58
+
59
+ // Get rate over specified window
60
+ public getRate(windowSeconds: number): { bytesInPerSec: number; bytesOutPerSec: number } {
61
+ const now = Date.now();
62
+ const windowStart = now - (windowSeconds * 1000);
63
+
64
+ const relevantSamples = this.samples.filter(s => s.timestamp > windowStart);
65
+
66
+ if (relevantSamples.length === 0) {
67
+ return { bytesInPerSec: 0, bytesOutPerSec: 0 };
68
+ }
69
+
70
+ const totalBytesIn = relevantSamples.reduce((sum, s) => sum + s.bytesIn, 0);
71
+ const totalBytesOut = relevantSamples.reduce((sum, s) => sum + s.bytesOut, 0);
72
+
73
+ const actualWindow = (now - relevantSamples[0].timestamp) / 1000;
74
+
75
+ return {
76
+ bytesInPerSec: Math.round(totalBytesIn / actualWindow),
77
+ bytesOutPerSec: Math.round(totalBytesOut / actualWindow)
78
+ };
79
+ }
80
+ }
81
+ ```
82
+
83
+ ### B. Connection-Level Byte Tracking
84
+
85
+ ```typescript
86
+ // In ConnectionRecord, add:
87
+ interface IConnectionRecord {
88
+ // ... existing fields ...
89
+
90
+ // Byte counters with timestamps
91
+ bytesReceivedHistory: Array<{ timestamp: number; bytes: number }>;
92
+ bytesSentHistory: Array<{ timestamp: number; bytes: number }>;
93
+
94
+ // For efficiency, could use circular buffer
95
+ lastBytesReceivedUpdate: number;
96
+ lastBytesSentUpdate: number;
97
+ }
98
+ ```
99
+
100
+ ### C. Enhanced Metrics Interface
101
+
102
+ ```typescript
103
+ interface IMetrics {
104
+ // Connection metrics
105
+ connections: {
106
+ active(): number;
107
+ total(): number;
108
+ byRoute(): Map<string, number>;
109
+ byIP(): Map<string, number>;
110
+ topIPs(limit?: number): Array<{ ip: string; count: number }>;
111
+ };
112
+
113
+ // Throughput metrics (bytes per second)
114
+ throughput: {
115
+ instant(): { in: number; out: number }; // Last 1 second
116
+ recent(): { in: number; out: number }; // Last 10 seconds
117
+ average(): { in: number; out: number }; // Last 60 seconds
118
+ custom(seconds: number): { in: number; out: number };
119
+ history(seconds: number): Array<{ timestamp: number; in: number; out: number }>;
120
+ byRoute(windowSeconds?: number): Map<string, { in: number; out: number }>;
121
+ byIP(windowSeconds?: number): Map<string, { in: number; out: number }>;
122
+ };
123
+
124
+ // Request metrics
125
+ requests: {
126
+ perSecond(): number;
127
+ perMinute(): number;
128
+ total(): number;
129
+ };
130
+
131
+ // Cumulative totals
132
+ totals: {
133
+ bytesIn(): number;
134
+ bytesOut(): number;
135
+ connections(): number;
136
+ };
137
+
138
+ // Performance metrics
139
+ percentiles: {
140
+ connectionDuration(): { p50: number; p95: number; p99: number };
141
+ bytesTransferred(): {
142
+ in: { p50: number; p95: number; p99: number };
143
+ out: { p50: number; p95: number; p99: number };
144
+ };
145
+ };
146
+ }
147
+ ```
148
+
149
+ ## 3. Implementation Plan
150
+
151
+ ### Current Status
152
+ - **Phase 1**: ~90% complete (core functionality implemented, tests need fixing)
153
+ - **Phase 2**: ~60% complete (main features done, percentiles pending)
154
+ - **Phase 3**: ~40% complete (basic optimizations in place)
155
+ - **Phase 4**: 0% complete (export formats not started)
156
+
157
+ ### Phase 1: Core Throughput Tracking (Week 1)
158
+ - [x] Implement `ThroughputTracker` class
159
+ - [x] Integrate byte recording into socket data handlers
160
+ - [x] Add periodic sampling (1-second intervals)
161
+ - [x] Update `getThroughputRate()` to use time-series data (replaced with new clean API)
162
+ - [ ] Add unit tests for throughput tracking
163
+
164
+ ### Phase 2: Enhanced Metrics (Week 2)
165
+ - [x] Add configurable time windows (1s, 10s, 60s, 5m, etc.)
166
+ - [ ] Implement percentile calculations
167
+ - [x] Add route-specific and IP-specific throughput tracking
168
+ - [x] Create historical data access methods
169
+ - [ ] Add integration tests
170
+
171
+ ### Phase 3: Performance Optimization (Week 3)
172
+ - [x] Use circular buffers for efficiency
173
+ - [ ] Implement data aggregation for longer time windows
174
+ - [x] Add configurable retention periods
175
+ - [ ] Optimize memory usage
176
+ - [ ] Add performance benchmarks
177
+
178
+ ### Phase 4: Export Formats (Week 4)
179
+ - [ ] Add Prometheus metric format with proper metric types
180
+ - [ ] Add StatsD format support
181
+ - [ ] Add JSON export with metadata
182
+ - [ ] Create OpenMetrics compatibility
183
+ - [ ] Add documentation and examples
184
+
185
+ ## 4. Key Design Decisions
186
+
187
+ ### A. Sampling Strategy
188
+ - **1-second samples** for fine-grained data
189
+ - **Aggregate to 1-minute** for longer retention
190
+ - **Keep 1 hour** of second-level data
191
+ - **Keep 24 hours** of minute-level data
192
+
193
+ ### B. Memory Management
194
+ - **Circular buffers** for fixed memory usage
195
+ - **Configurable retention** periods
196
+ - **Lazy aggregation** for older data
197
+ - **Efficient data structures** (typed arrays for samples)
198
+
199
+ ### C. Performance Considerations
200
+ - **Batch updates** during high throughput
201
+ - **Debounced calculations** for expensive metrics
202
+ - **Cached results** with TTL
203
+ - **Worker thread** option for heavy calculations
204
+
205
+ ## 5. Configuration Options
206
+
207
+ ```typescript
208
+ interface IMetricsConfig {
209
+ enabled: boolean;
210
+
211
+ // Sampling configuration
212
+ sampleIntervalMs: number; // Default: 1000 (1 second)
213
+ retentionSeconds: number; // Default: 3600 (1 hour)
214
+
215
+ // Performance tuning
216
+ enableDetailedTracking: boolean; // Per-connection byte history
217
+ enablePercentiles: boolean; // Calculate percentiles
218
+ cacheResultsMs: number; // Cache expensive calculations
219
+
220
+ // Export configuration
221
+ prometheusEnabled: boolean;
222
+ prometheusPath: string; // Default: /metrics
223
+ prometheusPrefix: string; // Default: smartproxy_
224
+ }
225
+ ```
226
+
227
+ ## 6. Example Usage
228
+
229
+ ```typescript
230
+ const proxy = new SmartProxy({
231
+ metrics: {
232
+ enabled: true,
233
+ sampleIntervalMs: 1000,
234
+ enableDetailedTracking: true
235
+ }
236
+ });
237
+
238
+ // Get metrics instance
239
+ const metrics = proxy.getMetrics();
240
+
241
+ // Connection metrics
242
+ console.log(`Active connections: ${metrics.connections.active()}`);
243
+ console.log(`Total connections: ${metrics.connections.total()}`);
244
+
245
+ // Throughput metrics
246
+ const instant = metrics.throughput.instant();
247
+ console.log(`Current: ${instant.in} bytes/sec in, ${instant.out} bytes/sec out`);
248
+
249
+ const recent = metrics.throughput.recent(); // Last 10 seconds
250
+ const average = metrics.throughput.average(); // Last 60 seconds
251
+
252
+ // Custom time window
253
+ const custom = metrics.throughput.custom(30); // Last 30 seconds
254
+
255
+ // Historical data for graphing
256
+ const history = metrics.throughput.history(300); // Last 5 minutes
257
+ history.forEach(point => {
258
+ console.log(`${new Date(point.timestamp)}: ${point.in} bytes/sec in, ${point.out} bytes/sec out`);
259
+ });
260
+
261
+ // Top routes by throughput
262
+ const routeThroughput = metrics.throughput.byRoute(60);
263
+ routeThroughput.forEach((stats, route) => {
264
+ console.log(`Route ${route}: ${stats.in} bytes/sec in, ${stats.out} bytes/sec out`);
265
+ });
266
+
267
+ // Request metrics
268
+ console.log(`RPS: ${metrics.requests.perSecond()}`);
269
+ console.log(`RPM: ${metrics.requests.perMinute()}`);
270
+
271
+ // Totals
272
+ console.log(`Total bytes in: ${metrics.totals.bytesIn()}`);
273
+ console.log(`Total bytes out: ${metrics.totals.bytesOut()}`);
274
+ ```
275
+
276
+ ## 7. Prometheus Export Example
277
+
278
+ ```
279
+ # HELP smartproxy_throughput_bytes_per_second Current throughput in bytes per second
280
+ # TYPE smartproxy_throughput_bytes_per_second gauge
281
+ smartproxy_throughput_bytes_per_second{direction="in",window="1s"} 1234567
282
+ smartproxy_throughput_bytes_per_second{direction="out",window="1s"} 987654
283
+ smartproxy_throughput_bytes_per_second{direction="in",window="10s"} 1134567
284
+ smartproxy_throughput_bytes_per_second{direction="out",window="10s"} 887654
285
+
286
+ # HELP smartproxy_bytes_total Total bytes transferred
287
+ # TYPE smartproxy_bytes_total counter
288
+ smartproxy_bytes_total{direction="in"} 123456789
289
+ smartproxy_bytes_total{direction="out"} 98765432
290
+
291
+ # HELP smartproxy_active_connections Current number of active connections
292
+ # TYPE smartproxy_active_connections gauge
293
+ smartproxy_active_connections 42
294
+
295
+ # HELP smartproxy_connection_duration_seconds Connection duration in seconds
296
+ # TYPE smartproxy_connection_duration_seconds histogram
297
+ smartproxy_connection_duration_seconds_bucket{le="0.1"} 100
298
+ smartproxy_connection_duration_seconds_bucket{le="1"} 500
299
+ smartproxy_connection_duration_seconds_bucket{le="10"} 800
300
+ smartproxy_connection_duration_seconds_bucket{le="+Inf"} 850
301
+ smartproxy_connection_duration_seconds_sum 4250
302
+ smartproxy_connection_duration_seconds_count 850
303
+ ```
304
+
305
+ ## 8. Migration Strategy
306
+
307
+ ### Breaking Changes
308
+ - Completely replace the old metrics API with the new clean design
309
+ - Remove all `get*` prefixed methods in favor of grouped properties
310
+ - Use simple `{ in, out }` objects instead of verbose property names
311
+ - Provide clear migration guide in documentation
312
+
313
+ ### Implementation Approach
314
+ 1. ✅ Create new `ThroughputTracker` class for time-series data
315
+ 2. ✅ Implement new `IMetrics` interface with clean API
316
+ 3. ✅ Replace `MetricsCollector` implementation entirely
317
+ 4. ✅ Update all references to use new API
318
+ 5. ⚠️ Add comprehensive tests for accuracy validation (partial)
319
+
320
+ ### Additional Refactoring Completed
321
+ - Refactored all SmartProxy components to use cleaner dependency pattern
322
+ - Components now receive only `SmartProxy` instance instead of individual dependencies
323
+ - Access to other components via `this.smartProxy.componentName`
324
+ - Significantly simplified constructor signatures across the codebase
325
+
326
+ ## 9. Success Metrics
327
+
328
+ - **Accuracy**: Throughput metrics accurate within 1% of actual
329
+ - **Performance**: < 1% CPU overhead for metrics collection
330
+ - **Memory**: < 10MB memory usage for 1 hour of data
331
+ - **Latency**: < 1ms to retrieve any metric
332
+ - **Reliability**: No metrics data loss under load
333
+
334
+ ## 10. Future Enhancements
335
+
336
+ ### Phase 5: Advanced Analytics
337
+ - Anomaly detection for traffic patterns
338
+ - Predictive analytics for capacity planning
339
+ - Correlation analysis between routes
340
+ - Real-time alerting integration
341
+
342
+ ### Phase 6: Distributed Metrics
343
+ - Metrics aggregation across multiple proxies
344
+ - Distributed time-series storage
345
+ - Cross-proxy analytics
346
+ - Global dashboard support
347
+
348
+ ## 11. Risks and Mitigations
349
+
350
+ ### Risk: Memory Usage
351
+ - **Mitigation**: Circular buffers and configurable retention
352
+ - **Monitoring**: Track memory usage per metric type
353
+
354
+ ### Risk: Performance Impact
355
+ - **Mitigation**: Efficient data structures and caching
356
+ - **Testing**: Load test with metrics enabled/disabled
357
+
358
+ ### Risk: Data Accuracy
359
+ - **Mitigation**: Atomic operations and proper synchronization
360
+ - **Validation**: Compare with external monitoring tools
361
+
362
+ ## Conclusion
363
+
364
+ This plan transforms SmartProxy's metrics from a basic cumulative system to a comprehensive, time-series based monitoring solution suitable for production environments. The phased approach ensures minimal disruption while delivering immediate value through accurate throughput measurements.
@@ -52,6 +52,9 @@ export class WrappedSocket {
52
52
  if (prop === 'setProxyInfo') {
53
53
  return target.setProxyInfo.bind(target);
54
54
  }
55
+ if (prop === 'remoteFamily') {
56
+ return target.remoteFamily;
57
+ }
55
58
 
56
59
  // For all other properties/methods, delegate to the underlying socket
57
60
  const value = target.socket[prop as keyof plugins.net.Socket];
@@ -89,6 +92,21 @@ export class WrappedSocket {
89
92
  return !!this.realClientIP;
90
93
  }
91
94
 
95
+ /**
96
+ * Returns the address family of the remote IP
97
+ */
98
+ get remoteFamily(): string | undefined {
99
+ const ip = this.realClientIP || this.socket.remoteAddress;
100
+ if (!ip) return undefined;
101
+
102
+ // Check if it's IPv6
103
+ if (ip.includes(':')) {
104
+ return 'IPv6';
105
+ }
106
+ // Otherwise assume IPv4
107
+ return 'IPv4';
108
+ }
109
+
92
110
  /**
93
111
  * Updates the real client information (called after parsing PROXY protocol)
94
112
  */
@@ -95,7 +95,8 @@ export class PathMatcher implements IMatcher<IPathMatchResult> {
95
95
  if (normalizedPattern.includes('*') && match.length > paramNames.length + 1) {
96
96
  const wildcardCapture = match[match.length - 1];
97
97
  if (wildcardCapture) {
98
- pathRemainder = wildcardCapture;
98
+ // Ensure pathRemainder includes leading slash if it had one
99
+ pathRemainder = wildcardCapture.startsWith('/') ? wildcardCapture : '/' + wildcardCapture;
99
100
  pathMatch = normalizedPath.substring(0, normalizedPath.length - wildcardCapture.length);
100
101
  }
101
102
  }
@@ -1,11 +1,10 @@
1
1
  import * as plugins from '../../plugins.js';
2
- import type { IConnectionRecord, ISmartProxyOptions } from './models/interfaces.js';
3
- import { SecurityManager } from './security-manager.js';
4
- import { TimeoutManager } from './timeout-manager.js';
2
+ import type { IConnectionRecord } from './models/interfaces.js';
5
3
  import { logger } from '../../core/utils/logger.js';
6
4
  import { LifecycleComponent } from '../../core/utils/lifecycle-component.js';
7
5
  import { cleanupSocket } from '../../core/utils/socket-utils.js';
8
6
  import { WrappedSocket } from '../../core/models/wrapped-socket.js';
7
+ import type { SmartProxy } from './smart-proxy.js';
9
8
 
10
9
  /**
11
10
  * Manages connection lifecycle, tracking, and cleanup with performance optimizations
@@ -29,17 +28,15 @@ export class ConnectionManager extends LifecycleComponent {
29
28
  private cleanupTimer: NodeJS.Timeout | null = null;
30
29
 
31
30
  constructor(
32
- private settings: ISmartProxyOptions,
33
- private securityManager: SecurityManager,
34
- private timeoutManager: TimeoutManager
31
+ private smartProxy: SmartProxy
35
32
  ) {
36
33
  super();
37
34
 
38
35
  // Set reasonable defaults for connection limits
39
- this.maxConnections = settings.defaults?.security?.maxConnections || 10000;
36
+ this.maxConnections = smartProxy.settings.defaults?.security?.maxConnections || 10000;
40
37
 
41
38
  // Start inactivity check timer if not disabled
42
- if (!settings.disableInactivityCheck) {
39
+ if (!smartProxy.settings.disableInactivityCheck) {
43
40
  this.startInactivityCheckTimer();
44
41
  }
45
42
  }
@@ -108,10 +105,10 @@ export class ConnectionManager extends LifecycleComponent {
108
105
  */
109
106
  public trackConnection(connectionId: string, record: IConnectionRecord): void {
110
107
  this.connectionRecords.set(connectionId, record);
111
- this.securityManager.trackConnectionByIP(record.remoteIP, connectionId);
108
+ this.smartProxy.securityManager.trackConnectionByIP(record.remoteIP, connectionId);
112
109
 
113
110
  // Schedule inactivity check
114
- if (!this.settings.disableInactivityCheck) {
111
+ if (!this.smartProxy.settings.disableInactivityCheck) {
115
112
  this.scheduleInactivityCheck(connectionId, record);
116
113
  }
117
114
  }
@@ -120,14 +117,14 @@ export class ConnectionManager extends LifecycleComponent {
120
117
  * Schedule next inactivity check for a connection
121
118
  */
122
119
  private scheduleInactivityCheck(connectionId: string, record: IConnectionRecord): void {
123
- let timeout = this.settings.inactivityTimeout!;
120
+ let timeout = this.smartProxy.settings.inactivityTimeout!;
124
121
 
125
122
  if (record.hasKeepAlive) {
126
- if (this.settings.keepAliveTreatment === 'immortal') {
123
+ if (this.smartProxy.settings.keepAliveTreatment === 'immortal') {
127
124
  // Don't schedule check for immortal connections
128
125
  return;
129
- } else if (this.settings.keepAliveTreatment === 'extended') {
130
- const multiplier = this.settings.keepAliveInactivityMultiplier || 6;
126
+ } else if (this.smartProxy.settings.keepAliveTreatment === 'extended') {
127
+ const multiplier = this.smartProxy.settings.keepAliveInactivityMultiplier || 6;
131
128
  timeout = timeout * multiplier;
132
129
  }
133
130
  }
@@ -172,7 +169,7 @@ export class ConnectionManager extends LifecycleComponent {
172
169
  * Initiates cleanup once for a connection
173
170
  */
174
171
  public initiateCleanupOnce(record: IConnectionRecord, reason: string = 'normal'): void {
175
- if (this.settings.enableDetailedLogging) {
172
+ if (this.smartProxy.settings.enableDetailedLogging) {
176
173
  logger.log('info', `Connection cleanup initiated`, {
177
174
  connectionId: record.id,
178
175
  remoteIP: record.remoteIP,
@@ -253,7 +250,12 @@ export class ConnectionManager extends LifecycleComponent {
253
250
  this.nextInactivityCheck.delete(record.id);
254
251
 
255
252
  // Track connection termination
256
- this.securityManager.removeConnectionByIP(record.remoteIP, record.id);
253
+ this.smartProxy.securityManager.removeConnectionByIP(record.remoteIP, record.id);
254
+
255
+ // Remove from metrics tracking
256
+ if (this.smartProxy.metricsCollector) {
257
+ this.smartProxy.metricsCollector.removeConnection(record.id);
258
+ }
257
259
 
258
260
  if (record.cleanupTimer) {
259
261
  clearTimeout(record.cleanupTimer);
@@ -334,7 +336,7 @@ export class ConnectionManager extends LifecycleComponent {
334
336
  this.connectionRecords.delete(record.id);
335
337
 
336
338
  // Log connection details
337
- if (this.settings.enableDetailedLogging) {
339
+ if (this.smartProxy.settings.enableDetailedLogging) {
338
340
  logger.log('info',
339
341
  `Connection terminated: ${record.remoteIP}:${record.localPort} (${reason}) - ` +
340
342
  `${plugins.prettyMs(duration)}, IN: ${record.bytesReceived}B, OUT: ${record.bytesSent}B`,
@@ -414,7 +416,7 @@ export class ConnectionManager extends LifecycleComponent {
414
416
  */
415
417
  public handleClose(side: 'incoming' | 'outgoing', record: IConnectionRecord) {
416
418
  return () => {
417
- if (this.settings.enableDetailedLogging) {
419
+ if (this.smartProxy.settings.enableDetailedLogging) {
418
420
  logger.log('info', `Connection closed on ${side} side`, {
419
421
  connectionId: record.id,
420
422
  side,
@@ -553,9 +555,9 @@ export class ConnectionManager extends LifecycleComponent {
553
555
  const inactivityTime = now - record.lastActivity;
554
556
 
555
557
  // Use extended timeout for extended-treatment keep-alive connections
556
- let effectiveTimeout = this.settings.inactivityTimeout!;
557
- if (record.hasKeepAlive && this.settings.keepAliveTreatment === 'extended') {
558
- const multiplier = this.settings.keepAliveInactivityMultiplier || 6;
558
+ let effectiveTimeout = this.smartProxy.settings.inactivityTimeout!;
559
+ if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'extended') {
560
+ const multiplier = this.smartProxy.settings.keepAliveInactivityMultiplier || 6;
559
561
  effectiveTimeout = effectiveTimeout * multiplier;
560
562
  }
561
563
 
@@ -1,14 +1,15 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import { HttpProxy } from '../http-proxy/index.js';
3
3
  import { setupBidirectionalForwarding } from '../../core/utils/socket-utils.js';
4
- import type { IConnectionRecord, ISmartProxyOptions } from './models/interfaces.js';
4
+ import type { IConnectionRecord } from './models/interfaces.js';
5
5
  import type { IRouteConfig } from './models/route-types.js';
6
6
  import { WrappedSocket } from '../../core/models/wrapped-socket.js';
7
+ import type { SmartProxy } from './smart-proxy.js';
7
8
 
8
9
  export class HttpProxyBridge {
9
10
  private httpProxy: HttpProxy | null = null;
10
11
 
11
- constructor(private settings: ISmartProxyOptions) {}
12
+ constructor(private smartProxy: SmartProxy) {}
12
13
 
13
14
  /**
14
15
  * Get the HttpProxy instance
@@ -21,18 +22,18 @@ export class HttpProxyBridge {
21
22
  * Initialize HttpProxy instance
22
23
  */
23
24
  public async initialize(): Promise<void> {
24
- if (!this.httpProxy && this.settings.useHttpProxy && this.settings.useHttpProxy.length > 0) {
25
+ if (!this.httpProxy && this.smartProxy.settings.useHttpProxy && this.smartProxy.settings.useHttpProxy.length > 0) {
25
26
  const httpProxyOptions: any = {
26
- port: this.settings.httpProxyPort!,
27
+ port: this.smartProxy.settings.httpProxyPort!,
27
28
  portProxyIntegration: true,
28
- logLevel: this.settings.enableDetailedLogging ? 'debug' : 'info'
29
+ logLevel: this.smartProxy.settings.enableDetailedLogging ? 'debug' : 'info'
29
30
  };
30
31
 
31
32
  this.httpProxy = new HttpProxy(httpProxyOptions);
32
- console.log(`Initialized HttpProxy on port ${this.settings.httpProxyPort}`);
33
+ console.log(`Initialized HttpProxy on port ${this.smartProxy.settings.httpProxyPort}`);
33
34
 
34
35
  // Apply route configurations to HttpProxy
35
- await this.syncRoutesToHttpProxy(this.settings.routes || []);
36
+ await this.syncRoutesToHttpProxy(this.smartProxy.settings.routes || []);
36
37
  }
37
38
  }
38
39
 
@@ -51,7 +52,7 @@ export class HttpProxyBridge {
51
52
  : [route.match.ports];
52
53
 
53
54
  return routePorts.some(port =>
54
- this.settings.useHttpProxy?.includes(port)
55
+ this.smartProxy.settings.useHttpProxy?.includes(port)
55
56
  );
56
57
  })
57
58
  .map(route => this.routeToHttpProxyConfig(route));