diff options
author | LinuxWizard42 <computerwizard@linuxmail.org> | 2022-10-12 22:54:37 +0300 |
---|---|---|
committer | LinuxWizard42 <computerwizard@linuxmail.org> | 2022-10-12 22:54:37 +0300 |
commit | 703e03aba33f234712206769f57717ba7d92d23d (patch) | |
tree | 0041f04ccb75bd5379c764e9fe42249fffe75fc3 /node_modules/global-tunnel-ng/index.js | |
parent | ab6e257e6e9d9a483d7e86f220d8b209a2cd7753 (diff) | |
download | FlashRunner-703e03aba33f234712206769f57717ba7d92d23d.tar.gz FlashRunner-703e03aba33f234712206769f57717ba7d92d23d.tar.zst |
Added export_allowed file to make repository visible in cgit
Diffstat (limited to 'node_modules/global-tunnel-ng/index.js')
-rw-r--r-- | node_modules/global-tunnel-ng/index.js | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/node_modules/global-tunnel-ng/index.js b/node_modules/global-tunnel-ng/index.js new file mode 100644 index 0000000..f5e89e1 --- /dev/null +++ b/node_modules/global-tunnel-ng/index.js @@ -0,0 +1,348 @@ +/* jshint node:true */ +'use strict'; +/** + * @fileOverview + * Global proxy settings. + */ +var globalTunnel = exports; +exports.constructor = function() {}; + +var http = require('http'); +var https = require('https'); +var urlParse = require('url').parse; +var urlStringify = require('url').format; + +var pick = require('lodash/pick'); +var assign = require('lodash/assign'); +var clone = require('lodash/clone'); +var tunnel = require('tunnel'); +var npmConfig = require('npm-conf'); +var encodeUrl = require('encodeurl'); + +var agents = require('./lib/agents'); +exports.agents = agents; + +var ENV_VAR_PROXY_SEARCH_ORDER = [ + 'https_proxy', + 'HTTPS_PROXY', + 'http_proxy', + 'HTTP_PROXY' +]; +var NPM_CONFIG_PROXY_SEARCH_ORDER = ['https-proxy', 'http-proxy', 'proxy']; + +// Save the original settings for restoration later. +var ORIGINALS = { + http: pick(http, 'globalAgent', ['request', 'get']), + https: pick(https, 'globalAgent', ['request', 'get']), + env: pick(process.env, ENV_VAR_PROXY_SEARCH_ORDER) +}; + +var loggingEnabled = + process && + process.env && + process.env.DEBUG && + process.env.DEBUG.toLowerCase().indexOf('global-tunnel') !== -1 && + console && + typeof console.log === 'function'; + +function log(message) { + if (loggingEnabled) { + console.log('DEBUG global-tunnel: ' + message); + } +} + +function resetGlobals() { + assign(http, ORIGINALS.http); + assign(https, ORIGINALS.https); + var val; + for (var key in ORIGINALS.env) { + if (Object.prototype.hasOwnProperty.call(ORIGINALS.env, key)) { + val = ORIGINALS.env[key]; + if (val !== null && val !== undefined) { + process.env[key] = val; + } + } + } +} + +/** + * Parses the de facto `http_proxy` environment. + */ +function tryParse(url) { + if (!url) { + return null; + } + + var parsed = urlParse(url); + + return { + protocol: parsed.protocol, + host: parsed.hostname, + port: parseInt(parsed.port, 10), + proxyAuth: parsed.auth + }; +} + +// Stringifies the normalized parsed config +function stringifyProxy(conf) { + return encodeUrl( + urlStringify({ + protocol: conf.protocol, + hostname: conf.host, + port: conf.port, + auth: conf.proxyAuth + }) + ); +} + +globalTunnel.isProxying = false; +globalTunnel.proxyUrl = null; +globalTunnel.proxyConfig = null; + +function findEnvVarProxy() { + var i; + var key; + var val; + var result; + for (i = 0; i < ENV_VAR_PROXY_SEARCH_ORDER.length; i++) { + key = ENV_VAR_PROXY_SEARCH_ORDER[i]; + val = process.env[key]; + if (val !== null && val !== undefined) { + // Get the first non-empty + result = result || val; + // Delete all + // NB: we do it here to prevent double proxy handling (and for example path change) + // by us and the `request` module or other sub-dependencies + delete process.env[key]; + log('Found proxy in environment variable ' + ENV_VAR_PROXY_SEARCH_ORDER[i]); + } + } + + if (!result) { + // __GLOBAL_TUNNEL_DEPENDENCY_NPMCONF__ is a hook to override the npm-conf module + var config = + (global.__GLOBAL_TUNNEL_DEPENDENCY_NPMCONF__ && + global.__GLOBAL_TUNNEL_DEPENDENCY_NPMCONF__()) || + npmConfig(); + + for (i = 0; i < NPM_CONFIG_PROXY_SEARCH_ORDER.length && !val; i++) { + val = config.get(NPM_CONFIG_PROXY_SEARCH_ORDER[i]); + } + + if (val) { + log('Found proxy in npm config ' + NPM_CONFIG_PROXY_SEARCH_ORDER[i]); + result = val; + } + } + + return result; +} + +/** + * Overrides the node http/https `globalAgent`s to use the configured proxy. + * + * If the config is empty, the `http_proxy` environment variable is checked. + * If that's not present, the NPM `http-proxy` configuration is checked. + * If neither are present no proxying will be enabled. + * + * @param {object} conf - Options + * @param {string} conf.host - Hostname or IP of the HTTP proxy to use + * @param {int} conf.port - TCP port of the proxy + * @param {string} [conf.protocol='http'] - The protocol of the proxy, 'http' or 'https' + * @param {string} [conf.proxyAuth] - Credentials for the proxy in the form userId:password + * @param {string} [conf.connect='https'] - Which protocols will use the CONNECT method 'neither', 'https' or 'both' + * @param {int} [conf.sockets=5] Maximum number of TCP sockets to use in each pool. There are two different pools for HTTP and HTTPS + * @param {object} [conf.httpsOptions] - HTTPS options + */ +globalTunnel.initialize = function(conf) { + // Don't do anything if already proxying. + // To change the settings `.end()` should be called first. + if (globalTunnel.isProxying) { + log('Already proxying'); + return; + } + + try { + // This has an effect of also removing the proxy config + // from the global env to prevent other modules (like request) doing + // double handling + var envVarProxy = findEnvVarProxy(); + + if (conf && typeof conf === 'string') { + // Passed string - parse it as a URL + conf = tryParse(conf); + } else if (conf) { + // Passed object - take it but clone for future mutations + conf = clone(conf); + } else if (envVarProxy) { + // Nothing passed - parse from the env + conf = tryParse(envVarProxy); + } else { + log('No configuration found, not proxying'); + // No config - do nothing + return; + } + + log('Proxy configuration to be used is ' + JSON.stringify(conf, null, 2)); + + if (!conf.host) { + throw new Error('upstream proxy host is required'); + } + if (!conf.port) { + throw new Error('upstream proxy port is required'); + } + + if (conf.protocol === undefined) { + conf.protocol = 'http:'; // Default to proxy speaking http + } + if (!/:$/.test(conf.protocol)) { + conf.protocol += ':'; + } + + if (!conf.connect) { + conf.connect = 'https'; // Just HTTPS by default + } + + if (['both', 'neither', 'https'].indexOf(conf.connect) < 0) { + throw new Error('valid connect options are "neither", "https", or "both"'); + } + + var connectHttp = conf.connect === 'both'; + var connectHttps = conf.connect !== 'neither'; + + if (conf.httpsOptions) { + conf.innerHttpsOpts = conf.httpsOptions; + conf.outerHttpsOpts = conf.innerHttpsOpts; + } + + http.globalAgent = globalTunnel._makeAgent(conf, 'http', connectHttp); + https.globalAgent = globalTunnel._makeAgent(conf, 'https', connectHttps); + + http.request = globalTunnel._makeHttp('request', http, 'http'); + https.request = globalTunnel._makeHttp('request', https, 'https'); + http.get = globalTunnel._makeHttp('get', http, 'http'); + https.get = globalTunnel._makeHttp('get', https, 'https'); + + globalTunnel.isProxying = true; + globalTunnel.proxyUrl = stringifyProxy(conf); + globalTunnel.proxyConfig = clone(conf); + } catch (e) { + resetGlobals(); + throw e; + } +}; + +var _makeAgent = function(conf, innerProtocol, useCONNECT) { + log('Creating proxying agent'); + var outerProtocol = conf.protocol; + innerProtocol += ':'; + + var opts = { + proxy: pick(conf, 'host', 'port', 'protocol', 'localAddress', 'proxyAuth'), + maxSockets: conf.sockets + }; + opts.proxy.innerProtocol = innerProtocol; + + if (useCONNECT) { + if (conf.proxyHttpsOptions) { + assign(opts.proxy, conf.proxyHttpsOptions); + } + if (conf.originHttpsOptions) { + assign(opts, conf.originHttpsOptions); + } + + if (outerProtocol === 'https:') { + if (innerProtocol === 'https:') { + return tunnel.httpsOverHttps(opts); + } + return tunnel.httpOverHttps(opts); + } + if (innerProtocol === 'https:') { + return tunnel.httpsOverHttp(opts); + } + return tunnel.httpOverHttp(opts); + } + if (conf.originHttpsOptions) { + throw new Error('originHttpsOptions must be combined with a tunnel:true option'); + } + if (conf.proxyHttpsOptions) { + // NB: not opts. + assign(opts, conf.proxyHttpsOptions); + } + + if (outerProtocol === 'https:') { + return new agents.OuterHttpsAgent(opts); + } + return new agents.OuterHttpAgent(opts); +}; + +/** + * Construct an agent based on: + * - is the connection to the proxy secure? + * - is the connection to the origin secure? + * - the address of the proxy + */ +globalTunnel._makeAgent = function(conf, innerProtocol, useCONNECT) { + var agent = _makeAgent(conf, innerProtocol, useCONNECT); + // Set the protocol to match that of the target request type + agent.protocol = innerProtocol + ':'; + return agent; +}; + +/** + * Override for http/https, makes sure to default the agent + * to the global agent. Due to how node implements it in lib/http.js, the + * globalAgent we define won't get used (node uses a module-scoped variable, + * not the exports field). + * @param {string} method 'request' or 'get', http/https methods + * @param {string|object} options http/https request url or options + * @param {function} [cb] + * @private + */ +globalTunnel._makeHttp = function(method, httpOrHttps, protocol) { + return function(options, callback) { + if (typeof options === 'string') { + options = urlParse(options); + } else { + options = clone(options); + } + + // Respect the default agent provided by node's lib/https.js + if ( + (options.agent === null || options.agent === undefined) && + typeof options.createConnection !== 'function' && + (options.host || options.hostname) + ) { + options.agent = options._defaultAgent || httpOrHttps.globalAgent; + } + + // Set the default port ourselves to prevent Node doing it based on the proxy agent protocol + if (options.protocol === 'https:' || (!options.protocol && protocol === 'https')) { + options.port = options.port || 443; + } + if (options.protocol === 'http:' || (!options.protocol && protocol === 'http')) { + options.port = options.port || 80; + } + + log( + 'Requesting to ' + + (options.protocol || protocol) + + '//' + + (options.host || options.hostname) + + ':' + + options.port + ); + + return ORIGINALS[protocol][method].call(httpOrHttps, options, callback); + }; +}; + +/** + * Restores global http/https agents. + */ +globalTunnel.end = function() { + resetGlobals(); + globalTunnel.isProxying = false; + globalTunnel.proxyUrl = null; + globalTunnel.proxyConfig = null; +}; |