UNPKG

@serenity-js/rest

Version:

Serenity/JS Screenplay Pattern library for interacting with REST and other HTTP-based services, supporting comprehensive API testing and blended testing scenarios

120 lines 4.73 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ProxyAgent = void 0; const core_1 = require("@serenity-js/core"); const agent_base_1 = require("agent-base"); const http = __importStar(require("http")); const http_proxy_agent_1 = require("http-proxy-agent"); const https = __importStar(require("https")); const https_proxy_agent_1 = require("https-proxy-agent"); const lru_cache_1 = require("lru-cache"); const protocols = [ ...http_proxy_agent_1.HttpProxyAgent.protocols, ]; /** * A simplified version of the original * [`ProxyAgent`](https://github.com/TooTallNate/proxy-agents/blob/5923589c2e5206504772c250ac4f20fc31122d3b/packages/proxy-agent/src/index.ts) * with fewer dependencies. * * Delegates requests to the appropriate `Agent` subclass based on the "proxy" * environment variables, or the provided `agentOptions.getProxyForUrl` callback. * * Uses an LRU cache to prevent unnecessary creation of proxy `http.Agent` instances. */ class ProxyAgent extends agent_base_1.Agent { agentOptions; static proxyAgents = { http: [http_proxy_agent_1.HttpProxyAgent, https_proxy_agent_1.HttpsProxyAgent], https: [http_proxy_agent_1.HttpProxyAgent, https_proxy_agent_1.HttpsProxyAgent], }; /** * Cache for `Agent` instances. */ cache = new lru_cache_1.LRUCache({ max: 20, dispose: (value, key) => value.destroy(), }); httpAgent; httpsAgent; getProxyForUrl; constructor(agentOptions) { super(agentOptions); this.agentOptions = agentOptions; this.httpAgent = agentOptions?.httpAgent || new http.Agent(agentOptions); this.httpsAgent = agentOptions?.httpsAgent || new https.Agent(agentOptions); this.getProxyForUrl = agentOptions?.getProxyForUrl; } async connect(request, options) { const { secureEndpoint } = options; const isWebSocket = request.getHeader('upgrade') === 'websocket'; const protocol = secureEndpoint ? (isWebSocket ? 'wss:' : 'https:') : (isWebSocket ? 'ws:' : 'http:'); const host = request.getHeader('host'); const url = new URL(request.path, `${protocol}//${host}`).href; const proxy = this.getProxyForUrl(url); if (!proxy) { return secureEndpoint ? this.httpsAgent : this.httpAgent; } // attempt to get a cached `http.Agent` instance first const cacheKey = `${protocol}+${proxy}`; let agent = this.cache.get(cacheKey); if (!agent) { agent = this.createAgent(new URL(proxy), secureEndpoint || isWebSocket); this.cache.set(cacheKey, agent); } return agent; } createAgent(proxyUrl, requiresTls) { const protocol = proxyUrl.protocol.replace(':', ''); if (!this.isValidProtocol(protocol)) { throw new core_1.ConfigurationError(`Unsupported protocol for proxy URL: ${proxyUrl}`); } const ctor = ProxyAgent.proxyAgents[protocol][requiresTls ? 1 : 0]; return new ctor(proxyUrl, this.agentOptions); } isValidProtocol(v) { return protocols.includes(v); } destroy() { this.cache.clear(); super.destroy(); } } exports.ProxyAgent = ProxyAgent; //# sourceMappingURL=ProxyAgent.js.map