From 1c739fda019e162f4446fc83568bbb131a1fbaa5 Mon Sep 17 00:00:00 2001 From: JEROMEH Date: Tue, 7 May 2019 11:41:16 +0200 Subject: [PATCH 1/4] extract uriInNoProxy function in a separate lib file --- lib/getProxyFromURI.js | 37 +------------------------------------ lib/uriInNoProxy.js | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 36 deletions(-) create mode 100644 lib/uriInNoProxy.js diff --git a/lib/getProxyFromURI.js b/lib/getProxyFromURI.js index 0b9b18e5a..d6b9afa1c 100644 --- a/lib/getProxyFromURI.js +++ b/lib/getProxyFromURI.js @@ -1,41 +1,6 @@ 'use strict' -function formatHostname (hostname) { - // canonicalize the hostname, so that 'oogle.com' won't match 'google.com' - return hostname.replace(/^\.*/, '.').toLowerCase() -} - -function parseNoProxyZone (zone) { - zone = zone.trim().toLowerCase() - - var zoneParts = zone.split(':', 2) - var zoneHost = formatHostname(zoneParts[0]) - var zonePort = zoneParts[1] - var hasPort = zone.indexOf(':') > -1 - - return {hostname: zoneHost, port: zonePort, hasPort: hasPort} -} - -function uriInNoProxy (uri, noProxy) { - var port = uri.port || (uri.protocol === 'https:' ? '443' : '80') - var hostname = formatHostname(uri.hostname) - var noProxyList = noProxy.split(',') - - // iterate through the noProxyList until it finds a match. - return noProxyList.map(parseNoProxyZone).some(function (noProxyZone) { - var isMatchedAt = hostname.indexOf(noProxyZone.hostname) - var hostnameMatched = ( - isMatchedAt > -1 && - (isMatchedAt === hostname.length - noProxyZone.hostname.length) - ) - - if (noProxyZone.hasPort) { - return (port === noProxyZone.port) && hostnameMatched - } - - return hostnameMatched - }) -} +var uriInNoProxy = require('./uriInNoProxy') function getProxyFromURI (uri) { // Decide the proper request proxy to use based on the request URI object and the diff --git a/lib/uriInNoProxy.js b/lib/uriInNoProxy.js new file mode 100644 index 000000000..07687910f --- /dev/null +++ b/lib/uriInNoProxy.js @@ -0,0 +1,40 @@ +'use strict' + +function formatHostname (hostname) { + // canonicalize the hostname, so that 'oogle.com' won't match 'google.com' + return hostname.replace(/^\.*/, '.').toLowerCase() +} + +function parseNoProxyZone (zone) { + zone = zone.trim().toLowerCase() + + var zoneParts = zone.split(':', 2) + var zoneHost = formatHostname(zoneParts[0]) + var zonePort = zoneParts[1] + var hasPort = zone.indexOf(':') > -1 + + return {hostname: zoneHost, port: zonePort, hasPort: hasPort} +} + +function uriInNoProxy (uri, noProxy) { + var port = uri.port || (uri.protocol === 'https:' ? '443' : '80') + var hostname = formatHostname(uri.hostname) + var noProxyList = noProxy.split(',') + + // iterate through the noProxyList until it finds a match. + return noProxyList.map(parseNoProxyZone).some(function (noProxyZone) { + var isMatchedAt = hostname.indexOf(noProxyZone.hostname) + var hostnameMatched = ( + isMatchedAt > -1 && + (isMatchedAt === hostname.length - noProxyZone.hostname.length) + ) + + if (noProxyZone.hasPort) { + return (port === noProxyZone.port) && hostnameMatched + } + + return hostnameMatched + }) +} + +module.exports = uriInNoProxy From 8062dd00cf28c0749e418a43bc183cc0ec4d52be Mon Sep 17 00:00:00 2001 From: JEROMEH Date: Tue, 7 May 2019 11:42:52 +0200 Subject: [PATCH 2/4] noProxy option added --- README.md | 1 + request.js | 10 ++++++++-- tests/test-proxy.js | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b71ea6428..fe2e52493 100644 --- a/README.md +++ b/README.md @@ -833,6 +833,7 @@ The first argument can be either a `url` or an `options` object. The only requir - `localAddress` - local interface to bind for network connections. - `proxy` - an HTTP proxy to be used. Supports proxy Auth with Basic Auth, identical to support for the `url` parameter (by embedding the auth info in the `uri`) +- `noProxy` - no_proxy option - `strictSSL` - if `true`, requires SSL certificates be valid. **Note:** to use your own certificate authority, you need to specify an agent that was created with that CA as an option. - `tunnel` - controls the behavior of [HTTP `CONNECT` tunneling](https://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_tunneling) diff --git a/request.js b/request.js index 198b76093..f7590e3f4 100644 --- a/request.js +++ b/request.js @@ -19,6 +19,7 @@ var isTypedArray = require('is-typedarray').strict var helpers = require('./lib/helpers') var cookies = require('./lib/cookies') var getProxyFromURI = require('./lib/getProxyFromURI') +var uriInNoProxy = require('./lib/uriInNoProxy') var Querystring = require('./lib/querystring').Querystring var Har = require('./lib/har').Har var Auth = require('./lib/auth').Auth @@ -273,8 +274,13 @@ Request.prototype.init = function (options) { return self.emit('error', new Error(message)) } - if (!self.hasOwnProperty('proxy')) { - self.proxy = getProxyFromURI(self.uri) + if (self.hasOwnProperty('proxy')) { + // disable proxy in case of uri math to noProxy option + if (self.hasOwnProperty('noProxy') && uriInNoProxy(self.uri, self.noProxy)) { + self.proxy = null + } + } else { + self.proxy = getProxyFromURI(self.uri, self.noProxy) } self.tunnel = self._tunnel.isEnabled() diff --git a/tests/test-proxy.js b/tests/test-proxy.js index 77cb7a831..2803e8205 100644 --- a/tests/test-proxy.js +++ b/tests/test-proxy.js @@ -264,6 +264,11 @@ function addTests () { } }, true) + runTest('noProxy used with explicit proxy passed', { + proxy: s.url, + noProxy: '*' + }, false) + // misc // this fails if the check 'isMatchedAt > -1' in lib/getProxyFromURI.js is From b27a4e811b605a3e8db77579ae10302412f268d2 Mon Sep 17 00:00:00 2001 From: JEROMEH Date: Tue, 7 May 2019 12:11:04 +0200 Subject: [PATCH 3/4] add noProxy * value support --- request.js | 2 +- tests/test-proxy.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/request.js b/request.js index f7590e3f4..2ce37801d 100644 --- a/request.js +++ b/request.js @@ -276,7 +276,7 @@ Request.prototype.init = function (options) { if (self.hasOwnProperty('proxy')) { // disable proxy in case of uri math to noProxy option - if (self.hasOwnProperty('noProxy') && uriInNoProxy(self.uri, self.noProxy)) { + if (self.hasOwnProperty('noProxy') && (self.noProxy === '*' || uriInNoProxy(self.uri, self.noProxy))) { self.proxy = null } } else { diff --git a/tests/test-proxy.js b/tests/test-proxy.js index 2803e8205..1003751f2 100644 --- a/tests/test-proxy.js +++ b/tests/test-proxy.js @@ -269,6 +269,11 @@ function addTests () { noProxy: '*' }, false) + runTest('noProxy used with explicit proxy passed', { + proxy: s.url, + noProxy: 'google.com' + }, false) + // misc // this fails if the check 'isMatchedAt > -1' in lib/getProxyFromURI.js is From 8e86cc1aa43f9309f19150d0ada0d7b0545bf734 Mon Sep 17 00:00:00 2001 From: JEROMEH Date: Tue, 7 May 2019 12:32:31 +0200 Subject: [PATCH 4/4] simplify logic --- request.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/request.js b/request.js index 2ce37801d..547f947e9 100644 --- a/request.js +++ b/request.js @@ -274,13 +274,11 @@ Request.prototype.init = function (options) { return self.emit('error', new Error(message)) } - if (self.hasOwnProperty('proxy')) { - // disable proxy in case of uri math to noProxy option - if (self.hasOwnProperty('noProxy') && (self.noProxy === '*' || uriInNoProxy(self.uri, self.noProxy))) { - self.proxy = null - } - } else { - self.proxy = getProxyFromURI(self.uri, self.noProxy) + if (!self.hasOwnProperty('proxy')) { + self.proxy = getProxyFromURI(self.uri) + } else if ((self.noProxy === '*' || uriInNoProxy(self.uri, self.noProxy))) { + // noProxy option only operate over the proxy option, not over env vars + self.proxy = null } self.tunnel = self._tunnel.isEnabled()