Skip to content

Commit 880a17a

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 9c145e1 commit 880a17a

File tree

4 files changed

+39
-13
lines changed

4 files changed

+39
-13
lines changed

Lib/test/test_urllib.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,36 @@ def test_proxy_bypass_environment_host_match(self):
253253
self.assertTrue(bypass('localhost'))
254254
self.assertTrue(bypass('LocalHost')) # MixedCase
255255
self.assertTrue(bypass('LOCALHOST')) # UPPERCASE
256+
self.assertTrue(bypass('.localhost'))
256257
self.assertTrue(bypass('newdomain.com:1234'))
258+
self.assertTrue(bypass('.newdomain.com:1234'))
257259
self.assertTrue(bypass('foo.d.o.t')) # issue 29142
260+
self.assertTrue(bypass('d.o.t'))
258261
self.assertTrue(bypass('anotherdomain.com:8888'))
262+
self.assertTrue(bypass('.anotherdomain.com:8888'))
259263
self.assertTrue(bypass('www.newdomain.com:1234'))
260264
self.assertFalse(bypass('prelocalhost'))
261265
self.assertFalse(bypass('newdomain.com')) # no port
262266
self.assertFalse(bypass('newdomain.com:1235')) # wrong port
263267

268+
def test_proxy_bypass_environment_always_match(self):
269+
bypass = urllib.request.proxy_bypass_environment
270+
self.env.set('NO_PROXY', '*')
271+
self.assertTrue(bypass('newdomain.com'))
272+
self.assertTrue(bypass('newdomain.com:1234'))
273+
self.env.set('NO_PROXY', '*, anotherdomain.com')
274+
self.assertTrue(bypass('anotherdomain.com'))
275+
self.assertFalse(bypass('newdomain.com'))
276+
self.assertFalse(bypass('newdomain.com:1234'))
277+
278+
def test_proxy_bypass_environment_newline(self):
279+
bypass = urllib.request.proxy_bypass_environment
280+
self.env.set('NO_PROXY',
281+
'localhost, anotherdomain.com, newdomain.com:1234')
282+
self.assertFalse(bypass('localhost\n'))
283+
self.assertFalse(bypass('anotherdomain.com:8888\n'))
284+
self.assertFalse(bypass('newdomain.com:1234\n'))
285+
264286

265287
class ProxyTests_withOrderedEnv(unittest.TestCase):
266288

Lib/urllib/parse.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -997,9 +997,9 @@ def splitport(host):
997997
"""splitport('host:port') --> 'host', 'port'."""
998998
global _portprog
999999
if _portprog is None:
1000-
_portprog = re.compile('(.*):([0-9]*)$', re.DOTALL)
1000+
_portprog = re.compile('(.*):([0-9]*)', re.DOTALL)
10011001

1002-
match = _portprog.match(host)
1002+
match = _portprog.fullmatch(host)
10031003
if match:
10041004
host, port = match.groups()
10051005
if port:

Lib/urllib/request.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2499,24 +2499,26 @@ def proxy_bypass_environment(host, proxies=None):
24992499
try:
25002500
no_proxy = proxies['no']
25012501
except KeyError:
2502-
return 0
2502+
return False
25032503
# '*' is special case for always bypass
25042504
if no_proxy == '*':
2505-
return 1
2505+
return True
2506+
host = host.lower()
25062507
# strip port off host
25072508
hostonly, port = splitport(host)
25082509
# check if the host ends with any of the DNS suffixes
2509-
no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')]
2510-
for name in no_proxy_list:
2510+
for name in no_proxy.split(','):
2511+
name = name.strip()
25112512
if name:
25122513
name = name.lstrip('.') # ignore leading dots
2513-
name = re.escape(name)
2514-
pattern = r'(.+\.)?%s$' % name
2515-
if (re.match(pattern, hostonly, re.I)
2516-
or re.match(pattern, host, re.I)):
2517-
return 1
2514+
name = name.lower()
2515+
if hostonly == name or host == name:
2516+
return True
2517+
name = '.' + name
2518+
if hostonly.endswith(name) or host.endswith(name):
2519+
return True
25182520
# otherwise, don't bypass
2519-
return 0
2521+
return False
25202522

25212523

25222524
# This code tests an OSX specific data structure but is testable on all
@@ -2642,7 +2644,7 @@ def getproxies_registry():
26422644
for p in proxyServer.split(';'):
26432645
protocol, address = p.split('=', 1)
26442646
# See if address has a type:// prefix
2645-
if not re.match('^([^/:]+)://', address):
2647+
if not re.match('(?:[^/:]+)://', address):
26462648
address = '%s://%s' % (protocol, address)
26472649
proxies[protocol] = address
26482650
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)