Add Proxy-Auth header when proxies have credentials.
authorCory Benfield <lukasaoz@gmail.com>
Wed, 6 Feb 2013 18:24:23 +0000 (18:24 +0000)
committerCory Benfield <lukasaoz@gmail.com>
Wed, 6 Feb 2013 18:40:35 +0000 (18:40 +0000)
requests/adapters.py
requests/utils.py
test_requests.py

index c350ae4..4b58f45 100644 (file)
@@ -15,7 +15,7 @@ from .packages.urllib3.poolmanager import PoolManager, ProxyManager
 from .packages.urllib3.response import HTTPResponse
 from .compat import urlparse, basestring, urldefrag
 from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers,
-                    prepend_scheme_if_needed)
+                    prepend_scheme_if_needed, get_auth_from_url)
 from .structures import CaseInsensitiveDict
 from .packages.urllib3.exceptions import MaxRetryError
 from .packages.urllib3.exceptions import TimeoutError
@@ -23,6 +23,7 @@ from .packages.urllib3.exceptions import SSLError as _SSLError
 from .packages.urllib3.exceptions import HTTPError as _HTTPError
 from .cookies import extract_cookies_to_jar
 from .exceptions import ConnectionError, Timeout, SSLError
+from .auth import _basic_auth_str
 
 DEFAULT_POOLSIZE = 10
 DEFAULT_RETRIES = 0
@@ -146,6 +147,21 @@ class HTTPAdapter(BaseAdapter):
 
         return url
 
+    def add_headers(self, request, **kwargs):
+        """Add any headers needed by the connection. Currently this only adds a
+        Host: header if a proxy is being used."""
+        proxies = kwargs.get('proxies', {})
+
+        if proxies is None:
+            proxies = {}
+
+        proxy = proxies.get(urlparse(request.url).scheme)
+        username, password = get_auth_from_url(proxy)
+
+        if username and password:
+            request.headers['Proxy-Authorization'] = _basic_auth_str(username,
+                                                                     password)
+
     def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
         """Sends PreparedRequest object. Returns Response object."""
 
@@ -153,6 +169,7 @@ class HTTPAdapter(BaseAdapter):
 
         self.cert_verify(conn, request.url, verify, cert)
         url = self.request_url(request, proxies)
+        self.add_headers(request, proxies=proxies)
 
         chunked = not (request.body is None or 'Content-Length' in request.headers)
 
index 91bb3e8..bb07f83 100644 (file)
@@ -580,3 +580,13 @@ def prepend_scheme_if_needed(url, new_scheme):
         netloc, path = path, netloc
 
     return urlunparse((scheme, netloc, path, params, query, fragment))
+
+
+def get_auth_from_url(url):
+    """Given a url with authentication components, extract them into a tuple of
+    username,password."""
+    if url:
+        parsed = urlparse(url)
+        return (parsed.username, parsed.password)
+    else:
+        return ('', '')
index 72c6eb7..4ba9a43 100644 (file)
@@ -336,5 +336,10 @@ class RequestsTestCase(unittest.TestCase):
         self.assertTrue(next(iter(r)))
         io.close()
 
+    def test_get_auth_from_url(self):
+        url = 'http://user:pass@complex.url.com/path?query=yes'
+        self.assertEqual(('user', 'pass'),
+                         requests.utils.get_auth_from_url(url))
+
 if __name__ == '__main__':
     unittest.main()