123 lines
3.5 KiB
TypeScript
123 lines
3.5 KiB
TypeScript
|
import * as plugins from './plugins.js';
|
||
|
import type { IDomainConfig, IPortProxySettings } from './classes.pp.interfaces.js';
|
||
|
|
||
|
/**
|
||
|
* Manages domain configurations and target selection
|
||
|
*/
|
||
|
export class DomainConfigManager {
|
||
|
// Track round-robin indices for domain configs
|
||
|
private domainTargetIndices: Map<IDomainConfig, number> = new Map();
|
||
|
|
||
|
constructor(private settings: IPortProxySettings) {}
|
||
|
|
||
|
/**
|
||
|
* Updates the domain configurations
|
||
|
*/
|
||
|
public updateDomainConfigs(newDomainConfigs: IDomainConfig[]): void {
|
||
|
this.settings.domainConfigs = newDomainConfigs;
|
||
|
|
||
|
// Reset target indices for removed configs
|
||
|
const currentConfigSet = new Set(newDomainConfigs);
|
||
|
for (const [config] of this.domainTargetIndices) {
|
||
|
if (!currentConfigSet.has(config)) {
|
||
|
this.domainTargetIndices.delete(config);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get all domain configurations
|
||
|
*/
|
||
|
public getDomainConfigs(): IDomainConfig[] {
|
||
|
return this.settings.domainConfigs;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Find domain config matching a server name
|
||
|
*/
|
||
|
public findDomainConfig(serverName: string): IDomainConfig | undefined {
|
||
|
if (!serverName) return undefined;
|
||
|
|
||
|
return this.settings.domainConfigs.find((config) =>
|
||
|
config.domains.some((d) => plugins.minimatch(serverName, d))
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Find domain config for a specific port
|
||
|
*/
|
||
|
public findDomainConfigForPort(port: number): IDomainConfig | undefined {
|
||
|
return this.settings.domainConfigs.find(
|
||
|
(domain) =>
|
||
|
domain.portRanges &&
|
||
|
domain.portRanges.length > 0 &&
|
||
|
this.isPortInRanges(port, domain.portRanges)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if a port is within any of the given ranges
|
||
|
*/
|
||
|
public isPortInRanges(port: number, ranges: Array<{ from: number; to: number }>): boolean {
|
||
|
return ranges.some((range) => port >= range.from && port <= range.to);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get target IP with round-robin support
|
||
|
*/
|
||
|
public getTargetIP(domainConfig: IDomainConfig): string {
|
||
|
if (domainConfig.targetIPs && domainConfig.targetIPs.length > 0) {
|
||
|
const currentIndex = this.domainTargetIndices.get(domainConfig) || 0;
|
||
|
const ip = domainConfig.targetIPs[currentIndex % domainConfig.targetIPs.length];
|
||
|
this.domainTargetIndices.set(domainConfig, currentIndex + 1);
|
||
|
return ip;
|
||
|
}
|
||
|
|
||
|
return this.settings.targetIP || 'localhost';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks if a domain should use NetworkProxy
|
||
|
*/
|
||
|
public shouldUseNetworkProxy(domainConfig: IDomainConfig): boolean {
|
||
|
return !!domainConfig.useNetworkProxy;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the NetworkProxy port for a domain
|
||
|
*/
|
||
|
public getNetworkProxyPort(domainConfig: IDomainConfig): number | undefined {
|
||
|
return domainConfig.useNetworkProxy
|
||
|
? (domainConfig.networkProxyPort || this.settings.networkProxyPort)
|
||
|
: undefined;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get effective allowed and blocked IPs for a domain
|
||
|
*/
|
||
|
public getEffectiveIPRules(domainConfig: IDomainConfig): {
|
||
|
allowedIPs: string[],
|
||
|
blockedIPs: string[]
|
||
|
} {
|
||
|
return {
|
||
|
allowedIPs: [
|
||
|
...domainConfig.allowedIPs,
|
||
|
...(this.settings.defaultAllowedIPs || [])
|
||
|
],
|
||
|
blockedIPs: [
|
||
|
...(domainConfig.blockedIPs || []),
|
||
|
...(this.settings.defaultBlockedIPs || [])
|
||
|
]
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get connection timeout for a domain
|
||
|
*/
|
||
|
public getConnectionTimeout(domainConfig?: IDomainConfig): number {
|
||
|
if (domainConfig?.connectionTimeout) {
|
||
|
return domainConfig.connectionTimeout;
|
||
|
}
|
||
|
return this.settings.maxConnectionLifetime || 86400000; // 24 hours default
|
||
|
}
|
||
|
}
|