UNPKG

snowflake-sdk

Version:
147 lines 7.2 kB
"use strict"; const Util = require('../util'); const ProxyUtil = require('../proxy_util'); const Base = require('./base'); const HttpsOcspAgent = require('../agent/https_ocsp_agent'); const HttpsCrlAgent = require('../agent/https_crl_agent').default; const HttpsProxyAgent = require('../agent/https_proxy_agent').default; const HttpAgent = require('http').Agent; const GlobalConfig = require('../../lib/global_config'); const Logger = require('../logger'); const RequestUtil = require('../http/request_util'); const { isCrlValidationEnabled } = require('../agent/crl_validator'); /** * Creates a client that can be used to make requests in Node.js. * * @param {ConnectionConfig} connectionConfig * @constructor */ function NodeHttpClient(connectionConfig) { Logger.getInstance().trace('Initializing NodeHttpClient with Connection Config[%s]', connectionConfig.describeIdentityAttributes()); Base.apply(this, [connectionConfig]); } Util.inherits(NodeHttpClient, Base); function getFromCacheOrCreate(AgentClass, options, agentId, agentCache) { Logger.getInstance().trace('Agent[id: %s] - trying to retrieve from cache or create.', agentId); let agent = {}; function createAgent(AgentClass, agentOptions, agentId) { Logger.getInstance().debug('Agent[id: %s] - creating a new agent instance with idle timeout=%dms.', agentId, agentOptions.timeout); const agent = new AgentClass(agentOptions); agentCache.set(agentId, agent); Logger.getInstance().trace('Agent[id: %s] - new instance stored in cache.', agentId); // detect and log PROXY envvar + agent proxy settings const compareAndLogEnvAndAgentProxies = ProxyUtil.getCompareAndLogEnvAndAgentProxies(agentOptions); Logger.getInstance().debug('Agent[id: %s] - proxy settings used in requests: %s', agentId, compareAndLogEnvAndAgentProxies.messages); // if there's anything to warn on (e.g. both envvar + agent proxy used, and they are different) // log warnings on them if (compareAndLogEnvAndAgentProxies.warnings) { Logger.getInstance().warn('Agent[id: %s] - %s', agentId, compareAndLogEnvAndAgentProxies.warnings); } return agent; } if (agentCache.has(agentId)) { Logger.getInstance().trace('Agent[id: %s] - retrieving an agent instance from cache.', agentId); agent = agentCache.get(agentId); } else { agent = createAgent(AgentClass, options, agentId); } return agent; } function enrichAgentOptionsWithProxyConfig(agentOptions, proxy) { agentOptions.host = proxy.host; agentOptions.port = proxy.port; agentOptions.protocol = proxy.protocol; agentOptions.useForOCSP = proxy.useForOCSP; agentOptions.noProxy = proxy.noProxy; if (proxy.user && proxy.password) { agentOptions.user = proxy.user; agentOptions.password = proxy.password; } } function isBypassProxy(proxy, destination, agentId) { const matches = ProxyUtil.isByPassProxy(proxy, destination); if (matches) { Logger.getInstance().debug('Agent[id: %s] - bypassing proxy allowed for destination: %s', agentId, destination); return true; } return false; } /** * @inheritDoc */ NodeHttpClient.prototype.getAgent = function (parsedUrl, proxy, mock) { Logger.getInstance().trace('Agent[url: %s] - getting an agent instance.', RequestUtil.describeURL(parsedUrl.href)); if (!proxy && GlobalConfig.isEnvProxyActive()) { const isHttps = parsedUrl.protocol === 'https:'; proxy = ProxyUtil.getProxyFromEnv(isHttps); if (proxy) { Logger.getInstance().debug('Agent[url: %s] - proxy info loaded from the environment variable. Proxy host: %s', RequestUtil.describeURL(parsedUrl.href), proxy.host); } } return getProxyAgent(proxy, parsedUrl, parsedUrl.href, mock, this._connectionConfig); }; // TODO: // The 'destination' and 'mock' arguments in getProxyAgent introduce unnecessary complexity to // the function's interface and are not essential to its core purpose. Consider refactoring // getProxyAgent to remove these arguments, simplifying its signature and usage. function getProxyAgent(proxyOptions, parsedUrl, destination, mock, connectionConfig) { Logger.getInstance().trace('Agent[url: %s] - getting a proxy agent instance.', RequestUtil.describeURL(parsedUrl.href)); const agentOptions = { protocol: parsedUrl.protocol, hostname: parsedUrl.hostname, keepAlive: GlobalConfig.getKeepAlive(), // Idle socket timeout in milliseconds - only affects inactive sockets. // Does not affect pending requests. timeout: 30 * 1000, }; if (mock) { const mockAgent = mock.agentClass(agentOptions); if (mockAgent.protocol === parsedUrl.protocol) { Logger.getInstance().debug('Agent[url: %s] - the mock agent will be used.', RequestUtil.describeURL(parsedUrl.href)); return mockAgent; } } const destHost = ProxyUtil.getHostFromURL(destination); const agentId = createAgentId({ protocol: agentOptions.protocol, hostname: agentOptions.hostname, destination: destHost, keepAlive: agentOptions.keepAlive, }); Logger.getInstance().debug('Agent[id: %s] - the destination host is: %s.', agentId, destHost); const agentCache = connectionConfig.agentCache; const bypassProxy = isBypassProxy(proxyOptions, destHost, agentId); let agent; const isHttps = agentOptions.protocol === 'https:'; if (isHttps) { agentOptions.crlValidatorConfig = connectionConfig.crlValidatorConfig; if (proxyOptions && !bypassProxy) { Logger.getInstance().trace('Agent[id: %s] - using HTTPS agent enriched with proxy options.', agentId); enrichAgentOptionsWithProxyConfig(agentOptions, proxyOptions); agent = getFromCacheOrCreate(HttpsProxyAgent, agentOptions, agentId, agentCache); } else { const AgentClass = isCrlValidationEnabled(connectionConfig.crlValidatorConfig) ? HttpsCrlAgent : HttpsOcspAgent; Logger.getInstance().trace(`Agent[id: %s] - using ${AgentClass.name} agent without proxy.`, agentId); agent = getFromCacheOrCreate(AgentClass, agentOptions, agentId, agentCache); } } else if (proxyOptions && !bypassProxy) { Logger.getInstance().trace('Agent[id: %s] - using HTTP agent enriched with proxy options.', agentId); enrichAgentOptionsWithProxyConfig(agentOptions, proxyOptions); agent = getFromCacheOrCreate(HttpAgent, agentOptions, agentId, agentCache); } else { Logger.getInstance().trace('Agent[id: %s] - using HTTP agent without proxy.', agentId); agent = getFromCacheOrCreate(HttpAgent, agentOptions, agentId, agentCache); } return agent; } function createAgentId({ protocol, hostname, destination, keepAlive }) { return [protocol, hostname, destination, keepAlive ? 'keepAlive' : 'noKeepAlive'].join('-'); } module.exports = { NodeHttpClient, getProxyAgent, isBypassProxy }; //# sourceMappingURL=node_untyped.js.map