diff options
Diffstat (limited to 'desktop/node_modules/global-agent/dist/factories/createGlobalProxyAgent.js.flow')
-rw-r--r-- | desktop/node_modules/global-agent/dist/factories/createGlobalProxyAgent.js.flow | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/desktop/node_modules/global-agent/dist/factories/createGlobalProxyAgent.js.flow b/desktop/node_modules/global-agent/dist/factories/createGlobalProxyAgent.js.flow new file mode 100644 index 0000000..d515a9d --- /dev/null +++ b/desktop/node_modules/global-agent/dist/factories/createGlobalProxyAgent.js.flow @@ -0,0 +1,197 @@ +// @flow + +import http from 'http'; +import https from 'https'; +import { + boolean as parseBoolean, +} from 'boolean'; +import semver from 'semver'; +import Logger from '../Logger'; +import { + HttpProxyAgent, + HttpsProxyAgent, +} from '../classes'; +import { + UnexpectedStateError, +} from '../errors'; +import { + bindHttpMethod, + isUrlMatchingNoProxy, + parseProxyUrl, +} from '../utilities'; +import type { + ProxyAgentConfigurationInputType, + ProxyAgentConfigurationType, +} from '../types'; +import createProxyController from './createProxyController'; + +const httpGet = http.get; +const httpRequest = http.request; +const httpsGet = https.get; +const httpsRequest = https.request; + +const log = Logger.child({ + namespace: 'createGlobalProxyAgent', +}); + +const defaultConfigurationInput = { + environmentVariableNamespace: undefined, + forceGlobalAgent: undefined, + socketConnectionTimeout: 60000, +}; + +const omitUndefined = (subject) => { + const keys = Object.keys(subject); + + const result = {}; + + for (const key of keys) { + const value = subject[key]; + + if (value !== undefined) { + result[key] = value; + } + } + + return result; +}; + +const createConfiguration = (configurationInput: ProxyAgentConfigurationInputType): ProxyAgentConfigurationType => { + // eslint-disable-next-line no-process-env + const environment = process.env; + + const defaultConfiguration = { + environmentVariableNamespace: typeof environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE === 'string' ? environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE : 'GLOBAL_AGENT_', + forceGlobalAgent: typeof environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT === 'string' ? parseBoolean(environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT) : true, + socketConnectionTimeout: typeof environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT === 'string' ? Number.parseInt(environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT, 10) : defaultConfigurationInput.socketConnectionTimeout, + }; + + // $FlowFixMe + return { + ...defaultConfiguration, + ...omitUndefined(configurationInput), + }; +}; + +export default (configurationInput: ProxyAgentConfigurationInputType = defaultConfigurationInput) => { + const configuration = createConfiguration(configurationInput); + + const proxyController = createProxyController(); + + // eslint-disable-next-line no-process-env + proxyController.HTTP_PROXY = process.env[configuration.environmentVariableNamespace + 'HTTP_PROXY'] || null; + + // eslint-disable-next-line no-process-env + proxyController.HTTPS_PROXY = process.env[configuration.environmentVariableNamespace + 'HTTPS_PROXY'] || null; + + // eslint-disable-next-line no-process-env + proxyController.NO_PROXY = process.env[configuration.environmentVariableNamespace + 'NO_PROXY'] || null; + + log.info({ + configuration, + state: proxyController, + }, 'global agent has been initialized'); + + const mustUrlUseProxy = (getProxy) => { + return (url) => { + if (!getProxy()) { + return false; + } + + if (!proxyController.NO_PROXY) { + return true; + } + + return !isUrlMatchingNoProxy(url, proxyController.NO_PROXY); + }; + }; + + const getUrlProxy = (getProxy) => { + return () => { + const proxy = getProxy(); + + if (!proxy) { + throw new UnexpectedStateError('HTTP(S) proxy must be configured.'); + } + + return parseProxyUrl(proxy); + }; + }; + + const getHttpProxy = () => { + return proxyController.HTTP_PROXY; + }; + + const BoundHttpProxyAgent = class extends HttpProxyAgent { + constructor () { + super( + () => { + return getHttpProxy(); + }, + mustUrlUseProxy(getHttpProxy), + getUrlProxy(getHttpProxy), + http.globalAgent, + configuration.socketConnectionTimeout, + ); + } + }; + + const httpAgent = new BoundHttpProxyAgent(); + + const getHttpsProxy = () => { + return proxyController.HTTPS_PROXY || proxyController.HTTP_PROXY; + }; + + const BoundHttpsProxyAgent = class extends HttpsProxyAgent { + constructor () { + super( + () => { + return getHttpsProxy(); + }, + mustUrlUseProxy(getHttpsProxy), + getUrlProxy(getHttpsProxy), + https.globalAgent, + configuration.socketConnectionTimeout, + ); + } + }; + + const httpsAgent = new BoundHttpsProxyAgent(); + + // Overriding globalAgent was added in v11.7. + // @see https://nodejs.org/uk/blog/release/v11.7.0/ + if (semver.gte(process.version, 'v11.7.0')) { + // @see https://github.com/facebook/flow/issues/7670 + // $FlowFixMe + http.globalAgent = httpAgent; + + // $FlowFixMe + https.globalAgent = httpsAgent; + } + + // The reason this logic is used in addition to overriding http(s).globalAgent + // is because there is no guarantee that we set http(s).globalAgent variable + // before an instance of http(s).Agent has been already constructed by someone, + // e.g. Stripe SDK creates instances of http(s).Agent at the top-level. + // @see https://github.com/gajus/global-agent/pull/13 + // + // We still want to override http(s).globalAgent when possible to enable logic + // in `bindHttpMethod`. + if (semver.gte(process.version, 'v10.0.0')) { + // $FlowFixMe + http.get = bindHttpMethod(httpGet, httpAgent, configuration.forceGlobalAgent); + + // $FlowFixMe + http.request = bindHttpMethod(httpRequest, httpAgent, configuration.forceGlobalAgent); + + // $FlowFixMe + https.get = bindHttpMethod(httpsGet, httpsAgent, configuration.forceGlobalAgent); + + // $FlowFixMe + https.request = bindHttpMethod(httpsRequest, httpsAgent, configuration.forceGlobalAgent); + } else { + log.warn('attempt to initialize global-agent in unsupported Node.js version was ignored'); + } + + return proxyController; +}; |