From 814e0520ad61387e89b22806d20544adf6ce8ed5 Mon Sep 17 00:00:00 2001 From: Christopher Davis Date: Sat, 17 Dec 2011 13:40:04 -0600 Subject: [PATCH 1/9] Add Proxy Authorization support --- requests/auth.py | 8 ++++++++ requests/models.py | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/requests/auth.py b/requests/auth.py index fad6eb79..042962d8 100644 --- a/requests/auth.py +++ b/requests/auth.py @@ -35,6 +35,14 @@ class HTTPBasicAuth(AuthBase): return r +class HTTPProxyAuth(HTTPBasicAuth): + """Attaches HTTP Proxy Authenetication to a given Request object.""" + def __call__(self, r): + auth_s = b64encode('%s:%s' % (self.username, self.password)) + r.headers['Proxy-Authorization'] = ('Basic %s' % auth_s) + return r + + class HTTPDigestAuth(AuthBase): """Attaches HTTP Digest Authentication to the given Request object.""" def __init__(self, username, password): diff --git a/requests/models.py b/requests/models.py index 78af22c6..e043d88c 100644 --- a/requests/models.py +++ b/requests/models.py @@ -17,7 +17,7 @@ from .hooks import dispatch_hook from .structures import CaseInsensitiveDict from .status_codes import codes from .packages import oreos -from .auth import HTTPBasicAuth +from .auth import HTTPBasicAuth, HTTPProxyAuth from .packages.urllib3.exceptions import MaxRetryError from .packages.urllib3.exceptions import SSLError as _SSLError from .packages.urllib3.exceptions import HTTPError as _HTTPError @@ -407,6 +407,12 @@ class Request(object): if proxy: conn = poolmanager.proxy_from_url(proxy) + _proxy = urlparse(proxy) + if '@' in _proxy.netloc: + auth, url = _proxy.netloc.split('@', 1) + self.proxy_auth = HTTPProxyAuth(*auth.split(':', 1)) + r = self.proxy_auth(self) + self.__dict__.update(r.__dict__) else: # Check to see if keep_alive is allowed. if self.config.get('keep_alive'): From 4e2ecd698700698dc1ad0daedf910f3dfa53a4ee Mon Sep 17 00:00:00 2001 From: Christopher Davis Date: Sat, 17 Dec 2011 13:48:40 -0600 Subject: [PATCH 2/9] Fixed some tab/spaces mixed issues --- requests/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requests/models.py b/requests/models.py index e043d88c..e84c8f1a 100644 --- a/requests/models.py +++ b/requests/models.py @@ -409,10 +409,10 @@ class Request(object): conn = poolmanager.proxy_from_url(proxy) _proxy = urlparse(proxy) if '@' in _proxy.netloc: - auth, url = _proxy.netloc.split('@', 1) - self.proxy_auth = HTTPProxyAuth(*auth.split(':', 1)) - r = self.proxy_auth(self) - self.__dict__.update(r.__dict__) + auth, url = _proxy.netloc.split('@', 1) + self.proxy_auth = HTTPProxyAuth(*auth.split(':', 1)) + r = self.proxy_auth(self) + self.__dict__.update(r.__dict__) else: # Check to see if keep_alive is allowed. if self.config.get('keep_alive'): From a3b8ef15dbc863c1923a47c5a9adc055711dfbf8 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 18 Dec 2011 14:07:12 -0500 Subject: [PATCH 3/9] urllib3 import --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index bb385555..d4eb7cbd 100644 --- a/Makefile +++ b/Makefile @@ -13,4 +13,9 @@ stats: site: cd docs; make dirhtml +deps: + rm -fr requests/packages/urllib3 + git clone https://github.com/shazow/urllib3.git + mv urllib3/urllib3 requests/packages/ + rm -fr urllib3 docs: site From 59372826180b860f4b7f4928bf20d7da1a07d584 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 18 Dec 2011 14:07:21 -0500 Subject: [PATCH 4/9] pyc importer --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index d4eb7cbd..01c10638 100644 --- a/Makefile +++ b/Makefile @@ -13,9 +13,13 @@ stats: site: cd docs; make dirhtml +pyc: + find . -name "*.pyc" -exec rm '{}' ';' + deps: rm -fr requests/packages/urllib3 git clone https://github.com/shazow/urllib3.git mv urllib3/urllib3 requests/packages/ rm -fr urllib3 + docs: site From 8f58c095c54a84ad5527e804fcbd506f5b5d1a91 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 18 Dec 2011 14:10:38 -0500 Subject: [PATCH 5/9] urllib3 update --- requests/packages/urllib3/connectionpool.py | 39 ++++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/requests/packages/urllib3/connectionpool.py b/requests/packages/urllib3/connectionpool.py index 8b10dc70..be9b7feb 100644 --- a/requests/packages/urllib3/connectionpool.py +++ b/requests/packages/urllib3/connectionpool.py @@ -210,6 +210,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): if timeout is _Default: timeout = self.timeout + conn.timeout = timeout # This only does anything in Py26+ + conn.request(method, url, **httplib_request_kw) conn.sock.settimeout(timeout) httplib_response = conn.getresponse() @@ -244,6 +246,13 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): More commonly, it's appropriate to use a convenience method provided by :class:`.RequestMethods`, such as :meth:`.request`. + .. note:: + + `release_conn` will only behave as expected if + `preload_content=False` because we want to make + `preload_content=False` the default behaviour someday soon without + breaking backwards compatibility. + :param method: HTTP request method (such as GET, POST, PUT, etc.) @@ -279,10 +288,12 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): :param release_conn: If False, then the urlopen call will not release the connection - back into the pool once a response is received. This is useful if - you're not preloading the response's content immediately. You will - need to call ``r.release_conn()`` on the response ``r`` to return - the connection back into the pool. If None, it takes the value of + back into the pool once a response is received (but will release if + you read the entire contents of the response such as when + `preload_content=True`). This is useful if you're not preloading + the response's content immediately. You will need to call + ``r.release_conn()`` on the response ``r`` to return the connection + back into the pool. If None, it takes the value of ``response_kw.get('preload_content', True)``. :param \**response_kw: @@ -295,6 +306,9 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): if retries < 0: raise MaxRetryError("Max retries exceeded for url: %s" % url) + if timeout is _Default: + timeout = self.timeout + if release_conn is None: release_conn = response_kw.get('preload_content', True) @@ -336,10 +350,15 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # ``response.release_conn()`` is called (implicitly by # ``response.read()``) - except (SocketTimeout, Empty), e: - # Timed out either by socket or queue - raise TimeoutError("Request timed out after %s seconds" % - self.timeout) + except (Empty), e: + # Timed out by queue + raise TimeoutError("Request timed out. (pool_timeout=%s)" % + pool_timeout) + + except (SocketTimeout), e: + # Timed out by socket + raise TimeoutError("Request timed out. (timeout=%s)" % + timeout) except (BaseSSLError), e: # SSL certificate error @@ -488,10 +507,12 @@ def get_host(url): # simplified for our needs. port = None scheme = 'http' - if '//' in url: + if '://' in url: scheme, url = url.split('://', 1) if '/' in url: url, _path = url.split('/', 1) + if '@' in url: + _auth, url = url.split('@', 1) if ':' in url: url, port = url.split(':', 1) port = int(port) From 8207ed074e2f02bd5d77e7583807039a25fa116b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 18 Dec 2011 19:14:50 -0500 Subject: [PATCH 6/9] keep auth DRY --- requests/auth.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/requests/auth.py b/requests/auth.py index 042962d8..5b429ed3 100644 --- a/requests/auth.py +++ b/requests/auth.py @@ -16,6 +16,12 @@ from urlparse import urlparse from .utils import randombytes, parse_dict_header + +def _basic_auth_str(username, password): + """Returns a Basic Auth string.""" + return 'Basic %s' % b64encode('%s:%s' % (username, password)) + + class AuthBase(object): """Base class that all auth implementations derive from""" @@ -30,16 +36,14 @@ class HTTPBasicAuth(AuthBase): self.password = str(password) def __call__(self, r): - auth_s = b64encode('%s:%s' % (self.username, self.password)) - r.headers['Authorization'] = ('Basic %s' % auth_s) + r.headers['Authorization'] = _basic_auth_str(self.username, self.password) return r class HTTPProxyAuth(HTTPBasicAuth): """Attaches HTTP Proxy Authenetication to a given Request object.""" def __call__(self, r): - auth_s = b64encode('%s:%s' % (self.username, self.password)) - r.headers['Proxy-Authorization'] = ('Basic %s' % auth_s) + r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password) return r From 5be6c21b140bb0c140527cb843b6b474594f165b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 18 Dec 2011 19:17:51 -0500 Subject: [PATCH 7/9] added @chrisguitarguy to authors. #309 --- AUTHORS.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index e1835d24..023deb52 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -64,4 +64,5 @@ Patches and Suggestions - Robert Gieseke - Idan Gazit - Ed Summers -- Chris Van Horne \ No newline at end of file +- Chris Van Horne +- Christopher Davis \ No newline at end of file From 6ce4ece8aa452764be26cdb26e5ce72dfd0da53d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 18 Dec 2011 19:18:09 -0500 Subject: [PATCH 8/9] v0.8.6 --- HISTORY.rst | 7 +++++++ requests/__init__.py | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 4fb77402..d17355ec 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,13 @@ History ------- +0.8.6 (2011-12-18) +++++++++++++++++++ + +* Socket timeout fixes. +* Proxy Authorization support. + + 0.8.5 (2011-12-14) ++++++++++++++++++ diff --git a/requests/__init__.py b/requests/__init__.py index 55f63706..ee3173e1 100644 --- a/requests/__init__.py +++ b/requests/__init__.py @@ -15,8 +15,8 @@ requests """ __title__ = 'requests' -__version__ = '0.8.5' -__build__ = 0x000805 +__version__ = '0.8.6' +__build__ = 0x000806 __author__ = 'Kenneth Reitz' __license__ = 'ISC' __copyright__ = 'Copyright 2011 Kenneth Reitz' From c910b958f0694a5e5e7a517cf5b9bdec5f2fef03 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 18 Dec 2011 19:18:16 -0500 Subject: [PATCH 9/9] quotes --- requests/auth.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requests/auth.py b/requests/auth.py index 5b429ed3..4af3d6d3 100644 --- a/requests/auth.py +++ b/requests/auth.py @@ -88,8 +88,8 @@ class HTTPDigestAuth(AuthBase): p_parsed = urlparse(r.request.url) path = p_parsed.path + p_parsed.query - A1 = "%s:%s:%s" % (self.username, realm, self.password) - A2 = "%s:%s" % (r.request.method, path) + A1 = '%s:%s:%s' % (self.username, realm, self.password) + A2 = '%s:%s' % (r.request.method, path) if qop == 'auth': if nonce == last_nonce: