Added possibility to use IP ranges (ex. 192.168.1.0/24) to no_proxy environment variable
authorKamil Madac <kamil.madac@gmail.com>
Mon, 2 Dec 2013 21:32:29 +0000 (22:32 +0100)
committerKamil Madac <kamil.madac@gmail.com>
Mon, 2 Dec 2013 21:32:29 +0000 (22:32 +0100)
requests/utils.py
test_requests.py

index 4283560..f92eed6 100644 (file)
@@ -17,6 +17,7 @@ import os
 import platform
 import re
 import sys
+import netaddr
 
 from . import __version__
 from . import certs
@@ -420,11 +421,27 @@ def get_environ_proxies(url):
         # the end of the netloc, both with and without the port.
         no_proxy = no_proxy.replace(' ', '').split(',')
 
-        for host in no_proxy:
-            if netloc.endswith(host) or netloc.split(':')[0].endswith(host):
-                # The URL does match something in no_proxy, so we don't want
-                # to apply the proxies on this URL.
-                return {}
+        ip = None
+        try:
+            ip = netaddr.IPAddress(netloc.split(':')[0])
+        except netaddr.AddrFormatError:
+            pass
+
+        if ip:
+            for proxy_ip in no_proxy:
+                proxy_ipaddress = None
+                try:
+                    proxy_ipaddress = netaddr.IPNetwork(proxy_ip)
+                except (netaddr.AddrFormatError, ValueError):
+                    continue
+                if proxy_ipaddress and ip in proxy_ipaddress:
+                    return {}
+        else:
+            for host in no_proxy:
+                if netloc.endswith(host) or netloc.split(':')[0].endswith(host):
+                    # The URL does match something in no_proxy, so we don't want
+                    # to apply the proxies on this URL.
+                    return {}
 
     # If the system proxy settings indicate that this URL should be bypassed,
     # don't proxy.
index 3b67395..cb91ade 100755 (executable)
@@ -910,5 +910,14 @@ class UtilsTestCase(unittest.TestCase):
         else:
             assert super_len(cStringIO.StringIO('but some how, some way...')) == 25
 
+    def test_get_environ_proxies_ip_ranges(self):
+        """ Ensures that IP addresses are correctly matches with ranges in no_proxy variable """
+        from requests.utils import get_environ_proxies
+        os.environ['no_proxy'] = "127.0.0.1,localhost.localdomain,192.168.0.0/24,172.16.1.1"
+        assert get_environ_proxies('http://192.168.0.1:5000/') == {}
+        assert get_environ_proxies('http://192.168.0.1/') == {}
+        assert get_environ_proxies('http://172.16.1.1/') == {}
+        assert get_environ_proxies('http://192.168.1.1:5000/') == {'no': os.environ['no_proxy']}
+
 if __name__ == '__main__':
     unittest.main()