From 74b1d4a85cbf10e84b364bc17927f5420ae5d187 Mon Sep 17 00:00:00 2001 From: Joe Gregorio Date: Thu, 25 Oct 2012 14:05:49 -0400 Subject: Adding proxy_info_from_* methods to Python3. Reviewed in https://codereview.appspot.com/6588078/. --- python3/httplib2/__init__.py | 57 +++++++++++++++++++++++++++++++++++++++++--- python3/httplib2test.py | 44 +++++++++++++++++++++++++++++++++- 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() -- cgit v1.2.1