Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

snowflake-sdk

Package Overview
Dependencies
Maintainers
2
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

snowflake-sdk - npm Package Compare versions

Comparing version 1.9.1 to 1.9.2

285

lib/agent/https_proxy_ocsp_agent.js
/*
* Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>
* Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved.
*/
/**
* Module dependencies.
*/
var net = require('net');
var tls = require('tls');
var url = require('url');
var extend = require('extend');
var HttpsProxyAgent = require('https-proxy-agent');
var createAgent = require('agent-base');
var inherits = require('util').inherits;
var debug = require('debug')('https-proxy-agent');
var SocketUtil = require('./socket_util');
const tls = require('tls');
const { HttpsProxyAgent } = require('https-proxy-agent');
const SocketUtil = require('./socket_util');
const Logger = require('../logger');
/**
* Module exports.
*/
module.exports = createHttpsProxyAgent;
module.exports = HttpsProxyOcspAgent;
/**
* The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to the
* specified "HTTP(s) proxy server" in order to proxy HTTPS requests.
*
* @api public
*/
function HttpsProxyOcspAgent(opts)
{
if (!(this instanceof HttpsProxyOcspAgent))
{
return new HttpsProxyOcspAgent(opts);
}
if ('string' == typeof opts)
{
opts = url.parse(opts);
}
if (!opts)
{
throw new Error('an HTTP(S) proxy server `host` and `port` must be specified!');
}
debug('creating new HttpsProxyAgent instance: %o', opts);
var HttpsAgent = new HttpsProxyAgent(opts);
var Agent = createAgent.call(this, connect);
HttpsAgent.callback = Agent.callback;
HttpsAgent.timeout = Agent.timeout;
HttpsAgent.options = Agent.opts;
var proxy = extend({}, opts);
// if `true`, then connect to the proxy server over TLS. defaults to `false`.
HttpsAgent.secureProxy = proxy.protocol ? /^https:?$/i.test(proxy.protocol) : false;
// prefer `hostname` over `host`, and set the `port` if needed
proxy.host = proxy.hostname || proxy.host;
proxy.port = +proxy.port || (this.secureProxy ? 443 : 80);
if (proxy.host && proxy.path)
{
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete proxy.path;
delete proxy.pathname;
}
if (proxy.user && proxy.password)
{
// user:password
proxy.auth = proxy.user + ':' + proxy.password;
delete proxy.user;
delete proxy.password;
if (!HttpsAgent.secureProxy)
{
Logger.getInstance().warn("Warning: connecting to an authenticated proxy server through HTTP. To use HTTPS, set 'proxyProtocol' to 'HTTPS'")
}
}
HttpsAgent.proxy = proxy;
return HttpsAgent;
function createHttpsProxyAgent(opts) {
// HttpsProxyAgent >= 6.x takes two arguments for its constructor
// See: https://github.com/TooTallNate/proxy-agents/blob/main/packages/https-proxy-agent/CHANGELOG.md#600
const { host: hostname, port, user: username, password, protocol: rawProtocol, ...agentOptions } = opts;
const protocol = rawProtocol.endsWith(':') ? rawProtocol : `${rawProtocol}:`;
return new HttpsProxyOcspAgent({ hostname, port, username, password, protocol }, agentOptions);
}
inherits(HttpsProxyAgent, createAgent);
/**
* Called when the node-core HTTP client library is creating a new HTTP request.
*
* @api public
*/
function connect(req, opts, fn)
{
var proxy = this.proxy;
var agent = this;
Logger.getInstance().debug("Using proxy=%s for host %s", proxy.host, opts.host);
// create a socket connection to the proxy server
var socket;
if (this.secureProxy)
{
socket = tls.connect(proxy);
class HttpsProxyOcspAgent extends HttpsProxyAgent {
constructor(proxy, opts) {
super(proxy, opts);
}
else
{
socket = net.connect(proxy);
}
// we need to buffer any HTTP traffic that happens with the proxy before we get
// the CONNECT response, so that if the response is anything other than an "200"
// response code, then we can re-play the "data" events on the socket once the
// HTTP parser is hooked up...
var buffers = [];
var buffersLength = 0;
function read()
{
var b = socket.read();
if (b)
{
ondata(b);
async connect(req, opts) {
Logger.getInstance().debug('Using proxy=%s for host %s', this.proxy.hostname, opts.host);
const socket = await super.connect(req, opts);
if (socket instanceof tls.TLSSocket) {
SocketUtil.secureSocket(socket, opts.host, this);
}
else
{
socket.once('readable', read);
}
return socket;
}
function cleanup()
{
socket.removeListener('data', ondata);
socket.removeListener('end', onend);
socket.removeListener('error', onerror);
socket.removeListener('close', onclose);
socket.removeListener('readable', read);
}
function onclose(err)
{
debug('onclose had error %o', err);
}
function onend()
{
debug('onend');
}
function onerror(err)
{
cleanup();
fn(err);
}
function ondata(b)
{
buffers.push(b);
buffersLength += b.length;
var buffered = Buffer.concat(buffers, buffersLength);
var str = buffered.toString('ascii');
if (!~str.indexOf('\r\n\r\n'))
{
// keep buffering
debug('have not received end of HTTP headers yet...');
if (socket.read)
{
read();
}
else
{
socket.once('data', ondata);
}
return;
}
var firstLine = str.substring(0, str.indexOf('\r\n'));
var statusCode = +firstLine.split(' ')[1];
debug('got proxy server response: %o', firstLine);
if (200 === statusCode)
{
// 200 Connected status code!
var sock = socket;
// nullify the buffered data since we won't be needing it
buffers = buffered = null;
if (opts.secureEndpoint)
{
var host = opts.host;
// since the proxy is connecting to an SSL server, we have
// to upgrade this socket connection to an SSL connection
debug('upgrading proxy-connected socket to TLS connection: %o', opts.host);
opts.socket = socket;
opts.servername = opts.host;
opts.host = null;
opts.hostname = null;
opts.port = null;
sock = tls.connect(opts);
// pass in proxy agent to apply proxy for ocsp connection
// ocsp connection won't be secureEndpoint so no worry for recursive
// ocsp validation
SocketUtil.secureSocket(sock, host, agent);
}
cleanup();
fn(null, sock);
}
else
{
// some other status code that's not 200... need to re-play the HTTP header
// "data" events onto the socket once the HTTP machinery is attached so that
// the user can parse and handle the error status code
cleanup();
// save a reference to the concat'd Buffer for the `onsocket` callback
buffers = buffered;
// need to wait for the "socket" event to re-play the "data" events
req.once('socket', onsocket);
fn(null, socket);
}
}
function onsocket(socket)
{
// replay the "buffers" Buffer onto the `socket`, since at this point
// the HTTP module machinery has been hooked up for the user
if ('function' == typeof socket.ondata)
{
// node <= v0.11.3, the `ondata` function is set on the socket
socket.ondata(buffers, 0, buffers.length);
}
else if (socket.listeners('data').length > 0)
{
// node > v0.11.3, the "data" event is listened for directly
socket.emit('data', buffers);
}
else
{
// never?
throw new Error('should not happen...');
}
// nullify the cached Buffer instance
buffers = null;
}
socket.on('error', onerror);
socket.on('close', onclose);
socket.on('end', onend);
if (socket.read)
{
read();
}
else
{
socket.once('data', ondata);
}
var hostname = opts.host + ':' + opts.port;
var msg = 'CONNECT ' + hostname + ' HTTP/1.1\r\n';
var auth = proxy.auth;
if (auth)
{
msg += 'Proxy-Authorization: Basic ' + Buffer.from(auth, 'utf8').toString('base64') + '\r\n';
}
msg += 'Host: ' + hostname + '\r\n' +
'Connection: close\r\n' +
'\r\n';
socket.write(msg);
}

3

lib/connection/connection_config.js

@@ -206,3 +206,3 @@ /*

var proxyPassword = options.proxyPassword;
var proxyProtocol = options.proxyProtocol;
var proxyProtocol = options.proxyProtocol || 'http';
var noProxy = options.noProxy;

@@ -271,2 +271,3 @@

port: proxyPort,
protocol: proxyProtocol,
noProxy: noProxy

@@ -273,0 +274,0 @@ };

@@ -39,2 +39,3 @@ /*

HttpClient.prototype.request = function (options) {
let request;
const requestOptions = prepareRequestOptions.call(this, options);

@@ -41,0 +42,0 @@ let sendRequest = async function sendRequest() {

@@ -56,2 +56,12 @@ /*

Logger.getInstance().trace(`Create and add to cache new agent ${agentId}`);
// detect and log PROXY envvar + agent proxy settings
const compareAndLogEnvAndAgentProxies = Util.getCompareAndLogEnvAndAgentProxies(agentOptions);
Logger.getInstance().debug(`Proxy settings used in requests:${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(`${compareAndLogEnvAndAgentProxies.warnings}`);
}
return agent;

@@ -58,0 +68,0 @@ }

@@ -73,2 +73,7 @@ /*

{
// if we're running in DEBUG loglevel, probably we want to see the full error too
const logErr = err ? JSON.stringify(err, Util.getCircularReplacer())
: `status: ${JSON.stringify(response.status)} ${JSON.stringify(response.statusText)}`
+ ` headers: ${JSON.stringify(response.headers)}`;
Logger.getInstance().debug('Encountered an error when getting data from cloud storage: ' + logErr);
// if we haven't exceeded the maximum number of retries yet and the

@@ -88,3 +93,3 @@ // server came back with a retryable error code.

const nextSendRequestWaitTimeMs = sleep * 1000;
Logger.getInstance().trace("Request will be retried after %d milliseconds", nextSendRequestWaitTimeMs);
Logger.getInstance().trace("Request will be retried after %d milliseconds", Math.floor(nextSendRequestWaitTimeMs));
setTimeout(sendRequest, nextSendRequestWaitTimeMs);

@@ -91,0 +96,0 @@ return

@@ -618,2 +618,6 @@ /*

{
// if we're running in DEBUG loglevel, probably we want to see the full error instead
Logger.getInstance().debug('Encountered an error when sending the request. Details: '
+ JSON.stringify(err, Util.getCircularReplacer()));
err = Errors.createNetworkError(

@@ -620,0 +624,0 @@ ErrorCodes.ERR_SF_NETWORK_COULD_NOT_CONNECT, err);

@@ -640,2 +640,71 @@ /*

return subdomainRegex.test(value);
};
/**
* Try to get the PROXY environmental variables
* On Windows, envvar name is case-insensitive, but on *nix, it's case-sensitive
*
* Compare them with the proxy specified on the Connection, if any
* Return with the log constructed from the components detection and comparison
* If there's something to warn the user about, return that too
*
* @param the agentOptions object from agent creation
* @returns {object}
*/
exports.getCompareAndLogEnvAndAgentProxies = function(agentOptions) {
const envProxy = {};
let logMessages = {'messages': '', 'warnings': ''};
envProxy.httpProxy = process.env.HTTP_PROXY || process.env.http_proxy;
envProxy.httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy;
envProxy.noProxy = process.env.NO_PROXY || process.env.no_proxy;
envProxy.logHttpProxy = envProxy.httpProxy ?
'HTTP_PROXY: ' + envProxy.httpProxy : 'HTTP_PROXY: <unset>';
envProxy.logHttpsProxy = envProxy.httpsProxy ?
'HTTPS_PROXY: ' + envProxy.httpsProxy : 'HTTPS_PROXY: <unset>';
envProxy.logNoProxy = envProxy.noProxy ?
'NO_PROXY: ' + envProxy.noProxy : 'NO_PROXY: <unset>';
// log PROXY envvars
if (envProxy.httpProxy || envProxy.httpsProxy) {
logMessages.messages = logMessages.messages + ` // PROXY environment variables: `
+ `${envProxy.logHttpProxy} ${envProxy.logHttpsProxy} ${envProxy.logNoProxy}.`;
}
// log proxy config on Connection, if any set
if (agentOptions.host) {
const proxyHostAndPort = agentOptions.host + ':' + agentOptions.port
const proxyProtocolHostAndPort = agentOptions.protocol ?
' protocol=' + agentOptions.protocol + ' proxy=' + proxyHostAndPort
: ' proxy=' + proxyHostAndPort;
const proxyUsername = agentOptions.user ? ' user=' + agentOptions.user : ''
logMessages.messages = logMessages.messages + ` // Proxy configured in Connection:${proxyProtocolHostAndPort}${proxyUsername}`;
// check if both the PROXY envvars and Connection proxy config is set
// generate warnings if they are, and are also different
if (envProxy.httpProxy &&
this.removeScheme(envProxy.httpProxy).toLowerCase() != this.removeScheme(proxyHostAndPort).toLowerCase()) {
logMessages.warnings = logMessages.warnings + ` Using both the HTTP_PROXY (${envProxy.httpProxy})`
+` and the proxyHost:proxyPort (${proxyHostAndPort}) settings to connect, but with different values.`
+` If you experience connectivity issues, try unsetting one of them.`
};
if (envProxy.httpsProxy &&
this.removeScheme(envProxy.httpsProxy).toLowerCase() != this.removeScheme(proxyHostAndPort).toLowerCase()) {
logMessages.warnings = logMessages.warnings + ` Using both the HTTPS_PROXY (${envProxy.httpsProxy})`
+` and the proxyHost:proxyPort (${proxyHostAndPort}) settings to connect, but with different values.`
+` If you experience connectivity issues, try unsetting one of them.`
};
}
logMessages.messages = logMessages.messages ? logMessages.messages : ' none.'
return logMessages;
};
/**
* remove http:// or https:// from the input, e.g. used with proxy URL
* @param input
* @returns {string}
*/
exports.removeScheme = function (input) {
return input.toString().replace(/(^\w+:|^)\/\//, '');
};
{
"name": "snowflake-sdk",
"version": "1.9.1",
"version": "1.9.2",
"description": "Node.js driver for Snowflake",

@@ -25,4 +25,4 @@ "dependencies": {

"generic-pool": "^3.8.2",
"glob": "^7.1.6",
"https-proxy-agent": "^5.0.1",
"glob": "^9.0.0",
"https-proxy-agent": "^7.0.2",
"jsonwebtoken": "^9.0.0",

@@ -29,0 +29,0 @@ "mime-types": "^2.1.29",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc