|
| 1 | +const proxyFromEnv = require('proxy-from-env') |
| 2 | + |
| 3 | +module.exports = { |
| 4 | + getWSProxyAgent, |
| 5 | + getHTTPProxyAgent |
| 6 | +} |
| 7 | + |
| 8 | +/** |
| 9 | + * Get a specific proxy agent for a WebSocket connection. This should be applied to the `wsOptions.agent` property |
| 10 | + * |
| 11 | + * NOTE: This utility function is specifically designed for the MQTT instances where the proxy is set based on the http based EndPoint |
| 12 | + * that the instance will use to make a connection. As such, the proxy URL is determined based on the `wsEndPoint` provided in |
| 13 | + * conjunction with env vars `http_proxy`, `https_proxy` and `no_proxy`. |
| 14 | + * |
| 15 | + * More Info: |
| 16 | + * `wsOptions.agent` is expected to be an HTTP or HTTPS agent based on the request protocol |
| 17 | + * http/ws requests use env var `http_proxy` and the HttpProxyAgent |
| 18 | + * https/wss requests use env var `https_proxy` and the HttpsProxyAgent |
| 19 | + * REF: https://github.com/TooTallNate/proxy-agents/tree/main/packages/proxy-agent#maps-proxy-protocols-to-httpagent-implementations |
| 20 | + * |
| 21 | + * @param {String} url - WebSocket url |
| 22 | + * @param {import('http').AgentOptions} proxyOptions - proxy options |
| 23 | + * @returns {import('https-proxy-agent').HttpsProxyAgent | import('http-proxy-agent').HttpProxyAgent | null} |
| 24 | + */ |
| 25 | +function getWSProxyAgent (url, proxyOptions) { |
| 26 | + if (!url) { |
| 27 | + return null |
| 28 | + } |
| 29 | + const _url = new URL(url) |
| 30 | + const isHTTPBased = _url.protocol === 'ws:' || _url.protocol === 'http:' |
| 31 | + const isHTTPSBased = _url.protocol === 'wss:' || _url.protocol === 'https:' |
| 32 | + if (!isHTTPBased && !isHTTPSBased) { |
| 33 | + return null |
| 34 | + } |
| 35 | + |
| 36 | + // replace ^ws with http so that getProxyForUrl can return the correct http*_proxy for ws/wss |
| 37 | + const proxyUrl = proxyFromEnv.getProxyForUrl(url.replace(/^ws/, 'http')) |
| 38 | + |
| 39 | + if (proxyUrl && isHTTPSBased) { |
| 40 | + const HttpsAgent = require('https-proxy-agent').HttpsProxyAgent |
| 41 | + return new HttpsAgent(proxyUrl, proxyOptions) |
| 42 | + } |
| 43 | + if (proxyUrl && isHTTPBased) { |
| 44 | + const HttpAgent = require('http-proxy-agent').HttpProxyAgent |
| 45 | + return new HttpAgent(proxyUrl, proxyOptions) |
| 46 | + } |
| 47 | + return null |
| 48 | +} |
| 49 | + |
| 50 | +/** |
| 51 | + * Get proxy agent for HTTP or HTTPS got instance. This should be applied to the `agent` property of the got instance options |
| 52 | + * |
| 53 | + * NOTE: This utility function is specifically designed for the GOT instances where the proxy is set based on the `httpEndPoint` |
| 54 | + * that the instance will use to make requests. As such, the proxy URL is determined based on the `httpEndPoint` provided |
| 55 | + * in conjunction with env vars `http_proxy`, `https_proxy` and `no_proxy`. |
| 56 | + * @param {String} url - http or https URL |
| 57 | + * @param {import('http').AgentOptions} proxyOptions - proxy options |
| 58 | + * @returns {{http: import('http-proxy-agent').HttpProxyAgent | undefined, https: import('https-proxy-agent').HttpsProxyAgent | undefined}} |
| 59 | + */ |
| 60 | +function getHTTPProxyAgent (url, proxyOptions) { |
| 61 | + const agent = {} |
| 62 | + if (url) { |
| 63 | + const _url = new URL(url) |
| 64 | + const proxyUrl = proxyFromEnv.getProxyForUrl(url) |
| 65 | + if (proxyUrl && _url.protocol === 'http:') { |
| 66 | + const HttpAgent = require('http-proxy-agent').HttpProxyAgent |
| 67 | + agent.http = new HttpAgent(proxyUrl, proxyOptions) |
| 68 | + } |
| 69 | + if (proxyUrl && _url.protocol === 'https:') { |
| 70 | + const HttpsAgent = require('https-proxy-agent').HttpsProxyAgent |
| 71 | + agent.https = new HttpsAgent(proxyUrl, proxyOptions) |
| 72 | + } |
| 73 | + } |
| 74 | + return agent |
| 75 | +} |
0 commit comments