| Index: third_party/requests/packages/urllib3/connectionpool.py | 
| diff --git a/third_party/requests/packages/urllib3/connectionpool.py b/third_party/requests/packages/urllib3/connectionpool.py | 
| index f3e926089f91e39b159e50679a5852de8fbde4d5..691d4e238b370a23e1900cc951979162d0b1530a 100644 | 
| --- a/third_party/requests/packages/urllib3/connectionpool.py | 
| +++ b/third_party/requests/packages/urllib3/connectionpool.py | 
| @@ -4,12 +4,11 @@ | 
| # This module is part of urllib3 and is released under | 
| # the MIT License: http://www.opensource.org/licenses/mit-license.php | 
|  | 
| -import logging | 
| -import socket | 
| import errno | 
| +import logging | 
|  | 
| from socket import error as SocketError, timeout as SocketTimeout | 
| -from .util import resolve_cert_reqs, resolve_ssl_version, assert_fingerprint | 
| +import socket | 
|  | 
| try: # Python 3 | 
| from http.client import HTTPConnection, HTTPException | 
| @@ -22,11 +21,15 @@ try: # Python 3 | 
| from queue import LifoQueue, Empty, Full | 
| except ImportError: | 
| from Queue import LifoQueue, Empty, Full | 
| +    import Queue as _  # Platform-specific: Windows | 
|  | 
|  | 
| try: # Compiled with SSL? | 
| HTTPSConnection = object | 
| -    BaseSSLError = None | 
| + | 
| +    class BaseSSLError(BaseException): | 
| +        pass | 
| + | 
| ssl = None | 
|  | 
| try: # Python 3 | 
| @@ -41,21 +44,29 @@ except (ImportError, AttributeError): # Platform-specific: No SSL. | 
| pass | 
|  | 
|  | 
| -from .request import RequestMethods | 
| -from .response import HTTPResponse | 
| -from .util import get_host, is_connection_dropped, ssl_wrap_socket | 
| from .exceptions import ( | 
| ClosedPoolError, | 
| +    ConnectTimeoutError, | 
| EmptyPoolError, | 
| HostChangedError, | 
| MaxRetryError, | 
| SSLError, | 
| -    TimeoutError, | 
| +    ReadTimeoutError, | 
| +    ProxyError, | 
| ) | 
| - | 
| -from .packages.ssl_match_hostname import match_hostname, CertificateError | 
| +from .packages.ssl_match_hostname import CertificateError, match_hostname | 
| from .packages import six | 
| - | 
| +from .request import RequestMethods | 
| +from .response import HTTPResponse | 
| +from .util import ( | 
| +    assert_fingerprint, | 
| +    get_host, | 
| +    is_connection_dropped, | 
| +    resolve_cert_reqs, | 
| +    resolve_ssl_version, | 
| +    ssl_wrap_socket, | 
| +    Timeout, | 
| +) | 
|  | 
| xrange = six.moves.xrange | 
|  | 
| @@ -93,11 +104,24 @@ class VerifiedHTTPSConnection(HTTPSConnection): | 
|  | 
| def connect(self): | 
| # Add certificate verification | 
| -        sock = socket.create_connection((self.host, self.port), self.timeout) | 
| +        try: | 
| +            sock = socket.create_connection( | 
| +                address=(self.host, self.port), | 
| +                timeout=self.timeout) | 
| +        except SocketTimeout: | 
| +                raise ConnectTimeoutError( | 
| +                    self, "Connection to %s timed out. (connect timeout=%s)" % | 
| +                    (self.host, self.timeout)) | 
|  | 
| resolved_cert_reqs = resolve_cert_reqs(self.cert_reqs) | 
| resolved_ssl_version = resolve_ssl_version(self.ssl_version) | 
|  | 
| +        if self._tunnel_host: | 
| +            self.sock = sock | 
| +            # Calls self._set_hostport(), so self.host is | 
| +            # self._tunnel_host below. | 
| +            self._tunnel() | 
| + | 
| # Wrap socket using verification with the root certs in | 
| # trusted_root_certs | 
| self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file, | 
| @@ -110,10 +134,11 @@ class VerifiedHTTPSConnection(HTTPSConnection): | 
| if self.assert_fingerprint: | 
| assert_fingerprint(self.sock.getpeercert(binary_form=True), | 
| self.assert_fingerprint) | 
| -            else: | 
| +            elif self.assert_hostname is not False: | 
| match_hostname(self.sock.getpeercert(), | 
| self.assert_hostname or self.host) | 
|  | 
| + | 
| ## Pool objects | 
|  | 
| class ConnectionPool(object): | 
| @@ -126,6 +151,9 @@ class ConnectionPool(object): | 
| QueueCls = LifoQueue | 
|  | 
| def __init__(self, host, port=None): | 
| +        # httplib doesn't like it when we include brackets in ipv6 addresses | 
| +        host = host.strip('[]') | 
| + | 
| self.host = host | 
| self.port = port | 
|  | 
| @@ -133,6 +161,8 @@ class ConnectionPool(object): | 
| return '%s(host=%r, port=%r)' % (type(self).__name__, | 
| self.host, self.port) | 
|  | 
| +# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 | 
| +_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK]) | 
|  | 
| class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| """ | 
| @@ -151,9 +181,15 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| as a valid HTTP/1.0 or 1.1 status line, passed into | 
| :class:`httplib.HTTPConnection`. | 
|  | 
| +        .. note:: | 
| +           Only works in Python 2. This parameter is ignored in Python 3. | 
| + | 
| :param timeout: | 
| -        Socket timeout for each individual connection, can be a float. None | 
| -        disables timeout. | 
| +        Socket timeout in seconds for each individual connection. This can | 
| +        be a float or integer, which sets the timeout for the HTTP request, | 
| +        or an instance of :class:`urllib3.util.Timeout` which gives you more | 
| +        fine-grained control over request timeouts. After the constructor has | 
| +        been parsed, this is always a `urllib3.util.Timeout` object. | 
|  | 
| :param maxsize: | 
| Number of connections to save that can be reused. More than 1 is useful | 
| @@ -171,20 +207,39 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| :param headers: | 
| Headers to include with all requests, unless other headers are given | 
| explicitly. | 
| + | 
| +    :param _proxy: | 
| +        Parsed proxy URL, should not be used directly, instead, see | 
| +        :class:`urllib3.connectionpool.ProxyManager`" | 
| + | 
| +    :param _proxy_headers: | 
| +        A dictionary with proxy headers, should not be used directly, | 
| +        instead, see :class:`urllib3.connectionpool.ProxyManager`" | 
| """ | 
|  | 
| scheme = 'http' | 
|  | 
| -    def __init__(self, host, port=None, strict=False, timeout=None, maxsize=1, | 
| -                 block=False, headers=None): | 
| +    def __init__(self, host, port=None, strict=False, | 
| +                 timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, | 
| +                 headers=None, _proxy=None, _proxy_headers=None): | 
| ConnectionPool.__init__(self, host, port) | 
| RequestMethods.__init__(self, headers) | 
|  | 
| self.strict = strict | 
| + | 
| +        # This is for backwards compatibility and can be removed once a timeout | 
| +        # can only be set to a Timeout object | 
| +        if not isinstance(timeout, Timeout): | 
| +            timeout = Timeout.from_float(timeout) | 
| + | 
| self.timeout = timeout | 
| + | 
| self.pool = self.QueueCls(maxsize) | 
| self.block = block | 
|  | 
| +        self.proxy = _proxy | 
| +        self.proxy_headers = _proxy_headers or {} | 
| + | 
| # Fill the queue up so that doing get() on it will block properly | 
| for _ in xrange(maxsize): | 
| self.pool.put(None) | 
| @@ -200,9 +255,14 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| self.num_connections += 1 | 
| log.info("Starting new HTTP connection (%d): %s" % | 
| (self.num_connections, self.host)) | 
| -        return HTTPConnection(host=self.host, | 
| -                              port=self.port, | 
| -                              strict=self.strict) | 
| +        extra_params = {} | 
| +        if not six.PY3:  # Python 2 | 
| +            extra_params['strict'] = self.strict | 
| + | 
| +        return HTTPConnection(host=self.host, port=self.port, | 
| +                              timeout=self.timeout.connect_timeout, | 
| +                              **extra_params) | 
| + | 
|  | 
| def _get_conn(self, timeout=None): | 
| """ | 
| @@ -263,31 +323,89 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| % self.host) | 
|  | 
| # Connection never got put back into the pool, close it. | 
| -        conn.close() | 
| +        if conn: | 
| +            conn.close() | 
| + | 
| +    def _get_timeout(self, timeout): | 
| +        """ Helper that always returns a :class:`urllib3.util.Timeout` """ | 
| +        if timeout is _Default: | 
| +            return self.timeout.clone() | 
| + | 
| +        if isinstance(timeout, Timeout): | 
| +            return timeout.clone() | 
| +        else: | 
| +            # User passed us an int/float. This is for backwards compatibility, | 
| +            # can be removed later | 
| +            return Timeout.from_float(timeout) | 
|  | 
| def _make_request(self, conn, method, url, timeout=_Default, | 
| **httplib_request_kw): | 
| """ | 
| Perform a request on a given httplib connection object taken from our | 
| pool. | 
| + | 
| +        :param conn: | 
| +            a connection from one of our connection pools | 
| + | 
| +        :param timeout: | 
| +            Socket timeout in seconds for the request. This can be a | 
| +            float or integer, which will set the same timeout value for | 
| +            the socket connect and the socket read, or an instance of | 
| +            :class:`urllib3.util.Timeout`, which gives you more fine-grained | 
| +            control over your timeouts. | 
| """ | 
| self.num_requests += 1 | 
|  | 
| -        if timeout is _Default: | 
| -            timeout = self.timeout | 
| - | 
| -        conn.timeout = timeout # This only does anything in Py26+ | 
| -        conn.request(method, url, **httplib_request_kw) | 
| +        timeout_obj = self._get_timeout(timeout) | 
|  | 
| -        # Set timeout | 
| -        sock = getattr(conn, 'sock', False) # AppEngine doesn't have sock attr. | 
| -        if sock: | 
| -            sock.settimeout(timeout) | 
| +        try: | 
| +            timeout_obj.start_connect() | 
| +            conn.timeout = timeout_obj.connect_timeout | 
| +            # conn.request() calls httplib.*.request, not the method in | 
| +            # request.py. It also calls makefile (recv) on the socket | 
| +            conn.request(method, url, **httplib_request_kw) | 
| +        except SocketTimeout: | 
| +            raise ConnectTimeoutError( | 
| +                self, "Connection to %s timed out. (connect timeout=%s)" % | 
| +                (self.host, timeout_obj.connect_timeout)) | 
| + | 
| +        # Reset the timeout for the recv() on the socket | 
| +        read_timeout = timeout_obj.read_timeout | 
| +        log.debug("Setting read timeout to %s" % read_timeout) | 
| +        # App Engine doesn't have a sock attr | 
| +        if hasattr(conn, 'sock') and \ | 
| +            read_timeout is not None and \ | 
| +            read_timeout is not Timeout.DEFAULT_TIMEOUT: | 
| +            # In Python 3 socket.py will catch EAGAIN and return None when you | 
| +            # try and read into the file pointer created by http.client, which | 
| +            # instead raises a BadStatusLine exception. Instead of catching | 
| +            # the exception and assuming all BadStatusLine exceptions are read | 
| +            # timeouts, check for a zero timeout before making the request. | 
| +            if read_timeout == 0: | 
| +                raise ReadTimeoutError( | 
| +                    self, url, | 
| +                    "Read timed out. (read timeout=%s)" % read_timeout) | 
| +            conn.sock.settimeout(read_timeout) | 
| + | 
| +        # Receive the response from the server | 
| +        try: | 
| +            try: # Python 2.7+, use buffering of HTTP responses | 
| +                httplib_response = conn.getresponse(buffering=True) | 
| +            except TypeError: # Python 2.6 and older | 
| +                httplib_response = conn.getresponse() | 
| +        except SocketTimeout: | 
| +            raise ReadTimeoutError( | 
| +                self, url, "Read timed out. (read timeout=%s)" % read_timeout) | 
| + | 
| +        except SocketError as e: # Platform-specific: Python 2 | 
| +            # See the above comment about EAGAIN in Python 3. In Python 2 we | 
| +            # have to specifically catch it and throw the timeout error | 
| +            if e.errno in _blocking_errnos: | 
| +                raise ReadTimeoutError( | 
| +                    self, url, | 
| +                    "Read timed out. (read timeout=%s)" % read_timeout) | 
| +            raise | 
|  | 
| -        try: # Python 2.7+, use buffering of HTTP responses | 
| -            httplib_response = conn.getresponse(buffering=True) | 
| -        except TypeError: # Python 2.6 and older | 
| -            httplib_response = conn.getresponse() | 
|  | 
| # AppEngine doesn't have a version attr. | 
| http_version = getattr(conn, '_http_vsn_str', 'HTTP/?') | 
| @@ -367,7 +485,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
|  | 
| :param redirect: | 
| If True, automatically handle redirects (status codes 301, 302, | 
| -            303, 307). Each redirect counts as a retry. | 
| +            303, 307, 308). Each redirect counts as a retry. | 
|  | 
| :param assert_same_host: | 
| If ``True``, will make sure that the host of the pool requests is | 
| @@ -375,7 +493,9 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| use the pool on an HTTP proxy and request foreign hosts. | 
|  | 
| :param timeout: | 
| -            If specified, overrides the default timeout for this one request. | 
| +            If specified, overrides the default timeout for this one | 
| +            request. It may be a float (in seconds) or an instance of | 
| +            :class:`urllib3.util.Timeout`. | 
|  | 
| :param pool_timeout: | 
| If set and the pool is set to block=True, then this method will | 
| @@ -402,18 +522,11 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| if retries < 0: | 
| raise MaxRetryError(self, url) | 
|  | 
| -        if timeout is _Default: | 
| -            timeout = self.timeout | 
| - | 
| if release_conn is None: | 
| release_conn = response_kw.get('preload_content', True) | 
|  | 
| # Check host | 
| if assert_same_host and not self.is_same_host(url): | 
| -            host = "%s://%s" % (self.scheme, self.host) | 
| -            if self.port: | 
| -                host = "%s:%d" % (host, self.port) | 
| - | 
| raise HostChangedError(self, url, retries - 1) | 
|  | 
| conn = None | 
| @@ -444,20 +557,20 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| #     ``response.release_conn()`` is called (implicitly by | 
| #     ``response.read()``) | 
|  | 
| -        except Empty as e: | 
| +        except Empty: | 
| # Timed out by queue | 
| -            raise TimeoutError(self, url, | 
| -                               "Request timed out. (pool_timeout=%s)" % | 
| -                               pool_timeout) | 
| +            raise ReadTimeoutError( | 
| +                self, url, "Read timed out, no pool connections are available.") | 
|  | 
| -        except SocketTimeout as e: | 
| +        except SocketTimeout: | 
| # Timed out by socket | 
| -            raise TimeoutError(self, url, | 
| -                               "Request timed out. (timeout=%s)" % | 
| -                               timeout) | 
| +            raise ReadTimeoutError(self, url, "Read timed out.") | 
|  | 
| except BaseSSLError as e: | 
| # SSL certificate error | 
| +            if 'timed out' in str(e) or \ | 
| +               'did not complete (read)' in str(e): # Platform-specific: Python 2.6 | 
| +                raise ReadTimeoutError(self, url, "Read timed out.") | 
| raise SSLError(e) | 
|  | 
| except CertificateError as e: | 
| @@ -465,6 +578,10 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): | 
| raise SSLError(e) | 
|  | 
| except (HTTPException, SocketError) as e: | 
| +            if isinstance(e, SocketError) and self.proxy is not None: | 
| +                raise ProxyError('Cannot connect to proxy. ' | 
| +                                 'Socket error: %s.' % e) | 
| + | 
| # Connection broken, discard. It will be replaced next _get_conn(). | 
| conn = None | 
| # This is necessary so we can access e below | 
| @@ -513,6 +630,7 @@ class HTTPSConnectionPool(HTTPConnectionPool): | 
|  | 
| :class:`.VerifiedHTTPSConnection` uses one of ``assert_fingerprint``, | 
| ``assert_hostname`` and ``host`` in this order to verify connections. | 
| +    If ``assert_hostname`` is False, no verification is done. | 
|  | 
| The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs`` and | 
| ``ssl_version`` are only used if :mod:`ssl` is available and are fed into | 
| @@ -525,13 +643,13 @@ class HTTPSConnectionPool(HTTPConnectionPool): | 
| def __init__(self, host, port=None, | 
| strict=False, timeout=None, maxsize=1, | 
| block=False, headers=None, | 
| +                 _proxy=None, _proxy_headers=None, | 
| key_file=None, cert_file=None, cert_reqs=None, | 
| ca_certs=None, ssl_version=None, | 
| assert_hostname=None, assert_fingerprint=None): | 
|  | 
| -        HTTPConnectionPool.__init__(self, host, port, | 
| -                                    strict, timeout, maxsize, | 
| -                                    block, headers) | 
| +        HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize, | 
| +                                    block, headers, _proxy, _proxy_headers) | 
| self.key_file = key_file | 
| self.cert_file = cert_file | 
| self.cert_reqs = cert_reqs | 
| @@ -540,6 +658,34 @@ class HTTPSConnectionPool(HTTPConnectionPool): | 
| self.assert_hostname = assert_hostname | 
| self.assert_fingerprint = assert_fingerprint | 
|  | 
| +    def _prepare_conn(self, connection): | 
| +        """ | 
| +        Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` | 
| +        and establish the tunnel if proxy is used. | 
| +        """ | 
| + | 
| +        if isinstance(connection, VerifiedHTTPSConnection): | 
| +            connection.set_cert(key_file=self.key_file, | 
| +                                cert_file=self.cert_file, | 
| +                                cert_reqs=self.cert_reqs, | 
| +                                ca_certs=self.ca_certs, | 
| +                                assert_hostname=self.assert_hostname, | 
| +                                assert_fingerprint=self.assert_fingerprint) | 
| +            connection.ssl_version = self.ssl_version | 
| + | 
| +        if self.proxy is not None: | 
| +            # Python 2.7+ | 
| +            try: | 
| +                set_tunnel = connection.set_tunnel | 
| +            except AttributeError:  # Platform-specific: Python 2.6 | 
| +                set_tunnel = connection._set_tunnel | 
| +            set_tunnel(self.host, self.port, self.proxy_headers) | 
| +            # Establish tunnel connection early, because otherwise httplib | 
| +            # would improperly set Host: header to proxy's IP:port. | 
| +            connection.connect() | 
| + | 
| +        return connection | 
| + | 
| def _new_conn(self): | 
| """ | 
| Return a fresh :class:`httplib.HTTPSConnection`. | 
| @@ -548,26 +694,28 @@ class HTTPSConnectionPool(HTTPConnectionPool): | 
| log.info("Starting new HTTPS connection (%d): %s" | 
| % (self.num_connections, self.host)) | 
|  | 
| +        actual_host = self.host | 
| +        actual_port = self.port | 
| +        if self.proxy is not None: | 
| +            actual_host = self.proxy.host | 
| +            actual_port = self.proxy.port | 
| + | 
| if not ssl:  # Platform-specific: Python compiled without +ssl | 
| if not HTTPSConnection or HTTPSConnection is object: | 
| raise SSLError("Can't connect to HTTPS URL because the SSL " | 
| "module is not available.") | 
| - | 
| -            return HTTPSConnection(host=self.host, | 
| -                                   port=self.port, | 
| -                                   strict=self.strict) | 
| - | 
| -        connection = VerifiedHTTPSConnection(host=self.host, | 
| -                                             port=self.port, | 
| -                                             strict=self.strict) | 
| -        connection.set_cert(key_file=self.key_file, cert_file=self.cert_file, | 
| -                            cert_reqs=self.cert_reqs, ca_certs=self.ca_certs, | 
| -                            assert_hostname=self.assert_hostname, | 
| -                            assert_fingerprint=self.assert_fingerprint) | 
| - | 
| -        connection.ssl_version = self.ssl_version | 
| - | 
| -        return connection | 
| +            connection_class = HTTPSConnection | 
| +        else: | 
| +            connection_class = VerifiedHTTPSConnection | 
| + | 
| +        extra_params = {} | 
| +        if not six.PY3:  # Python 2 | 
| +            extra_params['strict'] = self.strict | 
| +        connection = connection_class(host=actual_host, port=actual_port, | 
| +                                      timeout=self.timeout.connect_timeout, | 
| +                                      **extra_params) | 
| + | 
| +        return self._prepare_conn(connection) | 
|  | 
|  | 
| def connection_from_url(url, **kw): | 
|  |