- Removed deprecated route utility functions in favor of direct matcher usage. - Updated imports to reflect new module structure for routing utilities. - Consolidated route manager functionality into SharedRouteManager for better consistency. - Eliminated legacy routing methods and interfaces, streamlining the HttpProxy and associated components. - Enhanced WebSocket and HTTP request handling to utilize the new unified HttpRouter. - Updated route matching logic to leverage matcher classes for domain, path, and header checks. - Cleaned up legacy compatibility code across various modules, ensuring a more maintainable codebase.
88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
/**
|
|
* Route matching utilities for SmartProxy components
|
|
*
|
|
* This file provides utility functions that use the unified matchers
|
|
* and additional route-specific utilities.
|
|
*/
|
|
|
|
import { DomainMatcher, PathMatcher, IpMatcher, HeaderMatcher } from './matchers/index.js';
|
|
import { RouteSpecificity } from './specificity.js';
|
|
import type { IRouteSpecificity } from './types.js';
|
|
import type { IRouteConfig } from '../../proxies/smart-proxy/models/route-types.js';
|
|
|
|
|
|
/**
|
|
* Match domains from a route against a given domain
|
|
*
|
|
* @param domains Array or single domain pattern to match against
|
|
* @param domain Domain to match
|
|
* @returns Whether the domain matches any of the patterns
|
|
*/
|
|
export function matchRouteDomain(domains: string | string[] | undefined, domain: string | undefined): boolean {
|
|
// If no domains specified in the route, match all domains
|
|
if (!domains) {
|
|
return true;
|
|
}
|
|
|
|
// If no domain in the request, can't match domain-specific routes
|
|
if (!domain) {
|
|
return false;
|
|
}
|
|
|
|
const patterns = Array.isArray(domains) ? domains : [domains];
|
|
return patterns.some(pattern => DomainMatcher.match(pattern, domain));
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Calculate route specificity score
|
|
* Higher score means more specific matching criteria
|
|
*
|
|
* @param match Match criteria to evaluate
|
|
* @returns Numeric specificity score
|
|
*/
|
|
export function calculateRouteSpecificity(match: {
|
|
domains?: string | string[];
|
|
path?: string;
|
|
clientIp?: string[];
|
|
tlsVersion?: string[];
|
|
headers?: Record<string, string | RegExp>;
|
|
}): number {
|
|
let score = 0;
|
|
|
|
// Path specificity using PathMatcher
|
|
if (match.path) {
|
|
score += PathMatcher.calculateSpecificity(match.path);
|
|
}
|
|
|
|
// Domain specificity using DomainMatcher
|
|
if (match.domains) {
|
|
const domains = Array.isArray(match.domains) ? match.domains : [match.domains];
|
|
// Use the highest specificity among all domains
|
|
const domainScore = Math.max(...domains.map(d => DomainMatcher.calculateSpecificity(d)));
|
|
score += domainScore;
|
|
}
|
|
|
|
// Headers specificity using HeaderMatcher
|
|
if (match.headers) {
|
|
const stringHeaders: Record<string, string> = {};
|
|
for (const [key, value] of Object.entries(match.headers)) {
|
|
stringHeaders[key] = value instanceof RegExp ? value.source : value;
|
|
}
|
|
score += HeaderMatcher.calculateSpecificity(stringHeaders);
|
|
}
|
|
|
|
// Client IP adds some specificity
|
|
if (match.clientIp && match.clientIp.length > 0) {
|
|
// Use the first IP pattern for specificity
|
|
score += IpMatcher.calculateSpecificity(match.clientIp[0]);
|
|
}
|
|
|
|
// TLS version adds minimal specificity
|
|
if (match.tlsVersion && match.tlsVersion.length > 0) {
|
|
score += match.tlsVersion.length * 10;
|
|
}
|
|
|
|
return score;
|
|
} |