Skip to content

Commit fc84d50

Browse files
bpo-39057: Fix urllib.request.proxy_bypass_environment(). (GH-17619)
Ignore leading dots and no longer ignore a trailing newline. (cherry picked from commit 6a265f0) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent 8595255 commit fc84d50

4 files changed

Lines changed: 39 additions & 13 deletions

File tree

Lib/test/test_urllib.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,36 @@ def test_proxy_bypass_environment_host_match(self):
261261
self.assertTrue(bypass('localhost'))
262262
self.assertTrue(bypass('LocalHost')) # MixedCase
263263
self.assertTrue(bypass('LOCALHOST')) # UPPERCASE
264+
self.assertTrue(bypass('.localhost'))
264265
self.assertTrue(bypass('newdomain.com:1234'))
266+
self.assertTrue(bypass('.newdomain.com:1234'))
265267
self.assertTrue(bypass('foo.d.o.t')) # issue 29142
268+
self.assertTrue(bypass('d.o.t'))
266269
self.assertTrue(bypass('anotherdomain.com:8888'))
270+
self.assertTrue(bypass('.anotherdomain.com:8888'))
267271
self.assertTrue(bypass('www.newdomain.com:1234'))
268272
self.assertFalse(bypass('prelocalhost'))
269273
self.assertFalse(bypass('newdomain.com')) # no port
270274
self.assertFalse(bypass('newdomain.com:1235')) # wrong port
271275

276+
def test_proxy_bypass_environment_always_match(self):
277+
bypass = urllib.request.proxy_bypass_environment
278+
self.env.set('NO_PROXY', '*')
279+
self.assertTrue(bypass('newdomain.com'))
280+
self.assertTrue(bypass('newdomain.com:1234'))
281+
self.env.set('NO_PROXY', '*, anotherdomain.com')
282+
self.assertTrue(bypass('anotherdomain.com'))
283+
self.assertFalse(bypass('newdomain.com'))
284+
self.assertFalse(bypass('newdomain.com:1234'))
285+
286+
def test_proxy_bypass_environment_newline(self):
287+
bypass = urllib.request.proxy_bypass_environment
288+
self.env.set('NO_PROXY',
289+
'localhost, anotherdomain.com, newdomain.com:1234')
290+
self.assertFalse(bypass('localhost\n'))
291+
self.assertFalse(bypass('anotherdomain.com:8888\n'))
292+
self.assertFalse(bypass('newdomain.com:1234\n'))
293+
272294

273295
class ProxyTests_withOrderedEnv(unittest.TestCase):
274296

Lib/urllib/parse.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,9 +1054,9 @@ def _splitport(host):
10541054
"""splitport('host:port') --> 'host', 'port'."""
10551055
global _portprog
10561056
if _portprog is None:
1057-
_portprog = re.compile('(.*):([0-9]*)$', re.DOTALL)
1057+
_portprog = re.compile('(.*):([0-9]*)', re.DOTALL)
10581058

1059-
match = _portprog.match(host)
1059+
match = _portprog.fullmatch(host)
10601060
if match:
10611061
host, port = match.groups()
10621062
if port:

Lib/urllib/request.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2500,24 +2500,26 @@ def proxy_bypass_environment(host, proxies=None):
25002500
try:
25012501
no_proxy = proxies['no']
25022502
except KeyError:
2503-
return 0
2503+
return False
25042504
# '*' is special case for always bypass
25052505
if no_proxy == '*':
2506-
return 1
2506+
return True
2507+
host = host.lower()
25072508
# strip port off host
25082509
hostonly, port = _splitport(host)
25092510
# check if the host ends with any of the DNS suffixes
2510-
no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')]
2511-
for name in no_proxy_list:
2511+
for name in no_proxy.split(','):
2512+
name = name.strip()
25122513
if name:
25132514
name = name.lstrip('.') # ignore leading dots
2514-
name = re.escape(name)
2515-
pattern = r'(.+\.)?%s$' % name
2516-
if (re.match(pattern, hostonly, re.I)
2517-
or re.match(pattern, host, re.I)):
2518-
return 1
2515+
name = name.lower()
2516+
if hostonly == name or host == name:
2517+
return True
2518+
name = '.' + name
2519+
if hostonly.endswith(name) or host.endswith(name):
2520+
return True
25192521
# otherwise, don't bypass
2520-
return 0
2522+
return False
25212523

25222524

25232525
# This code tests an OSX specific data structure but is testable on all
@@ -2643,7 +2645,7 @@ def getproxies_registry():
26432645
for p in proxyServer.split(';'):
26442646
protocol, address = p.split('=', 1)
26452647
# See if address has a type:// prefix
2646-
if not re.match('^([^/:]+)://', address):
2648+
if not re.match('(?:[^/:]+)://', address):
26472649
address = '%s://%s' % (protocol, address)
26482650
proxies[protocol] = address
26492651
else:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:func:`urllib.request.proxy_bypass_environment` now ignores leading dots and
2+
no longer ignores a trailing newline.

0 commit comments

Comments
 (0)