Skip to content

Commit a8e662c

Browse files
author
Avishagp
committed
fix: no_proxy issue
1 parent e5dee92 commit a8e662c

File tree

2 files changed

+120
-12
lines changed

2 files changed

+120
-12
lines changed

lib/needle.js

+28-10
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,34 @@ function host_and_ports_match(url1, url2) {
191191
}
192192

193193
// returns false if a no_proxy host matches given url
194-
function should_proxy_to(url) {
195-
var no_proxy = get_env_var(['NO_PROXY'], true);
196-
if (!no_proxy) return true;
197-
198-
var host, hosts = no_proxy.split(',');
199-
for (var i in hosts) {
200-
host = hosts[i];
201-
if (host_and_ports_match(host, url)) {
202-
return false;
194+
function should_proxy_to(uri) {
195+
const noProxy = get_env_var(["NO_PROXY"], true);
196+
if (!noProxy) {
197+
return true;
198+
}
199+
200+
let urlMatchedNoProxyPattern = false
201+
const requestUrl = new URL(uri);
202+
const patternList = noProxy.split(/[\s,]+/);
203+
204+
// iterate over all NO_PROXY patterns and determine whether the given URL matches any of them
205+
for (const pattern of patternList) {
206+
if(pattern.trim().length == 0) {
207+
continue
208+
}
209+
210+
// replace leading dot by asterisk, escape dots and finally replace asterisk by .*
211+
const preparedPattern = pattern.replace(/^\./, "*").replace(/[.]/g, '\\$&').replace(/\*/g, '.*')
212+
const regex = new RegExp(preparedPattern)
213+
const matches = (uri.match(regex)?.length > 0);
214+
if (matches) {
215+
// hostname + port of the request URL match a given NO_PROXY pattern
216+
urlMatchedNoProxyPattern = true
217+
break;
203218
}
204219
}
205220

206-
return true;
221+
return !urlMatchedNoProxyPattern;
207222
}
208223

209224
function pump_streams(streams, cb) {
@@ -914,3 +929,6 @@ module.exports.defaults = function(obj) {
914929
module.exports.request = function(method, uri, data, opts, callback) {
915930
return new Needle(method, uri, data, opts, callback).start();
916931
};
932+
933+
// Exporting for testing
934+
module.exports.should_proxy_to = should_proxy_to;

test/proxy_spec.js

+92-2
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ describe('proxy option', function() {
137137
}))
138138
})
139139

140-
it('proxies request if matching host in list but different port', function(done) {
140+
it('does not proxy request if matching host in list and just has a different port', function(done) {
141141
process.env.NO_PROXY = 'localhost';
142-
send_request({ proxy: nonexisting_host + ':123/done' }, proxied(nonexisting_host, '123', function() {
142+
send_request({ proxy: nonexisting_host + ':123/done' }, not_proxied(function() {
143143
delete process.env.NO_PROXY;
144144
done();
145145
}))
@@ -152,6 +152,96 @@ describe('proxy option', function() {
152152
done();
153153
}))
154154
})
155+
156+
describe('should_proxy_to()', function() {
157+
158+
const noProxy = ".ic1.mycorp,localhost,127.0.0.1,*.mycorp.org";
159+
const noProxyWithPorts = " ,.mycorp.org:1234,.ic1.mycorp,localhost,127.0.0.1";
160+
const URI = "http://registry.random.opr.mycorp.org";
161+
const URIWithPort = "http://registry.random.opr.mycorp.org:9874";
162+
const URIWithPort1234 = "http://registry.random.opr.mycorp.org:1234";
163+
const URIlocalhost = "http://localhost";
164+
const URIip = "http://127.0.0.1";
165+
166+
it("shall return true if NO_PROXY is undefined", function(done) {
167+
process.env.NO_PROXY = undefined;
168+
needle.should_proxy_to(URI).should.true()
169+
delete process.env.NO_PROXY;
170+
done();
171+
});
172+
173+
it("shall return true if NO_PROXY is empty", function(done) {
174+
process.env.NO_PROXY = "";
175+
needle.should_proxy_to(URI).should.true()
176+
delete process.env.NO_PROXY;
177+
done();
178+
});
179+
180+
it("shall return true if the host matches and the ports don't (URI doesn't have port specified)", function(done) {
181+
process.env.NO_PROXY = noProxyWithPorts;
182+
needle.should_proxy_to(URI).should.true()
183+
delete process.env.NO_PROXY;
184+
done();
185+
});
186+
187+
it("shall return true if the host matches and the ports don't (both have a port specified but just different values)", function(done) {
188+
process.env.NO_PROXY = noProxyWithPorts;
189+
needle.should_proxy_to(URIWithPort).should.true()
190+
delete process.env.NO_PROXY;
191+
done();
192+
});
193+
194+
it("shall return false if the host matches and the ports don't (no_proxy pattern doesn't have a port)", function(done) {
195+
process.env.NO_PROXY = noProxy;
196+
needle.should_proxy_to(URIWithPort).should.false()
197+
delete process.env.NO_PROXY;
198+
done();
199+
});
200+
201+
it("shall return false if host matches", function(done) {
202+
process.env.NO_PROXY = noProxy;
203+
needle.should_proxy_to(URI).should.false()
204+
delete process.env.NO_PROXY;
205+
done();
206+
});
207+
208+
it("shall return false if the host and port matches", function(done) {
209+
process.env.NO_PROXY = noProxyWithPorts;
210+
needle.should_proxy_to(URIWithPort1234).should.false()
211+
delete process.env.NO_PROXY;
212+
done();
213+
});
214+
215+
it("shall return false if the host matches (localhost)", function(done) {
216+
process.env.NO_PROXY = noProxy;
217+
needle.should_proxy_to(URIlocalhost).should.false()
218+
delete process.env.NO_PROXY;
219+
done();
220+
});
221+
222+
it("shall return false if the host matches (ip)", function(done) {
223+
process.env.NO_PROXY = noProxy;
224+
needle.should_proxy_to(URIip).should.false()
225+
delete process.env.NO_PROXY;
226+
done();
227+
});
228+
229+
it("shall return false if the host matches (ip)", function(done) {
230+
process.env.NO_PROXY = noProxy.replace(/,g/, " ");
231+
needle.should_proxy_to(URIip).should.false()
232+
delete process.env.NO_PROXY;
233+
done();
234+
});
235+
236+
it("shall return false if the host matches (ip)", function(done) {
237+
process.env.NO_PROXY = noProxy.replace(/,g/, " ");
238+
needle.should_proxy_to(URIip).should.false()
239+
delete process.env.NO_PROXY;
240+
done();
241+
});
242+
243+
})
244+
155245
})
156246

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

0 commit comments

Comments
 (0)