Index: third_party/requests/adapters.py |
diff --git a/third_party/requests/adapters.py b/third_party/requests/adapters.py |
index 98b7317edb1242b1fbcdc86f0bcb880fd83b7b34..d557b74629946152902e1493bbb0375fe8873e1f 100644 |
--- a/third_party/requests/adapters.py |
+++ b/third_party/requests/adapters.py |
@@ -11,11 +11,12 @@ and maintain connections. |
import socket |
from .models import Response |
-from .packages.urllib3.poolmanager import PoolManager, ProxyManager |
+from .packages.urllib3.poolmanager import PoolManager, proxy_from_url |
from .packages.urllib3.response import HTTPResponse |
+from .packages.urllib3.util import Timeout as TimeoutSauce |
from .compat import urlparse, basestring, urldefrag, unquote |
from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers, |
- prepend_scheme_if_needed, get_auth_from_url) |
+ except_on_missing_scheme, get_auth_from_url) |
from .structures import CaseInsensitiveDict |
from .packages.urllib3.exceptions import MaxRetryError |
from .packages.urllib3.exceptions import TimeoutError |
@@ -71,6 +72,7 @@ class HTTPAdapter(BaseAdapter): |
pool_block=DEFAULT_POOLBLOCK): |
self.max_retries = max_retries |
self.config = {} |
+ self.proxy_manager = {} |
super(HTTPAdapter, self).__init__() |
@@ -118,7 +120,7 @@ class HTTPAdapter(BaseAdapter): |
:param verify: Whether we should actually verify the certificate. |
:param cert: The SSL certificate to verify. |
""" |
- if url.startswith('https') and verify: |
+ if url.lower().startswith('https') and verify: |
cert_loc = None |
@@ -184,19 +186,26 @@ class HTTPAdapter(BaseAdapter): |
def get_connection(self, url, proxies=None): |
"""Returns a urllib3 connection for the given URL. This should not be |
called from user code, and is only exposed for use when subclassing the |
- :class:`HTTPAdapter <reqeusts.adapters.HTTPAdapter>`. |
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
:param url: The URL to connect to. |
:param proxies: (optional) A Requests-style dictionary of proxies used on this request. |
""" |
proxies = proxies or {} |
- proxy = proxies.get(urlparse(url).scheme) |
+ proxy = proxies.get(urlparse(url.lower()).scheme) |
if proxy: |
- proxy = prepend_scheme_if_needed(proxy, urlparse(url).scheme) |
- conn = ProxyManager(self.poolmanager.connection_from_url(proxy)) |
+ except_on_missing_scheme(proxy) |
+ proxy_headers = self.proxy_headers(proxy) |
+ |
+ if not proxy in self.proxy_manager: |
+ self.proxy_manager[proxy] = proxy_from_url( |
+ proxy, |
+ proxy_headers=proxy_headers) |
+ |
+ conn = self.proxy_manager[proxy].connection_from_url(url) |
else: |
- conn = self.poolmanager.connection_from_url(url) |
+ conn = self.poolmanager.connection_from_url(url.lower()) |
return conn |
@@ -214,7 +223,7 @@ class HTTPAdapter(BaseAdapter): |
If the message is being sent through a proxy, the full URL has to be |
used. Otherwise, we should only use the path portion of the URL. |
- This shoudl not be called from user code, and is only exposed for use |
+ This should not be called from user code, and is only exposed for use |
when subclassing the |
:class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
@@ -232,8 +241,9 @@ 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. |
+ """Add any headers needed by the connection. As of v2.0 this does |
+ nothing by default, but is left for overriding by users that subclass |
+ the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
This should not be called from user code, and is only exposed for use |
when subclassing the |
@@ -242,12 +252,22 @@ class HTTPAdapter(BaseAdapter): |
:param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to. |
:param kwargs: The keyword arguments from the call to send(). |
""" |
- proxies = kwargs.get('proxies', {}) |
+ pass |
- if proxies is None: |
- proxies = {} |
+ def proxy_headers(self, proxy): |
+ """Returns a dictionary of the headers to add to any request sent |
+ through a proxy. This works with urllib3 magic to ensure that they are |
+ correctly sent to the proxy, rather than in a tunnelled request if |
+ CONNECT is being used. |
- proxy = proxies.get(urlparse(request.url).scheme) |
+ This should not be called from user code, and is only exposed for use |
+ when subclassing the |
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
+ |
+ :param proxies: The url of the proxy being used for this request. |
+ :param kwargs: Optional additional keyword arguments. |
+ """ |
+ headers = {} |
username, password = get_auth_from_url(proxy) |
if username and password: |
@@ -255,8 +275,10 @@ class HTTPAdapter(BaseAdapter): |
# to decode them. |
username = unquote(username) |
password = unquote(password) |
- request.headers['Proxy-Authorization'] = _basic_auth_str(username, |
- password) |
+ headers['Proxy-Authorization'] = _basic_auth_str(username, |
+ password) |
+ |
+ return headers |
def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): |
"""Sends PreparedRequest object. Returns Response object. |
@@ -273,10 +295,15 @@ class HTTPAdapter(BaseAdapter): |
self.cert_verify(conn, request.url, verify, cert) |
url = self.request_url(request, proxies) |
- self.add_headers(request, proxies=proxies) |
+ self.add_headers(request) |
chunked = not (request.body is None or 'Content-Length' in request.headers) |
+ if stream: |
+ timeout = TimeoutSauce(connect=timeout) |
+ else: |
+ timeout = TimeoutSauce(connect=timeout, read=timeout) |
+ |
try: |
if not chunked: |
resp = conn.urlopen( |