libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject [3/3] git commit: Update HTTP proxy code so it supports basic auth authentication.
Date Wed, 20 Aug 2014 16:20:59 GMT
Update HTTP proxy code so it supports basic auth authentication.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/a03e9f31
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/a03e9f31
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/a03e9f31

Branch: refs/heads/trunk
Commit: a03e9f31d3f3a11a6fb6c0a3bdd81a40dd4c9169
Parents: 5544e75
Author: Tomaz Muraus <tomaz@apache.org>
Authored: Wed Aug 20 17:45:29 2014 +0200
Committer: Tomaz Muraus <tomaz@apache.org>
Committed: Wed Aug 20 18:18:22 2014 +0200

----------------------------------------------------------------------
 .../examples/http_proxy/constructor_argument.py |  5 +-
 .../http_proxy/set_http_proxy_method.py         |  6 +--
 docs/other/using-http-proxy.rst                 | 10 +++-
 libcloud/httplib_ssl.py                         | 49 ++++++++++++++++++--
 libcloud/test/test_connection.py                | 10 ++++
 5 files changed, 70 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/a03e9f31/docs/examples/http_proxy/constructor_argument.py
----------------------------------------------------------------------
diff --git a/docs/examples/http_proxy/constructor_argument.py b/docs/examples/http_proxy/constructor_argument.py
index ae54945..3542beb 100644
--- a/docs/examples/http_proxy/constructor_argument.py
+++ b/docs/examples/http_proxy/constructor_argument.py
@@ -1,6 +1,7 @@
 from libcloud.compute.drivers.dreamhost import DreamhostConnection
 
-PROXY_URL = 'http://<proxy hostname>:<proxy port>'
+PROXY_URL_NO_AUTH = 'http://<proxy hostname>:<proxy port>'
+PROXY_URL_BASIC_AUTH = 'http://<user>:<pass>@<proxy hostname>:<proxy
port>'
 
 conn = DreamhostConnection(host='dreamhost.com', port=443,
-                           timeout=None, proxy_url=PROXY_URL)
+                           timeout=None, proxy_url=PROXY_URL_NO_AUTH)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/a03e9f31/docs/examples/http_proxy/set_http_proxy_method.py
----------------------------------------------------------------------
diff --git a/docs/examples/http_proxy/set_http_proxy_method.py b/docs/examples/http_proxy/set_http_proxy_method.py
index cb9b84a..b9d5bdf 100644
--- a/docs/examples/http_proxy/set_http_proxy_method.py
+++ b/docs/examples/http_proxy/set_http_proxy_method.py
@@ -3,10 +3,10 @@ from pprint import pprint
 from libcloud.compute.types import Provider
 from libcloud.compute.providers import get_driver
 
-PROXY_URL = 'http://<proxy hostname>:<proxy port>'
+PROXY_URL_NO_AUTH = 'http://<proxy hostname>:<proxy port>'
+PROXY_URL_BASIC_AUTH = 'http://<user>:<pass>@<proxy hostname>:<proxy
port>'
 
 cls = get_driver(Provider.RACKSPACE)
 driver = cls('username', 'api key', region='ord')
-driver.connection.set_http_proxy(proxy_url=PROXY_URL)
-
+driver.connection.set_http_proxy(proxy_url=PROXY_URL_NO_AUTH)
 pprint(driver.list_nodes())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/a03e9f31/docs/other/using-http-proxy.rst
----------------------------------------------------------------------
diff --git a/docs/other/using-http-proxy.rst b/docs/other/using-http-proxy.rst
index 8c12dc5..4231bea 100644
--- a/docs/other/using-http-proxy.rst
+++ b/docs/other/using-http-proxy.rst
@@ -23,8 +23,8 @@ bellow:
 Known limitations
 -----------------
 
-* HTTP proxies which require authentication are not supported
 * Python 2.6 is not supported
+* Only HTTP basic authentication proxy authorization method is supported
 
 Examples
 --------
@@ -35,10 +35,18 @@ with Libcloud.
 1. Using http_proxy environment variable
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+Without authentication:
+
 .. sourcecode:: python
 
     http_proxy=http://<proxy hostname>:<proxy port> python my_script.py
 
+With basic auth authentication:
+
+.. sourcecode:: python
+
+    http_proxy=http://<username>:<password>@<proxy hostname>:<proxy
port> python my_script.py
+
 2. Passing http_proxy argument to the connection class
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

http://git-wip-us.apache.org/repos/asf/libcloud/blob/a03e9f31/libcloud/httplib_ssl.py
----------------------------------------------------------------------
diff --git a/libcloud/httplib_ssl.py b/libcloud/httplib_ssl.py
index 3783f48..d74ad40 100644
--- a/libcloud/httplib_ssl.py
+++ b/libcloud/httplib_ssl.py
@@ -21,11 +21,14 @@ import re
 import socket
 import sys
 import ssl
