aboutsummaryrefslogtreecommitdiff
path: root/requests/adapters.py
diff options
context:
space:
mode:
Diffstat (limited to 'requests/adapters.py')
-rw-r--r--requests/adapters.py53
1 files changed, 45 insertions, 8 deletions
diff --git a/requests/adapters.py b/requests/adapters.py
index 5f9d9c7..5666e66 100644
--- a/requests/adapters.py
+++ b/requests/adapters.py
@@ -11,12 +11,11 @@ and maintain connections.
import socket
from .models import Response
-from .packages.urllib3.poolmanager import PoolManager, proxy_from_url
+from .packages.urllib3.poolmanager import PoolManager, ProxyManager
from .packages.urllib3.response import HTTPResponse
-from .hooks import dispatch_hook
-from .compat import urlparse, basestring, urldefrag
+from .compat import urlparse, basestring, urldefrag, unquote
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
@@ -24,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
@@ -44,15 +44,34 @@ class BaseAdapter(object):
class HTTPAdapter(BaseAdapter):
"""Built-In HTTP Adapter for Urllib3."""
+ __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize']
+
def __init__(self, pool_connections=DEFAULT_POOLSIZE, pool_maxsize=DEFAULT_POOLSIZE):
self.max_retries = DEFAULT_RETRIES
self.config = {}
super(HTTPAdapter, self).__init__()
+ self._pool_connections = pool_connections
+ self._pool_maxsize = pool_maxsize
+
self.init_poolmanager(pool_connections, pool_maxsize)
+ def __getstate__(self):
+ return dict((attr, getattr(self, attr, None)) for attr in
+ self.__attrs__)
+
+ def __setstate__(self, state):
+ for attr, value in state.items():
+ setattr(self, attr, value)
+
+ self.init_poolmanager(self._pool_connections, self._pool_maxsize)
+
def init_poolmanager(self, connections, maxsize):
+ # save these values for pickling
+ self._pool_connections = connections
+ self._pool_maxsize = maxsize
+
self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize)
def cert_verify(self, conn, url, verify, cert):
@@ -109,8 +128,6 @@ class HTTPAdapter(BaseAdapter):
response.request = req
response.connection = self
- # Run the Response hook.
- response = dispatch_hook('response', req.hooks, response)
return response
def get_connection(self, url, proxies=None):
@@ -120,7 +137,7 @@ class HTTPAdapter(BaseAdapter):
if proxy:
proxy = prepend_scheme_if_needed(proxy, urlparse(url).scheme)
- conn = proxy_from_url(proxy)
+ conn = ProxyManager(self.poolmanager.connection_from_url(proxy))
else:
conn = self.poolmanager.connection_from_url(url)
@@ -149,6 +166,25 @@ class HTTPAdapter(BaseAdapter):
return url
+ def add_headers(self, request, **kwargs):
+ """Add any headers needed by the connection. Currently this adds a
+ Proxy-Authorization header."""
+ 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:
+ # Proxy auth usernames and passwords will be urlencoded, we need
+ # to decode them.
+ username = unquote(username)
+ password = unquote(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."""
@@ -156,6 +192,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)
@@ -214,7 +251,7 @@ class HTTPAdapter(BaseAdapter):
elif isinstance(e, TimeoutError):
raise Timeout(e)
else:
- raise Timeout('Request timed out.')
+ raise
r = self.build_response(request, resp)