Skip to content

Commit

Permalink
Merge pull request #382 from tomas/env-http-proxy
Browse files Browse the repository at this point in the history
Use HTTP_PROXY and HTTPS_PROXY from env, if set
  • Loading branch information
tomas authored Apr 7, 2022
2 parents 67ad8a4 + 933fd79 commit d93c442
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 13 deletions.
62 changes: 53 additions & 9 deletions lib/needle.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ Object.keys(aliased.options).map(function(k) {
//////////////////////////////////////////
// helpers

function get_env_var(keys, try_lower) {
var val, i = -1, env = process.env;
while (!val && i < keys.length-1) {
val = env[keys[++i]];
if (!val && try_lower) {
val = env[keys[i].toLowerCase()];
}
}
return val;
}

function keys_by_type(type) {
return Object.keys(defaults).map(function(el) {
if (defaults[el] !== null && defaults[el].constructor == type)
Expand Down Expand Up @@ -168,6 +179,32 @@ function resolve_url(href, base) {
return url.resolve(base, href);
}

function host_and_ports_match(url1, url2) {
if (url1.indexOf('http') < 0) url1 = 'http://' + url1;
if (url2.indexOf('http') < 0) url2 = 'http://' + url2;
var a = url.parse(url1), b = url.parse(url2);

return a.host == b.host
&& String(a.port || (a.protocol == 'https:' ? 443 : 80))
== String(b.port || (b.protocol == 'https:' ? 443 : 80));
}

// returns false if a no_proxy host matches given url
function should_proxy_to(url) {
var no_proxy = get_env_var(['NO_PROXY'], true);
if (!no_proxy) return true;

var host, hosts = no_proxy.split(',');
for (var i in hosts) {
host = hosts[i];
if (host_and_ports_match(host, url)) {
return false;
}
}

return true;
}

function pump_streams(streams, cb) {
if (stream.pipeline)
return stream.pipeline.apply(null, streams.concat(cb));
Expand Down Expand Up @@ -299,19 +336,26 @@ Needle.prototype.setup = function(uri, options) {
}
}

var env_proxy = get_env_var(['HTTP_PROXY', 'HTTPS_PROXY'], true);
if (!config.proxy && env_proxy) config.proxy = env_proxy;

// if proxy is present, set auth header from either url or proxy_user option.
if (config.proxy) {
if (config.proxy.indexOf('http') === -1)
config.proxy = 'http://' + config.proxy;
if (should_proxy_to(uri)) {
if (config.proxy.indexOf('http') === -1)
config.proxy = 'http://' + config.proxy;

if (config.proxy.indexOf('@') !== -1) {
var proxy = (url.parse(config.proxy).auth || '').split(':');
options.proxy_user = proxy[0];
options.proxy_pass = proxy[1];
}

if (config.proxy.indexOf('@') !== -1) {
var proxy = (url.parse(config.proxy).auth || '').split(':');
options.proxy_user = proxy[0];
options.proxy_pass = proxy[1];
if (options.proxy_user)
config.headers['proxy-authorization'] = auth.basic(options.proxy_user, options.proxy_pass);
} else {
delete config.proxy;
}

if (options.proxy_user)
config.headers['proxy-authorization'] = auth.basic(options.proxy_user, options.proxy_pass);
}

// now that all our headers are set, overwrite them if instructed.
Expand Down
37 changes: 33 additions & 4 deletions test/proxy_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,41 @@ describe('proxy option', function() {

describe('when valid url is passed', function() {

it('proxies request', function(done) {
send_request({ proxy: nonexisting_host + ':123/done' }, proxied(nonexisting_host, '123', done))
describe('without NO_PROXY env var set', function() {
it('proxies request', function(done) {
send_request({ proxy: nonexisting_host + ':123/done' }, proxied(nonexisting_host, '123', done))
})

it('does not set a Proxy-Authorization header', function(done) {
send_request({ proxy: nonexisting_host + ':123/done' }, no_proxy_auth(done));
})
})

it('does not set a Proxy-Authorization header', function(done) {
send_request({ proxy: nonexisting_host + ':123/done' }, no_proxy_auth(done));
describe('with NO_PROXY env var set', function() {

it('proxies request if matching host not found in list', function(done) {
process.env.NO_PROXY = 'foo';
send_request({ proxy: nonexisting_host + ':123/done' }, proxied(nonexisting_host, '123', function() {
delete process.env.NO_PROXY;
done();
}))
})

it('proxies request if matching host in list but different port', function(done) {
process.env.NO_PROXY = 'localhost';
send_request({ proxy: nonexisting_host + ':123/done' }, proxied(nonexisting_host, '123', function() {
delete process.env.NO_PROXY;
done();
}))
})

it('does not proxy if matching host found in list', function(done) {
process.env.NO_PROXY = 'foo,' + url;
send_request({ proxy: nonexisting_host + ':123/done' }, not_proxied(function() {
delete process.env.NO_PROXY;
done();
}))
})
})

describe('and proxy url contains user:pass', function() {
Expand Down

0 comments on commit d93c442

Please sign in to comment.