summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Gregorio <jcgregorio@google.com>2012-10-25 14:05:49 -0400
committerJoe Gregorio <jcgregorio@google.com>2012-10-25 14:05:49 -0400
commit74b1d4a85cbf10e84b364bc17927f5420ae5d187 (patch)
treeb2c5ca22399423c4469dc722885bc58dec1d9013
parent53f169c2a4bbd00256d956f2a5b163caccd58f7c (diff)
downloadhttplib2-74b1d4a85cbf10e84b364bc17927f5420ae5d187.tar.gz
Adding proxy_info_from_* methods to Python3.
Reviewed in https://codereview.appspot.com/6588078/.
-rw-r--r--python3/httplib2/__init__.py57
-rwxr-xr-xpython3/httplib2test.py44
2 files changed, 97 insertions, 4 deletions
diff --git a/python3/httplib2/__init__.py b/python3/httplib2/__init__.py
index de2cbd6..fe5eb38 100644
--- a/python3/httplib2/__init__.py
+++ b/python3/httplib2/__init__.py
@@ -732,6 +732,56 @@ p = ProxyInfo(proxy_type=socks.PROXY_TYPE_HTTP, proxy_host='localhost', proxy_po
return socks and (self.proxy_host != None) and (self.proxy_port != None)
+def proxy_info_from_environment(method='http'):
+ """
+ Read proxy info from the environment variables.
+ """
+ if method not in ('http', 'https'):
+ return
+
+ env_var = method + '_proxy'
+ url = os.environ.get(env_var, os.environ.get(env_var.upper()))
+ if not url:
+ return
+ return proxy_info_from_url(url, method)
+
+
+def proxy_info_from_url(url, method='http'):
+ """
+ Construct a ProxyInfo from a URL (such as http_proxy env var)
+ """
+ url = urllib.parse.urlparse(url)
+ username = None
+ password = None
+ port = None
+ if '@' in url[1]:
+ ident, host_port = url[1].split('@', 1)
+ if ':' in ident:
+ username, password = ident.split(':', 1)
+ else:
+ password = ident
+ else:
+ host_port = url[1]
+ if ':' in host_port:
+ host, port = host_port.split(':', 1)
+ else:
+ host = host_port
+
+ if port:
+ port = int(port)
+ else:
+ port = dict(https=443, http=80)[method]
+
+ proxy_type = 3 # socks.PROXY_TYPE_HTTP
+ return ProxyInfo(
+ proxy_type = proxy_type,
+ proxy_host = host,
+ proxy_port = port,
+ proxy_user = username or None,
+ proxy_pass = password or None,
+ )
+
+
class HTTPConnectionWithTimeout(http.client.HTTPConnection):
"""HTTPConnection subclass that supports timeouts
@@ -798,8 +848,9 @@ class Http(object):
and more.
"""
- def __init__(self, cache=None, timeout=None, proxy_info=None,
- ca_certs=None, disable_ssl_certificate_validation=False):
+ def __init__(self, cache=None, timeout=None,
+ proxy_info=proxy_info_from_environment,
+ ca_certs=None, disable_ssl_certificate_validation=False):
"""If 'cache' is a string then it is used as a directory name for
a disk cache. Otherwise it must be an object that supports the
same interface as FileCache.
@@ -812,7 +863,7 @@ and more.
`proxy_info` may be:
- a callable that takes the http scheme ('http' or 'https') and
returns a ProxyInfo instance per request. By default, uses
- ProxyInfo.from_environment.
+ proxy_info_from_environment.
- a ProxyInfo instance (static proxy config).
- None (proxy disabled).
diff --git a/python3/httplib2test.py b/python3/httplib2test.py
index a3e29b2..1a92726 100755
--- a/python3/httplib2test.py
+++ b/python3/httplib2test.py
@@ -1535,4 +1535,46 @@ class HttpPrivateTest(unittest.TestCase):
end2end = httplib2._get_end2end_headers(response)
self.assertEqual(0, len(end2end))
-unittest.main()
+
+class TestProxyInfo(unittest.TestCase):
+ def setUp(self):
+ self.orig_env = dict(os.environ)
+
+ def tearDown(self):
+ os.environ.clear()
+ os.environ.update(self.orig_env)
+
+ def test_from_url(self):
+ pi = httplib2.proxy_info_from_url('http://myproxy.example.com')
+ self.assertEqual(pi.proxy_host, 'myproxy.example.com')
+ self.assertEqual(pi.proxy_port, 80)
+ self.assertEqual(pi.proxy_user, None)
+
+ def test_from_url_ident(self):
+ pi = httplib2.proxy_info_from_url('http://zoidberg:fish@someproxy:99')
+ self.assertEqual(pi.proxy_host, 'someproxy')
+ self.assertEqual(pi.proxy_port, 99)
+ self.assertEqual(pi.proxy_user, 'zoidberg')
+ self.assertEqual(pi.proxy_pass, 'fish')
+
+ def test_from_env(self):
+ os.environ['http_proxy'] = 'http://myproxy.example.com:8080'
+ pi = httplib2.proxy_info_from_environment()
+ self.assertEqual(pi.proxy_host, 'myproxy.example.com')
+ self.assertEqual(pi.proxy_port, 8080)
+
+ def test_from_env_no_proxy(self):
+ os.environ['http_proxy'] = 'http://myproxy.example.com:80'
+ os.environ['https_proxy'] = 'http://myproxy.example.com:81'
+ pi = httplib2.proxy_info_from_environment('https')
+ self.assertEqual(pi.proxy_host, 'myproxy.example.com')
+ self.assertEqual(pi.proxy_port, 81)
+
+ def test_from_env_none(self):
+ os.environ.clear()
+ pi = httplib2.proxy_info_from_environment()
+ self.assertEqual(pi, None)
+
+
+if __name__ == '__main__':
+ unittest.main()