Skip to content

Commit

Permalink
Adding support for no_proxy env variable (#1693)
Browse files Browse the repository at this point in the history
* Adding support for no_proxy env variable

* Adds support for the no_proxy environment variable commonly available
  with programs supporting the http_proxy/https_proxy environment
  variables.
* Adds tests to test the no_proxy environment variable.

* Adding documentation for the proxy env variables

* Adds documentation to README.md for the supported, conventional
  http_proxy, https_proxy, and no_proxy environment variables.
  • Loading branch information
Chance Dickson authored and emilyemorehouse committed Aug 7, 2018
1 parent b9f68bd commit 38de252
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 11 deletions.
6 changes: 5 additions & 1 deletion README.md
Expand Up @@ -353,7 +353,11 @@ These are the available config options for making requests. Only the `url` is re
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),

// 'proxy' defines the hostname and port of the proxy server
// 'proxy' defines the hostname and port of the proxy server.
// You can also define your proxy using the conventional `http_proxy` and
// `https_proxy` environment variables. If you are using environment variables
// for your proxy configuration, you can also define a `no_proxy` environment
// variable as a comma-separated list of domains that should not be proxied.
// Use `false` to disable proxies, ignoring environment variables.
// `auth` indicates that HTTP Basic auth should be used to connect to the proxy, and
// supplies credentials.
Expand Down
48 changes: 38 additions & 10 deletions lib/adapters/http.js
Expand Up @@ -102,17 +102,45 @@ module.exports = function httpAdapter(config) {
var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()];
if (proxyUrl) {
var parsedProxyUrl = url.parse(proxyUrl);
proxy = {
host: parsedProxyUrl.hostname,
port: parsedProxyUrl.port
};

if (parsedProxyUrl.auth) {
var proxyUrlAuth = parsedProxyUrl.auth.split(':');
proxy.auth = {
username: proxyUrlAuth[0],
password: proxyUrlAuth[1]
var noProxyEnv = process.env.no_proxy || process.env.NO_PROXY;
var shouldProxy = true;

if (noProxyEnv) {
var noProxy = noProxyEnv.split(',').map(function trim(s) {
return s.trim();
});

shouldProxy = !noProxy.some(function proxyMatch(proxyElement) {
if (!proxyElement) {
return false;
}
if (proxyElement === '*') {
return true;
}
if (proxyElement[0] === '.' &&
parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement &&
proxyElement.match(/\./g).length === parsed.hostname.match(/\./g).length) {
return true;
}

return parsed.hostname === proxyElement;
});
}


if (shouldProxy) {
proxy = {
host: parsedProxyUrl.hostname,
port: parsedProxyUrl.port
};

if (parsedProxyUrl.auth) {
var proxyUrlAuth = parsedProxyUrl.auth.split(':');
proxy.auth = {
username: proxyUrlAuth[0],
password: proxyUrlAuth[1]
};
}
}
}
}
Expand Down
77 changes: 77 additions & 0 deletions test/unit/adapters/http.js
Expand Up @@ -21,6 +21,9 @@ describe('supports http with nodejs', function () {
if (process.env.http_proxy) {
delete process.env.http_proxy;
}
if (process.env.no_proxy) {
delete process.env.no_proxy;
}
});

it('should respect the timeout property', function (done) {
Expand Down Expand Up @@ -403,6 +406,80 @@ describe('supports http with nodejs', function () {
});
});

it('should not use proxy for domains in no_proxy', function (done) {
server = http.createServer(function (req, res) {
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
res.end('4567');
}).listen(4444, function () {
proxy = http.createServer(function (request, response) {
var parsed = url.parse(request.url);
var opts = {
host: parsed.hostname,
port: parsed.port,
path: parsed.path
};

http.get(opts, function (res) {
var body = '';
res.on('data', function (data) {
body += data;
});
res.on('end', function () {
response.setHeader('Content-Type', 'text/html; charset=UTF-8');
response.end(body + '1234');
});
});

}).listen(4000, function () {
// set the env variable
process.env.http_proxy = 'http://localhost:4000/';
process.env.no_proxy = 'foo.com, localhost,bar.net , , quix.co';

axios.get('http://localhost:4444/').then(function (res) {
assert.equal(res.data, '4567', 'should not use proxy for domains in no_proxy');
done();
});
});
});
});

it('should use proxy for domains not in no_proxy', function (done) {
server = http.createServer(function (req, res) {
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
res.end('4567');
}).listen(4444, function () {
proxy = http.createServer(function (request, response) {
var parsed = url.parse(request.url);
var opts = {
host: parsed.hostname,
port: parsed.port,
path: parsed.path
};

http.get(opts, function (res) {
var body = '';
res.on('data', function (data) {
body += data;
});
res.on('end', function () {
response.setHeader('Content-Type', 'text/html; charset=UTF-8');
response.end(body + '1234');
});
});

}).listen(4000, function () {
// set the env variable
process.env.http_proxy = 'http://localhost:4000/';
process.env.no_proxy = 'foo.com, ,bar.net , quix.co';

axios.get('http://localhost:4444/').then(function (res) {
assert.equal(res.data, '45671234', 'should use proxy for domains not in no_proxy');
done();
});
});
});
});

it('should support HTTP proxy auth', function (done) {
server = http.createServer(function (req, res) {
res.end();
Expand Down

0 comments on commit 38de252

Please sign in to comment.