@@ -1912,7 +1912,8 @@ def proxy_bypass_environment(host, proxies=None):
19121912 """Test if proxies should not be used for a particular host.
19131913
19141914 Checks the proxy dict for the value of no_proxy, which should
1915- be a list of comma separated DNS suffixes, or '*' for all hosts.
1915+ be a list of comma separated DNS suffixes, IP address CIDR ranges,
1916+ or '*' for all hosts.
19161917
19171918 """
19181919 if proxies is None :
@@ -1928,14 +1929,40 @@ def proxy_bypass_environment(host, proxies=None):
19281929 host = host .lower ()
19291930 # strip port off host
19301931 hostonly , port = _splitport (host )
1931- # check if the host ends with any of the DNS suffixes
1932+ host_ip = None
1933+ checked_host_ip = False
1934+ # for every entry in no_proxy...
19321935 for name in no_proxy .split (',' ):
19331936 name = name .strip ()
19341937 if name :
19351938 name = name .lstrip ('.' ) # ignore leading dots
19361939 name = name .lower ()
1940+
1941+ # check for exact match
19371942 if hostonly == name or host == name :
19381943 return True
1944+
1945+ # check if the IP is within CIDR range
1946+ if '/' in name :
1947+ if not checked_host_ip :
1948+ from ipaddress import ip_address
1949+ for candidate in (hostonly , host ):
1950+ candidate = candidate .strip ('[]' )
1951+ try :
1952+ host_ip = ip_address (candidate )
1953+ break
1954+ except ValueError :
1955+ pass
1956+ checked_host_ip = True
1957+ if host_ip is not None :
1958+ from ipaddress import ip_network
1959+ try :
1960+ if host_ip in ip_network (name , strict = False ):
1961+ return True
1962+ except ValueError :
1963+ pass
1964+
1965+ # check if the host ends with any of the DNS suffixes
19391966 name = '.' + name
19401967 if hostonly .endswith (name ) or host .endswith (name ):
19411968 return True
0 commit comments