UNPKG

@stuntman/server

Version:

Stuntman - HTTP proxy / mock server with API

83 lines 3.06 kB
import { networkInterfaces } from 'os'; import dns, { Resolver as DNSResolver } from 'node:dns'; import { getDnsResolutionCache } from './storage.js'; import { errorToLog, logger } from '@stuntman/shared'; const localhostIPs = ['127.0.0.1', '::1']; const IP_WITH_OPTIONAL_PORT_REGEX = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}(:[0-9]+)?$/i; for (const nets of Object.values(networkInterfaces())) { if (!nets) { continue; } for (const net of nets) { const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4; if (net.family === familyV4Value && !localhostIPs.includes(net.address)) { localhostIPs.push(net.address); } } } export class IPUtils { dnsResolutionCache; mockUuid; externalDns = null; constructor(options) { this.mockUuid = options.mockUuid; if (options.externalDns?.length) { this.externalDns = new DNSResolver(); this.externalDns.setServers(options.externalDns); } this.dnsResolutionCache = getDnsResolutionCache(this.mockUuid); } isLocalhostIP(ip) { return localhostIPs.includes(ip); } async resolveIPs(hostname, options) { return new Promise((resolve, reject) => { const callback = (error, addresses) => { if (error) { logger.debug({ error: errorToLog(error), hostname }, 'error resolving hostname'); reject(error); return; } if (typeof addresses === 'string') { logger.debug({ ip: [addresses], hostname }, 'resolved hostname'); resolve([addresses]); return; } if (!addresses || addresses.length === 0) { logger.debug({ hostname }, 'no addresses found'); resolve([]); return; } logger.debug({ ip: addresses, hostname }, 'resolved hostname'); resolve(addresses); }; if (options?.useExternalDns) { if (!this.externalDns) { reject(new Error('external dns servers not set')); return; } this.externalDns.resolve(hostname, callback); return; } // TODO general handling of IPv6 dns.resolve4(hostname, callback); }); } async resolveIP(hostname, options) { const cachedIP = this.dnsResolutionCache.get(hostname); if (cachedIP) { return cachedIP; } const resolved = await this.resolveIPs(hostname, options); if (!resolved || resolved.length < 1) { throw new Error('unable to resolve IP'); } const ip = resolved[0]; this.dnsResolutionCache.set(hostname, ip); return ip; } isIP(hostname) { return IP_WITH_OPTIONAL_PORT_REGEX.test(hostname); } } //# sourceMappingURL=ipUtils.js.map