server/proxy_config.js (53 lines of code) (raw):

import { memoize, values } from 'lodash' import { format as formatUrl } from 'url' import { Agent as HttpsAgent } from 'https' import { readFileSync } from 'fs' import { WildcardMatcher } from './wildcard_matcher' const makeHttpsAgent = memoize( opts => new HttpsAgent(opts), opts => JSON.stringify(opts) ) export class ProxyConfig { constructor(config) { config = Object.assign({}, config); // ----- // read "match" info // ----- const rawMatches = Object.assign({}, config.match); this.id = formatUrl({ protocol: rawMatches.protocol, hostname: rawMatches.host, port: rawMatches.port, pathname: rawMatches.path }) || '*'; this.matchers = { protocol: new WildcardMatcher(rawMatches.protocol), host: new WildcardMatcher(rawMatches.host), port: new WildcardMatcher(rawMatches.port), path: new WildcardMatcher(rawMatches.path, '/'), }; // ----- // read config vars // ----- this.timeout = config.timeout; this.sslAgent = this._makeSslAgent(config); } _makeSslAgent(config) { const ssl = config.ssl || {}; this.verifySsl = ssl.verify; const sslAgentOpts = { ca: ssl.ca && ssl.ca.map(ca => readFileSync(ca)), cert: ssl.cert && readFileSync(ssl.cert), key: ssl.key && readFileSync(ssl.key), }; if (values(sslAgentOpts).filter(Boolean).length) { return new HttpsAgent(sslAgentOpts); } } getForParsedUri({ protocol, hostname, port, pathname }) { let match = this.matchers.protocol.match(protocol.slice(0, -1)); match = match && this.matchers.host.match(hostname); match = match && this.matchers.port.match(port); match = match && this.matchers.path.match(pathname); if (!match) return {}; return { timeout: this.timeout, rejectUnauthorized: this.sslAgent ? true : this.verifySsl, agent: protocol === 'https:' ? this.sslAgent : undefined }; } }