+import base64
 import warnings
 
 import libcloud.security
+from libcloud.utils.py3 import b
 from libcloud.utils.py3 import httplib
 from libcloud.utils.py3 import urlparse
+from libcloud.utils.py3 import urlunquote
 
 __all__ = [
     'LibcloudBaseConnection',
@@ -46,23 +49,37 @@ class LibcloudBaseConnection(object):
     proxy_scheme = None
     proxy_host = None
     proxy_port = None
+
+    proxy_username = None
+    proxy_password = None
+
     http_proxy_used = False
 
     def set_http_proxy(self, proxy_url):
         """
         Set a HTTP proxy which will be used with this connection.
 
-        :param proxy_url: Proxy URL (e.g. http://hostname:3128)
+        :param proxy_url: Proxy URL (e.g. http://<hostname>:<port> without
+                          authentication and
+                          http://<username>:<password>@<hostname>:<port>
for
+                          basic auth authentication information.
         :type proxy_url: ``str``
         """
         if sys.version_info[:2] == (2, 6):
             raise Exception('HTTP proxy support requires Python 2.7 or higher')
 
-        scheme, host, port = self._parse_proxy_url(proxy_url=proxy_url)
+        result = self._parse_proxy_url(proxy_url=proxy_url)
+        scheme = result[0]
+        host = result[1]
+        port = result[2]
+        username = result[3]
+        password = result[4]
 
         self.proxy_scheme = scheme
         self.proxy_host = host
         self.proxy_port = port
+        self.proxy_username = username
+        self.proxy_password = password
         self.http_proxy_used = True
 
         self._setup_http_proxy()
@@ -88,7 +105,22 @@ class LibcloudBaseConnection(object):
         proxy_scheme = parsed.scheme
         proxy_host, proxy_port = parsed.hostname, parsed.port
 
-        return (proxy_scheme, proxy_host, proxy_port)
+        netloc = parsed.netloc
+
+        if '@' in netloc:
+            username_password = netloc.split('@', 1)[0]
+            split = username_password.split(':', 1)
+
+            if len(split) == 0:
+                raise ValueError('URL is in an invalid format')
+
+            proxy_username, proxy_password = split[0], split[1]
+        else:
+            proxy_username = None
+            proxy_password = None
+
+        return (proxy_scheme, proxy_host, proxy_port, proxy_username,
+                proxy_password)
 
     def _setup_http_proxy(self):
         """
@@ -97,7 +129,16 @@ class LibcloudBaseConnection(object):
         :param proxy_url: Proxy URL (e.g. http://<host>:3128)
         :type proxy_url: ``str``
         """
-        self.set_tunnel(host=self.host, port=self.port)
+        headers = {}
+
+        if self.proxy_username and self.proxy_password:
+            # Include authentication header
+            user_pass = '%s:%s' % (self.proxy_username, self.proxy_password)
+            encoded = base64.encodestring(b(urlunquote(user_pass))).strip()
+            auth_header = 'Basic %s' % (encoded.decode('utf-8'))
+            headers['Proxy-Authorization'] = auth_header
+
+        self.set_tunnel(host=self.host, port=self.port, headers=headers)
         self._set_hostport(host=self.proxy_host, port=self.proxy_port)
 
     def _activate_http_proxy(self, sock):

http://git-wip-us.apache.org/repos/asf/libcloud/blob/a03e9f31/libcloud/test/test_connection.py
----------------------------------------------------------------------
diff --git a/libcloud/test/test_connection.py b/libcloud/test/test_connection.py
index 75d63fd..aabbd1d 100644
--- a/libcloud/test/test_connection.py
+++ b/libcloud/test/test_connection.py
@@ -40,6 +40,16 @@ class BaseConnectionClassTestCase(unittest.TestCase):
         self.assertEqual(result[0], 'http')
         self.assertEqual(result[1], '127.0.0.1')
         self.assertEqual(result[2], 3128)
+        self.assertEqual(result[3], None)
+        self.assertEqual(result[4], None)
+
+        proxy_url = 'http://user1:pass1@127.0.0.1:3128'
+        result = conn._parse_proxy_url(proxy_url=proxy_url)
+        self.assertEqual(result[0], 'http')
+        self.assertEqual(result[1], '127.0.0.1')
+        self.assertEqual(result[2], 3128)
+        self.assertEqual(result[3], 'user1')
+        self.assertEqual(result[4], 'pass1')
 
         proxy_url = 'https://127.0.0.1:3128'
         expected_msg = 'Only http proxies are supported'


Mime
View raw message