@push.rocks/smartproxy 3.32.2 → 3.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,21 @@ export interface IRouterResult {
19
19
  pathRemainder?: string;
20
20
  }
21
21
 
22
+ /**
23
+ * Router for HTTP reverse proxy requests
24
+ *
25
+ * Supports the following domain matching patterns:
26
+ * - Exact matches: "example.com"
27
+ * - Wildcard subdomains: "*.example.com" (matches any subdomain of example.com)
28
+ * - TLD wildcards: "example.*" (matches example.com, example.org, etc.)
29
+ * - Complex wildcards: "*.lossless*" (matches any subdomain of any lossless domain)
30
+ * - Default fallback: "*" (matches any unmatched domain)
31
+ *
32
+ * Also supports path pattern matching for each domain:
33
+ * - Exact path: "/api/users"
34
+ * - Wildcard paths: "/api/*"
35
+ * - Path parameters: "/users/:id/profile"
36
+ */
22
37
  export class ProxyRouter {
23
38
  // Store original configs for reference
24
39
  private reverseProxyConfigs: tsclass.network.IReverseProxyConfig[] = [];
@@ -98,9 +113,11 @@ export class ProxyRouter {
98
113
  return exactConfig;
99
114
  }
100
115
 
101
- // Try wildcard subdomain
116
+ // Try various wildcard patterns
102
117
  if (hostWithoutPort.includes('.')) {
103
118
  const domainParts = hostWithoutPort.split('.');
119
+
120
+ // Try wildcard subdomain (*.example.com)
104
121
  if (domainParts.length > 2) {
105
122
  const wildcardDomain = `*.${domainParts.slice(1).join('.')}`;
106
123
  const wildcardConfig = this.findConfigForHost(wildcardDomain, urlPath);
@@ -108,6 +125,23 @@ export class ProxyRouter {
108
125
  return wildcardConfig;
109
126
  }
110
127
  }
128
+
129
+ // Try TLD wildcard (example.*)
130
+ const baseDomain = domainParts.slice(0, -1).join('.');
131
+ const tldWildcardDomain = `${baseDomain}.*`;
132
+ const tldWildcardConfig = this.findConfigForHost(tldWildcardDomain, urlPath);
133
+ if (tldWildcardConfig) {
134
+ return tldWildcardConfig;
135
+ }
136
+
137
+ // Try complex wildcard patterns
138
+ const wildcardPatterns = this.findWildcardMatches(hostWithoutPort);
139
+ for (const pattern of wildcardPatterns) {
140
+ const wildcardConfig = this.findConfigForHost(pattern, urlPath);
141
+ if (wildcardConfig) {
142
+ return wildcardConfig;
143
+ }
144
+ }
111
145
  }
112
146
 
113
147
  // Fall back to default config if available
@@ -120,6 +154,53 @@ export class ProxyRouter {
120
154
  return undefined;
121
155
  }
122
156
 
157
+ /**
158
+ * Find potential wildcard patterns that could match a given hostname
159
+ * Handles complex patterns like "*.lossless*" or other partial matches
160
+ * @param hostname The hostname to find wildcard matches for
161
+ * @returns Array of potential wildcard patterns that could match
162
+ */
163
+ private findWildcardMatches(hostname: string): string[] {
164
+ const patterns: string[] = [];
165
+ const hostnameParts = hostname.split('.');
166
+
167
+ // Find all configured hostnames that contain wildcards
168
+ const wildcardConfigs = this.reverseProxyConfigs.filter(
169
+ config => config.hostName.includes('*')
170
+ );
171
+
172
+ // Extract unique wildcard patterns
173
+ const wildcardPatterns = [...new Set(
174
+ wildcardConfigs.map(config => config.hostName.toLowerCase())
175
+ )];
176
+
177
+ // For each wildcard pattern, check if it could match the hostname
178
+ // using simplified regex pattern matching
179
+ for (const pattern of wildcardPatterns) {
180
+ // Skip the default wildcard '*'
181
+ if (pattern === '*') continue;
182
+
183
+ // Skip already checked patterns (*.domain.com and domain.*)
184
+ if (pattern.startsWith('*.') && pattern.indexOf('*', 2) === -1) continue;
185
+ if (pattern.endsWith('.*') && pattern.indexOf('*') === pattern.length - 1) continue;
186
+
187
+ // Convert wildcard pattern to regex
188
+ const regexPattern = pattern
189
+ .replace(/\./g, '\\.') // Escape dots
190
+ .replace(/\*/g, '.*'); // Convert * to .* for regex
191
+
192
+ // Create regex object with case insensitive flag
193
+ const regex = new RegExp(`^${regexPattern}$`, 'i');
194
+
195
+ // If hostname matches this complex pattern, add it to the list
196
+ if (regex.test(hostname)) {
197
+ patterns.push(pattern);
198
+ }
199
+ }
200
+
201
+ return patterns;
202
+ }
203
+
123
204
  /**
124
205
  * Find a config for a specific host and path
125
206
  */