UNPKG

@applitools/execution-grid-tunnel

Version:

Allows user to run tests with exection-grid and navigate to private hosts and ips

97 lines (84 loc) 2.89 kB
'use strict' /** * Parse PAC's `FindProxyForURL` return string into a chain of entries the * `@applitools/eg-socks5-proxy-server` `setHttpProxyResolver` API consumes. * * PAC syntax: * "DIRECT" * "PROXY host:port" * "HTTPS host:port" * "PROXY a:1; PROXY b:2; DIRECT" (fallback chain, semicolon-separated) * * Mapping: * - "DIRECT" → sentinel string 'DIRECT' * - "PROXY host:port" → {address: 'host', port: <number>} * - "HTTPS host:port" → {address: 'host', port: <number>, tls: true} * - Anything else → logged as warn (action: 'pac-directive-parse-failed') and skipped * * Returns: * - null if the resulting list is empty OR contains only a single * 'DIRECT' entry (caller lets the SOCKS5 dispatcher fall through * to its DIRECT path — cleaner than running the orchestrator) * - ProxyChainEntry[] otherwise * * Per-request — never throws. Logging is via the structured logger * the caller passes in (same instance threaded through startEgTunnelService). */ const DIRECTIVE_REGEX = /^(PROXY|HTTPS|DIRECT)(?:\s+([^\s]+))?$/i function parsePacDirectives(directiveString, {logger, address, port} = {}) { if (typeof directiveString !== 'string' || directiveString.trim() === '') { return null } const entries = [] for (const raw of directiveString.split(';')) { const directive = raw.trim() if (directive === '') continue // tolerate "a; ;b" patterns const match = DIRECTIVE_REGEX.exec(directive) if (!match) { logger?.warn({ action: 'pac-directive-parse-failed', directive, address, port, }) continue } const kind = match[1].toUpperCase() if (kind === 'DIRECT') { entries.push('DIRECT') continue } // PROXY / HTTPS — require a host:port operand const operand = match[2] if (!operand || !operand.includes(':')) { logger?.warn({ action: 'pac-directive-parse-failed', directive, address, port, }) continue } const colonIdx = operand.lastIndexOf(':') const host = operand.slice(0, colonIdx) const portNum = Number(operand.slice(colonIdx + 1)) if (!host || !Number.isInteger(portNum) || portNum <= 0 || portNum > 65535) { logger?.warn({ action: 'pac-directive-parse-failed', directive, address, port, }) continue } const entry = {address: host, port: portNum} if (kind === 'HTTPS') entry.tls = true entries.push(entry) } if (entries.length === 0) return null // Lone DIRECT → null so the SOCKS5 dispatcher falls through to its // existing DIRECT path (avoids spinning up the chain orchestrator for nothing). if (entries.length === 1 && entries[0] === 'DIRECT') return null return entries } module.exports = {parsePacDirectives}