snowflake-sdk
Version:
Node.js driver for Snowflake
147 lines • 7.2 kB
JavaScript
"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