@push.rocks/smartproxy 19.6.12 → 19.6.14

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 (34) hide show
  1. package/dist_ts/core/utils/log-deduplicator.d.ts +36 -0
  2. package/dist_ts/core/utils/log-deduplicator.js +224 -0
  3. package/dist_ts/core/utils/shared-security-manager.d.ts +2 -1
  4. package/dist_ts/core/utils/shared-security-manager.js +22 -2
  5. package/dist_ts/proxies/http-proxy/http-proxy.d.ts +1 -0
  6. package/dist_ts/proxies/http-proxy/http-proxy.js +94 -9
  7. package/dist_ts/proxies/http-proxy/models/types.d.ts +2 -0
  8. package/dist_ts/proxies/http-proxy/models/types.js +1 -1
  9. package/dist_ts/proxies/http-proxy/security-manager.d.ts +42 -1
  10. package/dist_ts/proxies/http-proxy/security-manager.js +121 -2
  11. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +14 -0
  12. package/dist_ts/proxies/smart-proxy/connection-manager.js +74 -26
  13. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +5 -1
  14. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +1 -0
  15. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +24 -8
  16. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +9 -0
  17. package/dist_ts/proxies/smart-proxy/security-manager.js +63 -1
  18. package/dist_ts/proxies/smart-proxy/smart-proxy.js +4 -1
  19. package/dist_ts/proxies/smart-proxy/throughput-tracker.js +8 -10
  20. package/package.json +1 -1
  21. package/readme.hints.md +121 -1
  22. package/readme.plan.md +34 -353
  23. package/ts/core/utils/log-deduplicator.ts +280 -0
  24. package/ts/core/utils/shared-security-manager.ts +24 -1
  25. package/ts/proxies/http-proxy/http-proxy.ts +129 -9
  26. package/ts/proxies/http-proxy/models/types.ts +4 -0
  27. package/ts/proxies/http-proxy/security-manager.ts +136 -1
  28. package/ts/proxies/smart-proxy/connection-manager.ts +93 -27
  29. package/ts/proxies/smart-proxy/http-proxy-bridge.ts +5 -0
  30. package/ts/proxies/smart-proxy/models/interfaces.ts +1 -0
  31. package/ts/proxies/smart-proxy/route-connection-handler.ts +45 -14
  32. package/ts/proxies/smart-proxy/security-manager.ts +76 -1
  33. package/ts/proxies/smart-proxy/smart-proxy.ts +4 -0
  34. package/ts/proxies/smart-proxy/throughput-tracker.ts +7 -13
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Log deduplication utility to reduce log spam for repetitive events
3
+ */
4
+ export declare class LogDeduplicator {
5
+ private globalFlushTimer?;
6
+ private aggregatedEvents;
7
+ private flushInterval;
8
+ private maxBatchSize;
9
+ constructor(flushInterval?: number);
10
+ /**
11
+ * Log a deduplicated event
12
+ * @param key - Aggregation key (e.g., 'connection-rejected', 'cleanup-batch')
13
+ * @param level - Log level
14
+ * @param message - Log message template
15
+ * @param data - Additional data
16
+ * @param dedupeKey - Deduplication key within the aggregation (e.g., IP address, reason)
17
+ */
18
+ log(key: string, level: 'info' | 'warn' | 'error' | 'debug', message: string, data?: any, dedupeKey?: string): void;
19
+ /**
20
+ * Flush aggregated events for a specific key
21
+ */
22
+ flush(key: string): void;
23
+ /**
24
+ * Flush all pending events
25
+ */
26
+ flushAll(): void;
27
+ private flushConnectionRejections;
28
+ private flushConnectionCleanups;
29
+ private flushIPRejections;
30
+ private flushGeneric;
31
+ /**
32
+ * Cleanup and stop deduplication
33
+ */
34
+ cleanup(): void;
35
+ }
36
+ export declare const connectionLogDeduplicator: LogDeduplicator;
@@ -0,0 +1,224 @@
1
+ import { logger } from './logger.js';
2
+ /**
3
+ * Log deduplication utility to reduce log spam for repetitive events
4
+ */
5
+ export class LogDeduplicator {
6
+ constructor(flushInterval) {
7
+ this.aggregatedEvents = new Map();
8
+ this.flushInterval = 5000; // 5 seconds
9
+ this.maxBatchSize = 100;
10
+ if (flushInterval) {
11
+ this.flushInterval = flushInterval;
12
+ }
13
+ // Set up global periodic flush to ensure logs are emitted regularly
14
+ this.globalFlushTimer = setInterval(() => {
15
+ this.flushAll();
16
+ }, this.flushInterval * 2); // Flush everything every 2x the normal interval
17
+ if (this.globalFlushTimer.unref) {
18
+ this.globalFlushTimer.unref();
19
+ }
20
+ }
21
+ /**
22
+ * Log a deduplicated event
23
+ * @param key - Aggregation key (e.g., 'connection-rejected', 'cleanup-batch')
24
+ * @param level - Log level
25
+ * @param message - Log message template
26
+ * @param data - Additional data
27
+ * @param dedupeKey - Deduplication key within the aggregation (e.g., IP address, reason)
28
+ */
29
+ log(key, level, message, data, dedupeKey) {
30
+ const eventKey = dedupeKey || message;
31
+ const now = Date.now();
32
+ if (!this.aggregatedEvents.has(key)) {
33
+ this.aggregatedEvents.set(key, {
34
+ key,
35
+ events: new Map(),
36
+ flushTimer: undefined
37
+ });
38
+ }
39
+ const aggregated = this.aggregatedEvents.get(key);
40
+ if (aggregated.events.has(eventKey)) {
41
+ const event = aggregated.events.get(eventKey);
42
+ event.count++;
43
+ event.lastSeen = now;
44
+ if (data) {
45
+ event.data = { ...event.data, ...data };
46
+ }
47
+ }
48
+ else {
49
+ aggregated.events.set(eventKey, {
50
+ level,
51
+ message,
52
+ data,
53
+ count: 1,
54
+ firstSeen: now,
55
+ lastSeen: now
56
+ });
57
+ }
58
+ // Check if we should flush due to size
59
+ if (aggregated.events.size >= this.maxBatchSize) {
60
+ this.flush(key);
61
+ }
62
+ else if (!aggregated.flushTimer) {
63
+ // Schedule flush
64
+ aggregated.flushTimer = setTimeout(() => {
65
+ this.flush(key);
66
+ }, this.flushInterval);
67
+ if (aggregated.flushTimer.unref) {
68
+ aggregated.flushTimer.unref();
69
+ }
70
+ }
71
+ }
72
+ /**
73
+ * Flush aggregated events for a specific key
74
+ */
75
+ flush(key) {
76
+ const aggregated = this.aggregatedEvents.get(key);
77
+ if (!aggregated || aggregated.events.size === 0) {
78
+ return;
79
+ }
80
+ if (aggregated.flushTimer) {
81
+ clearTimeout(aggregated.flushTimer);
82
+ aggregated.flushTimer = undefined;
83
+ }
84
+ // Emit aggregated log based on the key
85
+ switch (key) {
86
+ case 'connection-rejected':
87
+ this.flushConnectionRejections(aggregated);
88
+ break;
89
+ case 'connection-cleanup':
90
+ this.flushConnectionCleanups(aggregated);
91
+ break;
92
+ case 'ip-rejected':
93
+ this.flushIPRejections(aggregated);
94
+ break;
95
+ default:
96
+ this.flushGeneric(aggregated);
97
+ }
98
+ // Clear events
99
+ aggregated.events.clear();
100
+ }
101
+ /**
102
+ * Flush all pending events
103
+ */
104
+ flushAll() {
105
+ for (const key of this.aggregatedEvents.keys()) {
106
+ this.flush(key);
107
+ }
108
+ }
109
+ flushConnectionRejections(aggregated) {
110
+ const totalCount = Array.from(aggregated.events.values()).reduce((sum, e) => sum + e.count, 0);
111
+ const byReason = new Map();
112
+ for (const [, event] of aggregated.events) {
113
+ const reason = event.data?.reason || 'unknown';
114
+ byReason.set(reason, (byReason.get(reason) || 0) + event.count);
115
+ }
116
+ const reasonSummary = Array.from(byReason.entries())
117
+ .sort((a, b) => b[1] - a[1])
118
+ .map(([reason, count]) => `${reason}: ${count}`)
119
+ .join(', ');
120
+ logger.log('warn', `Rejected ${totalCount} connections`, {
121
+ reasons: reasonSummary,
122
+ uniqueIPs: aggregated.events.size,
123
+ duration: Date.now() - Math.min(...Array.from(aggregated.events.values()).map(e => e.firstSeen)),
124
+ component: 'connection-dedup'
125
+ });
126
+ }
127
+ flushConnectionCleanups(aggregated) {
128
+ const totalCount = Array.from(aggregated.events.values()).reduce((sum, e) => sum + e.count, 0);
129
+ const byReason = new Map();
130
+ for (const [, event] of aggregated.events) {
131
+ const reason = event.data?.reason || 'normal';
132
+ byReason.set(reason, (byReason.get(reason) || 0) + event.count);
133
+ }
134
+ const reasonSummary = Array.from(byReason.entries())
135
+ .sort((a, b) => b[1] - a[1])
136
+ .slice(0, 5) // Top 5 reasons
137
+ .map(([reason, count]) => `${reason}: ${count}`)
138
+ .join(', ');
139
+ logger.log('info', `Cleaned up ${totalCount} connections`, {
140
+ reasons: reasonSummary,
141
+ duration: Date.now() - Math.min(...Array.from(aggregated.events.values()).map(e => e.firstSeen)),
142
+ component: 'connection-dedup'
143
+ });
144
+ }
145
+ flushIPRejections(aggregated) {
146
+ const byIP = new Map();
147
+ for (const [ip, event] of aggregated.events) {
148
+ if (!byIP.has(ip)) {
149
+ byIP.set(ip, { count: 0, reasons: new Set() });
150
+ }
151
+ const ipData = byIP.get(ip);
152
+ ipData.count += event.count;
153
+ if (event.data?.reason) {
154
+ ipData.reasons.add(event.data.reason);
155
+ }
156
+ }
157
+ // Log top offenders
158
+ const topOffenders = Array.from(byIP.entries())
159
+ .sort((a, b) => b[1].count - a[1].count)
160
+ .slice(0, 10)
161
+ .map(([ip, data]) => `${ip} (${data.count}x, ${Array.from(data.reasons).join('/')})`)
162
+ .join(', ');
163
+ const totalRejections = Array.from(byIP.values()).reduce((sum, data) => sum + data.count, 0);
164
+ logger.log('warn', `Rejected ${totalRejections} connections from ${byIP.size} IPs`, {
165
+ topOffenders,
166
+ duration: Date.now() - Math.min(...Array.from(aggregated.events.values()).map(e => e.firstSeen)),
167
+ component: 'ip-dedup'
168
+ });
169
+ }
170
+ flushGeneric(aggregated) {
171
+ const totalCount = Array.from(aggregated.events.values()).reduce((sum, e) => sum + e.count, 0);
172
+ const level = aggregated.events.values().next().value?.level || 'info';
173
+ // Special handling for IP cleanup events
174
+ if (aggregated.key === 'ip-cleanup') {
175
+ const totalCleaned = Array.from(aggregated.events.values()).reduce((sum, e) => {
176
+ return sum + (e.data?.cleanedIPs || 0) + (e.data?.cleanedRateLimits || 0);
177
+ }, 0);
178
+ if (totalCleaned > 0) {
179
+ logger.log(level, `IP tracking cleanup: removed ${totalCleaned} entries across ${totalCount} cleanup cycles`, {
180
+ duration: Date.now() - Math.min(...Array.from(aggregated.events.values()).map(e => e.firstSeen)),
181
+ component: 'log-dedup'
182
+ });
183
+ }
184
+ }
185
+ else {
186
+ logger.log(level, `${aggregated.key}: ${totalCount} events`, {
187
+ uniqueEvents: aggregated.events.size,
188
+ duration: Date.now() - Math.min(...Array.from(aggregated.events.values()).map(e => e.firstSeen)),
189
+ component: 'log-dedup'
190
+ });
191
+ }
192
+ }
193
+ /**
194
+ * Cleanup and stop deduplication
195
+ */
196
+ cleanup() {
197
+ this.flushAll();
198
+ if (this.globalFlushTimer) {
199
+ clearInterval(this.globalFlushTimer);
200
+ this.globalFlushTimer = undefined;
201
+ }
202
+ for (const aggregated of this.aggregatedEvents.values()) {
203
+ if (aggregated.flushTimer) {
204
+ clearTimeout(aggregated.flushTimer);
205
+ }
206
+ }
207
+ this.aggregatedEvents.clear();
208
+ }
209
+ }
210
+ // Global instance for connection-related log deduplication
211
+ export const connectionLogDeduplicator = new LogDeduplicator(5000); // 5 second batches
212
+ // Ensure logs are flushed on process exit
213
+ process.on('beforeExit', () => {
214
+ connectionLogDeduplicator.flushAll();
215
+ });
216
+ process.on('SIGINT', () => {
217
+ connectionLogDeduplicator.cleanup();
218
+ process.exit(0);
219
+ });
220
+ process.on('SIGTERM', () => {
221
+ connectionLogDeduplicator.cleanup();
222
+ process.exit(0);
223
+ });
224
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nLWRlZHVwbGljYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2NvcmUvdXRpbHMvbG9nLWRlZHVwbGljYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBaUJyQzs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBTTFCLFlBQVksYUFBc0I7UUFKMUIscUJBQWdCLEdBQWtDLElBQUksR0FBRyxFQUFFLENBQUM7UUFDNUQsa0JBQWEsR0FBVyxJQUFJLENBQUMsQ0FBQyxZQUFZO1FBQzFDLGlCQUFZLEdBQVcsR0FBRyxDQUFDO1FBR2pDLElBQUksYUFBYSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDckMsQ0FBQztRQUVELG9FQUFvRTtRQUNwRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRTtZQUN2QyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbEIsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxnREFBZ0Q7UUFFNUUsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLEdBQUcsQ0FDUixHQUFXLEVBQ1gsS0FBMEMsRUFDMUMsT0FBZSxFQUNmLElBQVUsRUFDVixTQUFrQjtRQUVsQixNQUFNLFFBQVEsR0FBRyxTQUFTLElBQUksT0FBTyxDQUFDO1FBQ3RDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUV2QixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxD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
@@ -66,9 +66,10 @@ export declare class SharedSecurityManager {
66
66
  *
67
67
  * @param route - The route to check
68
68
  * @param context - The request context
69
+ * @param routeConnectionCount - Current connection count for this route (optional)
69
70
  * @returns Whether access is allowed
70
71
  */
71
- isAllowed(route: IRouteConfig, context: IRouteContext): boolean;
72
+ isAllowed(route: IRouteConfig, context: IRouteContext, routeConnectionCount?: number): boolean;
72
73
  /**
73
74
  * Check if a client IP is allowed for a route
74
75
  *
@@ -101,9 +101,10 @@ export class SharedSecurityManager {
101
101
  *
102
102
  * @param route - The route to check
103
103
  * @param context - The request context
104
+ * @param routeConnectionCount - Current connection count for this route (optional)
104
105
  * @returns Whether access is allowed
105
106
  */
106
- isAllowed(route, context) {
107
+ isAllowed(route, context, routeConnectionCount) {
107
108
  if (!route.security) {
108
109
  return true; // No security restrictions
109
110
  }
@@ -112,6 +113,13 @@ export class SharedSecurityManager {
112
113
  this.logger?.debug?.(`IP ${context.clientIp} is blocked for route ${route.name || 'unnamed'}`);
113
114
  return false;
114
115
  }
116
+ // --- Route-level connection limit ---
117
+ if (route.security.maxConnections !== undefined && routeConnectionCount !== undefined) {
118
+ if (routeConnectionCount >= route.security.maxConnections) {
119
+ this.logger?.debug?.(`Route connection limit (${route.security.maxConnections}) exceeded for route ${route.name || 'unnamed'}`);
120
+ return false;
121
+ }
122
+ }
115
123
  // --- Rate limiting ---
116
124
  if (route.security.rateLimit?.enabled && !this.isWithinRateLimit(route, context)) {
117
125
  this.logger?.debug?.(`Rate limit exceeded for route ${route.name || 'unnamed'}`);
@@ -225,6 +233,18 @@ export class SharedSecurityManager {
225
233
  cleanupCaches() {
226
234
  // Clean up rate limits
227
235
  cleanupExpiredRateLimits(this.rateLimits, this.logger);
236
+ // Clean up IP connection tracking
237
+ let cleanedIPs = 0;
238
+ for (const [ip, info] of this.connectionsByIP.entries()) {
239
+ // Remove IPs with no active connections and no recent timestamps
240
+ if (info.connections.size === 0 && info.timestamps.length === 0) {
241
+ this.connectionsByIP.delete(ip);
242
+ cleanedIPs++;
243
+ }
244
+ }
245
+ if (cleanedIPs > 0 && this.logger?.debug) {
246
+ this.logger.debug(`Cleaned up ${cleanedIPs} IPs with no active connections`);
247
+ }
228
248
  // IP filter cache doesn't need cleanup (tied to routes)
229
249
  }
230
250
  /**
@@ -249,4 +269,4 @@ export class SharedSecurityManager {
249
269
  this.ipFilterCache.clear();
250
270
  }
251
271
  }
252
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLXNlY3VyaXR5LW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb3JlL3V0aWxzL3NoYXJlZC1zZWN1cml0eS1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFRNUMsT0FBTyxFQUNMLGNBQWMsRUFDZCxtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLG9CQUFvQixFQUNyQixNQUFNLHFCQUFxQixDQUFDO0FBRTdCOzs7R0FHRztBQUNILE1BQU0sT0FBTyxxQkFBcUI7SUFpQmhDOzs7OztPQUtHO0lBQ0gsWUFBWSxPQUtYLEVBQVUsTUFBd0I7UUFBeEIsV0FBTSxHQUFOLE1BQU0sQ0FBa0I7UUEzQm5DLHlCQUF5QjtRQUNqQixvQkFBZSxHQUFtQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRXBFLCtCQUErQjtRQUN2QixlQUFVLEdBQTZDLElBQUksR0FBRyxFQUFFLENBQUM7UUFFekUsOERBQThEO1FBQ3RELGtCQUFhLEdBQXNDLElBQUksR0FBRyxFQUFFLENBQUM7UUFNckUseUJBQXlCO1FBQ2pCLG9CQUFlLEdBQTBCLElBQUksQ0FBQztRQWNwRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixJQUFJLEdBQUcsQ0FBQztRQUM5RCxJQUFJLENBQUMsNEJBQTRCLEdBQUcsT0FBTyxDQUFDLDRCQUE0QixJQUFJLEdBQUcsQ0FBQztRQUVoRiw4Q0FBOEM7UUFDOUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLElBQUk7WUFDdEIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxHQUFHO1lBQ2pCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtZQUNsQixLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7U0FDckIsQ0FBQztRQUVGLGdDQUFnQztRQUNoQyxNQUFN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
272
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLXNlY3VyaXR5LW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb3JlL3V0aWxzL3NoYXJlZC1zZWN1cml0eS1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFRNUMsT0FBTyxFQUNMLGNBQWMsRUFDZCxtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLG9CQUFvQixFQUNyQixNQUFNLHFCQUFxQixDQUFDO0FBRTdCOzs7R0FHRztBQUNILE1BQU0sT0FBTyxxQkFBcUI7SUFpQmhDOzs7OztPQUtHO0lBQ0gsWUFBWSxPQUtYLEVBQVUsTUFBd0I7UUFBeEIsV0FBTSxHQUFOLE1BQU0sQ0FBa0I7UUEzQm5DLHlCQUF5QjtRQUNqQixvQkFBZSxHQUFtQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRXBFLCtCQUErQjtRQUN2QixlQUFVLEdBQTZDLElBQUksR0FBRyxFQUFFLENBQUM7UUFFekUsOERBQThEO1FBQ3RELGtCQUFhLEdBQXNDLElBQUksR0FBRyxFQUFFLENBQUM7UUFNckUseUJBQXlCO1FBQ2pCLG9CQUFlLEdBQTBCLElBQUksQ0FBQztRQWNwRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixJQUFJLEdBQUcsQ0FBQztRQUM5RCxJQUFJLENBQUMsNEJBQTRCLEdBQUcsT0FBTyxDQUFDLDRCQUE0QixJQUFJLEdBQUcsQ0FBQztRQUVoRiw4Q0FBOEM7UUFDOUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLElBQUk7WUFDdEIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxHQUFHO1lBQ2pCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtZQUNsQixLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7U0FDckIsQ0FBQztRQUVGLGdDQUFnQztRQUNoQyxNQUFN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
@@ -19,6 +19,7 @@ export declare class HttpProxy implements IMetricsTracker {
19
19
  private router;
20
20
  private routeManager;
21
21
  private functionCache;
22
+ private securityManager;
22
23
  socketMap: plugins.lik.ObjectMap<plugins.net.Socket>;
23
24
  activeContexts: Set<string>;
24
25
  connectedClients: number;
@@ -9,6 +9,8 @@ import { WebSocketHandler } from './websocket-handler.js';
9
9
  import { HttpRouter } from '../../routing/router/index.js';
10
10
  import { cleanupSocket } from '../../core/utils/socket-utils.js';
11
11
  import { FunctionCache } from './function-cache.js';
12
+ import { SecurityManager } from './security-manager.js';
13
+ import { connectionLogDeduplicator } from '../../core/utils/log-deduplicator.js';
12
14
  /**
13
15
  * HttpProxy provides a reverse proxy with TLS termination, WebSocket support,
14
16
  * automatic certificate management, and high-performance connection pooling.
@@ -78,6 +80,8 @@ export class HttpProxy {
78
80
  maxCacheSize: this.options.functionCacheSize || 1000,
79
81
  defaultTtl: this.options.functionCacheTtl || 5000
80
82
  });
83
+ // Initialize security manager
84
+ this.securityManager = new SecurityManager(this.logger, [], this.options.maxConnectionsPerIP || 100, this.options.connectionRateLimitPerMinute || 300);
81
85
  // Initialize other components
82
86
  this.certificateManager = new CertificateManager(this.options);
83
87
  this.connectionPool = new ConnectionPool(this.options);
@@ -204,36 +208,115 @@ export class HttpProxy {
204
208
  */
205
209
  setupConnectionTracking() {
206
210
  this.httpsServer.on('connection', (connection) => {
207
- // Check if max connections reached
211
+ let remoteIP = connection.remoteAddress || '';
212
+ const connectionId = Math.random().toString(36).substring(2, 15);
213
+ const isFromSmartProxy = this.options.portProxyIntegration && connection.remoteAddress?.includes('127.0.0.1');
214
+ // For SmartProxy connections, wait for CLIENT_IP header
215
+ if (isFromSmartProxy) {
216
+ let headerBuffer = Buffer.alloc(0);
217
+ let headerParsed = false;
218
+ const parseHeader = (data) => {
219
+ if (headerParsed)
220
+ return data;
221
+ headerBuffer = Buffer.concat([headerBuffer, data]);
222
+ const headerStr = headerBuffer.toString();
223
+ const headerEnd = headerStr.indexOf('\r\n');
224
+ if (headerEnd !== -1) {
225
+ const header = headerStr.substring(0, headerEnd);
226
+ if (header.startsWith('CLIENT_IP:')) {
227
+ remoteIP = header.substring(10); // Extract IP after "CLIENT_IP:"
228
+ this.logger.debug(`Extracted client IP from SmartProxy: ${remoteIP}`);
229
+ }
230
+ headerParsed = true;
231
+ // Store the real IP on the connection
232
+ connection._realRemoteIP = remoteIP;
233
+ // Validate the real IP
234
+ const ipValidation = this.securityManager.validateIP(remoteIP);
235
+ if (!ipValidation.allowed) {
236
+ connectionLogDeduplicator.log('ip-rejected', 'warn', `HttpProxy connection rejected (via SmartProxy)`, { remoteIP, reason: ipValidation.reason, component: 'http-proxy' }, remoteIP);
237
+ connection.destroy();
238
+ return null;
239
+ }
240
+ // Track connection by real IP
241
+ this.securityManager.trackConnectionByIP(remoteIP, connectionId);
242
+ // Return remaining data after header
243
+ return headerBuffer.slice(headerEnd + 2);
244
+ }
245
+ return null;
246
+ };
247
+ // Override the first data handler to parse header
248
+ const originalEmit = connection.emit;
249
+ connection.emit = function (event, ...args) {
250
+ if (event === 'data' && !headerParsed) {
251
+ const remaining = parseHeader(args[0]);
252
+ if (remaining && remaining.length > 0) {
253
+ // Call original emit with remaining data
254
+ return originalEmit.apply(connection, ['data', remaining]);
255
+ }
256
+ else if (headerParsed) {
257
+ // Header parsed but no remaining data
258
+ return true;
259
+ }
260
+ // Header not complete yet, suppress this data event
261
+ return true;
262
+ }
263
+ return originalEmit.apply(connection, [event, ...args]);
264
+ };
265
+ }
266
+ else {
267
+ // Direct connection - validate immediately
268
+ const ipValidation = this.securityManager.validateIP(remoteIP);
269
+ if (!ipValidation.allowed) {
270
+ connectionLogDeduplicator.log('ip-rejected', 'warn', `HttpProxy connection rejected`, { remoteIP, reason: ipValidation.reason, component: 'http-proxy' }, remoteIP);
271
+ connection.destroy();
272
+ return;
273
+ }
274
+ // Track connection by IP
275
+ this.securityManager.trackConnectionByIP(remoteIP, connectionId);
276
+ }
277
+ // Then check global max connections
208
278
  if (this.socketMap.getArray().length >= this.options.maxConnections) {
209
- this.logger.warn(`Max connections (${this.options.maxConnections}) reached, rejecting new connection`);
279
+ connectionLogDeduplicator.log('connection-rejected', 'warn', 'HttpProxy max connections reached', {
280
+ reason: 'global-limit',
281
+ currentConnections: this.socketMap.getArray().length,
282
+ maxConnections: this.options.maxConnections,
283
+ component: 'http-proxy'
284
+ }, 'http-proxy-global-limit');
210
285
  connection.destroy();
211
286
  return;
212
287
  }
213
- // Add connection to tracking
288
+ // Add connection to tracking with metadata
289
+ connection._connectionId = connectionId;
290
+ connection._remoteIP = remoteIP;
214
291
  this.socketMap.add(connection);
215
292
  this.connectedClients = this.socketMap.getArray().length;
216
293
  // Check for connection from SmartProxy by inspecting the source port
217
294
  const localPort = connection.localPort || 0;
218
295
  const remotePort = connection.remotePort || 0;
219
- // If this connection is from a SmartProxy (usually indicated by it coming from localhost)
220
- if (this.options.portProxyIntegration && connection.remoteAddress?.includes('127.0.0.1')) {
296
+ // If this connection is from a SmartProxy
297
+ if (isFromSmartProxy) {
221
298
  this.portProxyConnections++;
222
- this.logger.debug(`New connection from SmartProxy (local: ${localPort}, remote: ${remotePort})`);
299
+ this.logger.debug(`New connection from SmartProxy for client ${remoteIP} (local: ${localPort}, remote: ${remotePort})`);
223
300
  }
224
301
  else {
225
- this.logger.debug(`New direct connection (local: ${localPort}, remote: ${remotePort})`);
302
+ this.logger.debug(`New direct connection from ${remoteIP} (local: ${localPort}, remote: ${remotePort})`);
226
303
  }
227
304
  // Setup connection cleanup handlers
228
305
  const cleanupConnection = () => {
229
306
  if (this.socketMap.checkForObject(connection)) {
230
307
  this.socketMap.remove(connection);
231
308
  this.connectedClients = this.socketMap.getArray().length;
309
+ // Remove IP tracking
310
+ const connId = connection._connectionId;
311
+ const connIP = connection._realRemoteIP || connection._remoteIP;
312
+ if (connId && connIP) {
313
+ this.securityManager.removeConnectionByIP(connIP, connId);
314
+ }
232
315
  // If this was a SmartProxy connection, decrement the counter
233
316
  if (this.options.portProxyIntegration && connection.remoteAddress?.includes('127.0.0.1')) {
234
317
  this.portProxyConnections--;
235
318
  }
236
- this.logger.debug(`Connection closed. ${this.connectedClients} connections remaining`);
319
+ this.logger.debug(`Connection closed from ${connIP || 'unknown'}. ${this.connectedClients} connections remaining`);
237
320
  }
238
321
  };
239
322
  connection.on('close', cleanupConnection);
@@ -374,6 +457,8 @@ export class HttpProxy {
374
457
  // Close all connection pool connections
375
458
  this.connectionPool.closeAllConnections();
376
459
  // Certificate management cleanup is handled by SmartCertManager
460
+ // Flush any pending deduplicated logs
461
+ connectionLogDeduplicator.flushAll();
377
462
  // Close the HTTPS server
378
463
  return new Promise((resolve) => {
379
464
  this.httpsServer.close(() => {
@@ -414,4 +499,4 @@ export class HttpProxy {
414
499
  return this.routeManager.getRoutes();
415
500
  }
416
501
  }
417
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1wcm94eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3hpZXMvaHR0cC1wcm94eS9odHRwLXByb3h5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUNMLFlBQVksR0FDYixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxrQkFBa0IsSUFBSSxZQUFZLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQU96RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGNBQWMsRUFBd0IsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLFNBQVM7SUFDcEIsaUdBQWlHO0lBQzFGLE1BQU07UUFDWCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFvQ0Q7O09BRUc7SUFDSCxZQUFZLFVBQTZCO1FBcENsQyxXQUFNLEdBQW1CLEVBQUUsQ0FBQztRQVUzQixXQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQyxDQUFDLHNCQUFzQjtRQUl6RCxpQkFBaUI7UUFDVixjQUFTLEdBQUcsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBc0IsQ0FBQztRQUM1RCxtQkFBYyxHQUFnQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3hDLHFCQUFnQixHQUFXLENBQUMsQ0FBQztRQUM3QixjQUFTLEdBQVcsQ0FBQyxDQUFDO1FBQ3RCLG1CQUFjLEdBQVcsQ0FBQyxDQUFDO1FBQzNCLG1CQUFjLEdBQVcsQ0FBQyxDQUFDO1FBRWxDLHNDQUFzQztRQUM5Qix5QkFBb0IsR0FBVyxDQUFDLENBQUM7UUFDakMsNkJBQXdCLEdBQVcsQ0FBQyxDQUFDO1FBYTNDLHNCQUFzQjtRQUN0QixJQUFJLENBQUMsT0FBTyxHQUFHO1lBQ2IsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO1lBQ3JCLGNBQWMsRUFBRSxVQUFVLENBQUMsY0FBYyxJQUFJLEtBQUs7WUFDbEQsZ0JBQWdCLEVBQUUsVUFBVSxDQUFDLGdCQUFnQixJQUFJLE1BQU0sRUFBRSxhQUFhO1lBQ3RFLGNBQWMsRUFBRSxVQUFVLENBQUMsY0FBYyxJQUFJLEtBQUssRUFBRSxXQUFXO1lBQy9ELFFBQVEsRUFBRSxVQUFVLENBQUMsUUFBUSxJQUFJLE1BQU07WUFDdkMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJLElBQUk7Z0JBQ3ZCLFdBQVcsRUFBRSxHQUFHO2dCQUNoQixZQUFZLEVBQUUsaUNBQWlDO2dCQUMvQyxZQUFZLEVBQUUsNkJBQTZCO2dCQUMzQyxNQUFNLEVBQUUsS0FBSzthQUNkO1lBQ0Qsc0NBQXNDO1lBQ3RDLGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxFQUFFO1lBQ3ZELG9CQUFvQixFQUFFLFVBQVUsQ0FBQyxvQkFBb0IsSUFBSSxLQUFLO1lBQzlELG9DQUFvQztZQUNwQyxlQUFlLEVBQUUsVUFBVSxDQUFDLGVBQWUsSUFBSSxPQUFPO1lBQ3RELHVCQUF1QjtZQUN2QixJQUFJLEVBQUU7Z0JBQ0osT0FBTyxFQUFFLFVBQVUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxJQUFJLEtBQUs7Z0JBQzFDLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSSxFQUFFO2dCQUNqQyxZQUFZLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxZQUFZLElBQUksbUJBQW1CO2dCQUNsRSxhQUFhLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxhQUFhLElBQUksS0FBSyxFQUFFLGdDQUFnQztnQkFDeEYsa0JBQWtCLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxrQkFBa0IsSUFBSSxFQUFFO2dCQUM3RCxTQUFTLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxTQUFTLEtBQUssS0FBSyxFQUFFLGtCQUFrQjtnQkFDbkUsZ0JBQWdCLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxnQkFBZ0IsSUFBSSxTQUFTO2dCQUNoRSxtQkFBbUIsRUFBRSxVQUFVLENBQUMsSUFBSSxFQUFFLG1CQUFtQixJQUFJLEtBQUs7YUFDbkU7U0FDRixDQUFDO1FBRUYsb0JBQW9CO1FBQ3BCLElBQUksQ0FBQyxNQUFNLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFbEQsMkJBQTJCO1FBQzNCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxZQUFZLENBQUM7WUFDbkMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLHFCQUFxQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU87WUFDeEQsTUFBTSxFQUFFLEVBQUU7U0FDWCxDQUFDLENBQUM7UUFFSCw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2xELFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixJQUFJLElBQUk7WUFDcEQsVUFBVSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLElBQUksSUFBSTtTQUNsRCxDQUFDLENBQUM7UUFFSCw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxjQUFjLENBQ3RDLElBQUksQ0FBQyxPQUFPLEVBQ1osSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLFlBQVksRUFDakIsSUFBSSxDQUFDLGFBQWEsRUFDbEIsSUFBSSxDQUFDLE1BQU0sQ0FDWixDQUFDO1FBQ0YsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLENBQzFDLElBQUksQ0FBQyxPQUFPLEVBQ1osSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLE1BQU0sQ0FBQywwQ0FBMEM7U0FDdkQsQ0FBQztRQUVGLGtEQUFrRDtRQUNsRCxJQUFJLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTVDLHNDQUFzQztRQUN0QyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUMxRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ksdUJBQXVCO1FBQzVCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQ7O09BRUc7SUFDSSx1QkFBdUI7UUFDNUIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7O09BR0c7SUFDSSxnQkFBZ0I7UUFDckIsMERBQTBEO1FBQzFELElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMzQyxJQUFJLE9BQU8sSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUNoRSxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDdEIsQ0FBQztRQUNILENBQUM7UUFDRCw4QkFBOEI7UUFDOUIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUMzQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxjQUFjLENBQUMsY0FBdUIsRUFBRSxnQkFBeUIsRUFBRSxrQkFBMkI7UUFDbkcsSUFBSSxjQUFjLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1lBQzdDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDhCQUE4QixjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQ25FLENBQUM7UUFFRCxJQUFJLGdCQUFnQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7WUFFakQsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7Z0JBQ3JELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUM7WUFDMUUsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLGtCQUFrQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxPQUFPLENBQUMsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUM7WUFDckQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLGtCQUFrQixFQUFFLENBQUMsQ0FBQztZQUUxRSwwQ0FBMEM7WUFDMUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzlDLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksVUFBVTtRQUNmLE9BQU87WUFDTCxpQkFBaUIsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO1lBQ3hDLGFBQWEsRUFBRSxJQUFJLENBQUMsY0FBYztZQUNsQyxjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWM7WUFDbkMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLG9CQUFvQjtZQUMvQyx3QkFBd0IsRUFBRSxJQUFJLENBQUMsd0JBQXdCO1lBQ3ZELGtCQUFrQixFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFO1lBQ3ZELE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDeEQsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXLEVBQUU7WUFDbEMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixFQUFFLENBQUMsaUJBQWlCO1lBQzdFLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRTtTQUM3QyxDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLEtBQUs7UUFDaEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFNUIsNENBQTRDO1FBQzVDLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FDakQ7WUFDRSxHQUFHLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixFQUFFLENBQUMsR0FBRztZQUN6RCxJQUFJLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixFQUFFLENBQUMsSUFBSTtZQUMzRCxVQUFVLEVBQUUsSUFBSTtZQUNoQixhQUFhLEVBQUUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDO1NBQ2xDLENBQ0YsQ0FBQztRQUVGLG1EQUFtRDtRQUNuRCxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUUvQixpQ0FBaUM7UUFDakMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBVyxFQUFFLE9BQVksRUFBRSxFQUFFO1lBQzFELElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUMsQ0FBQztRQUNILG9DQUFvQztRQUNwQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxHQUFRLEVBQUUsR0FBUSxFQUFFLEVBQUU7WUFDcEQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO1FBRUgsNkRBQTZEO1FBQzdELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3pELDZDQUE2QztRQUM3QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNuRCx3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDOUIseUNBQXlDO1FBQ3pDLElBQUksQ0FBQyw2QkFBNkIsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFFaEYsbUJBQW1CO1FBQ25CLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUU7Z0JBQzlDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ25FLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLHVCQUF1QjtRQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxVQUE4QixFQUFFLEVBQUU7WUFDbkUsbUNBQW1DO1lBQ25DLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDcEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0JBQW9CLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxxQ0FBcUMsQ0FBQyxDQUFDO2dCQUN2RyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3JCLE9BQU87WUFDVCxDQUFDO1lBRUQsNkJBQTZCO1lBQzdCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQztZQUV6RCxxRUFBcUU7WUFDckUsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUM7WUFDNUMsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUM7WUFFOUMsMEZBQTBGO1lBQzFGLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsSUFBSSxVQUFVLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO2dCQUN6RixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsMENBQTBDLFNBQVMsYUFBYSxVQUFVLEdBQUcsQ0FBQyxDQUFDO1lBQ25HLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsU0FBUyxhQUFhLFVBQVUsR0FBRyxDQUFDLENBQUM7WUFDMUYsQ0FBQztZQUVELG9DQUFvQztZQUNwQyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsRUFBRTtnQkFDN0IsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO29CQUM5QyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDbEMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDO29CQUV6RCw2REFBNkQ7b0JBQzdELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsSUFBSSxVQUFVLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO3dCQUN6RixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztvQkFDOUIsQ0FBQztvQkFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsSUFBSSxDQUFDLGdCQUFnQix3QkFBd0IsQ0FBQyxDQUFDO2dCQUN6RixDQUFDO1lBQ0gsQ0FBQyxDQUFDO1lBRUYsVUFBVSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztZQUMxQyxVQUFVLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDM0MsaUJBQWlCLEVBQUUsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQztZQUNILFVBQVUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxrQ0FBa0M7UUFDbEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBQ25FLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ssc0JBQXNCO1FBQzVCLElBQUksQ0FBQyxlQUFlLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRTtZQUN0QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNoRSxNQUFNLE9BQU8sR0FBRztnQkFDZCxNQUFNO2dCQUNOLGlCQUFpQixFQUFFLElBQUksQ0FBQyxnQkFBZ0I7Z0JBQ3hDLGFBQWEsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFDbEMsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjO2dCQUNuQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsb0JBQW9CO2dCQUMvQyx3QkFBd0IsRUFBRSxJQUFJLENBQUMsd0JBQXdCO2dCQUN2RCxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxpQkFBaUI7Z0JBQzdFLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxFQUFFO2dCQUNsQyxjQUFjLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDO2dCQUMvQyxjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUU7YUFDcEQsQ0FBQztZQUVGLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM5QyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQywyQkFBMkI7UUFFdEMsNENBQTRDO1FBQzVDLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQXNCO1FBQ3BELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxNQUFNLENBQUMsTUFBTSxVQUFVLENBQUMsQ0FBQztRQUU1RSxzRkFBc0Y7UUFDdEYsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFFckIsOERBQThEO1FBQzlELGdFQUFnRTtRQUNoRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTdDLHlEQUF5RDtRQUN6RCxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDM0MsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBeUMsQ0FBQztRQUU1RSxtRUFBbUU7UUFDbkUsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUMzQixvREFBb0Q7WUFDcEQsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUM1RCxTQUFTO1lBQ1gsQ0FBQztZQUVELHlCQUF5QjtZQUN6QixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUNoRCxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPO2dCQUNyQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRTFCLHNCQUFzQjtZQUN0QixLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUM3QixzREFBc0Q7Z0JBQ3RELElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUN6QixTQUFTO2dCQUNYLENBQUM7Z0JBRUQsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUU3Qix3REFBd0Q7Z0JBQ3hELElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsV0FBVyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxNQUFNLEVBQUUsQ0FBQztvQkFDN0Usa0JBQWtCLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRTt3QkFDN0IsSUFBSSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJO3dCQUN2QyxHQUFHLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEdBQUc7cUJBQ3RDLENBQUMsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCx3REFBd0Q7UUFDeEQsS0FBSyxNQUFNLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxJQUFJLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDOUQsSUFBSSxDQUFDO2dCQUNILElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxpQkFBaUIsQ0FDdkMsTUFBTSxFQUNOLFFBQVEsQ0FBQyxJQUFJLEVBQ2IsUUFBUSxDQUFDLEdBQUcsQ0FDYixDQUFDO2dCQUVGLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2xDLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxNQUFNLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN0RSxDQUFDO1FBQ0gsQ0FBQztRQUVELDRCQUE0QjtRQUM1QixLQUFLLE1BQU0sUUFBUSxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksUUFBUSw2QkFBNkIsQ0FBQyxDQUFDO2dCQUNwRSxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2QyxDQUFDO1FBQ0gsQ0FBQztRQUVELG9DQUFvQztRQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUU5QiwyQ0FBMkM7UUFDM0MsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV4QyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsTUFBTSxDQUFDLE1BQU0sU0FBUyxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVELG9DQUFvQztJQUNwQyxrRkFBa0Y7SUFFbEY7O09BRUc7SUFDSSxLQUFLLENBQUMsaUJBQWlCLENBQUMsVUFBcUM7UUFDbEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsSUFBSTtRQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFFOUMsa0JBQWtCO1FBQ2xCLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUM7WUFDdkMsYUFBYSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFFRCx5QkFBeUI7UUFDekIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRWpDLDJEQUEyRDtRQUMzRCxJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUM3RSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2hDLENBQUM7UUFFRCw0QkFBNEI7UUFDNUIsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUNuRSxhQUFhLENBQUMsTUFBTSxFQUFFLGlCQUFpQixFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQzlELENBQUM7UUFDRixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUV6Qyx3Q0FBd0M7UUFDeEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBRTFDLGdFQUFnRTtRQUVoRSx5QkFBeUI7UUFDekIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzdCLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsdUNBQXVDLENBQUMsQ0FBQztnQkFDMUQsT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQWM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUVBQWlFLENBQUMsQ0FBQztRQUNwRixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksaUJBQWlCLENBQ3RCLE1BQWMsRUFDZCxXQUFtQixFQUNuQixVQUFrQixFQUNsQixVQUFpQjtRQUVqQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxlQUFlO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0NBQ0YifQ==
502
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1wcm94eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3hpZXMvaHR0cC1wcm94eS9odHRwLXByb3h5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUNMLFlBQVksR0FDYixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxrQkFBa0IsSUFBSSxZQUFZLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQU96RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGNBQWMsRUFBd0IsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDeEQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFFakY7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyxTQUFTO0lBQ3BCLGlHQUFpRztJQUMxRixNQUFNO1FBQ1gsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBcUNEOztPQUVHO0lBQ0gsWUFBWSxVQUE2QjtRQXJDbEMsV0FBTSxHQUFtQixFQUFFLENBQUM7UUFVM0IsV0FBTSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQyxzQkFBc0I7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
@@ -34,6 +34,8 @@ export interface IHttpProxyOptions {
34
34
  functionCacheTtl?: number;
35
35
  acme?: IAcmeOptions;
36
36
  routes?: IRouteConfig[];
37
+ maxConnectionsPerIP?: number;
38
+ connectionRateLimitPerMinute?: number;
37
39
  }
38
40
  /**
39
41
  * Interface for a certificate entry in the cache