Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/requests/adapters.py: 25%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2requests.adapters
3~~~~~~~~~~~~~~~~~
5This module contains the transport adapters that Requests uses to define
6and maintain connections.
7"""
9from __future__ import annotations
11import os.path
12import socket # noqa: F401 # type: ignore[reportUnusedImport]
13import typing
14import warnings
15from typing import Any
17from urllib3.exceptions import (
18 ClosedPoolError,
19 ConnectTimeoutError,
20 LocationValueError,
21 MaxRetryError,
22 NewConnectionError,
23 ProtocolError,
24 ReadTimeoutError,
25 ResponseError,
26)
27from urllib3.exceptions import HTTPError as _HTTPError
28from urllib3.exceptions import InvalidHeader as _InvalidHeader
29from urllib3.exceptions import ProxyError as _ProxyError
30from urllib3.exceptions import SSLError as _SSLError
31from urllib3.poolmanager import PoolManager, proxy_from_url
32from urllib3.util import Timeout as TimeoutSauce
33from urllib3.util import parse_url
34from urllib3.util.retry import Retry
36from .auth import _basic_auth_str # type: ignore[reportPrivateUsage]
37from .compat import basestring, urlparse
38from .cookies import extract_cookies_to_jar
39from .exceptions import (
40 ConnectionError,
41 ConnectTimeout,
42 InvalidHeader,
43 InvalidProxyURL,
44 InvalidSchema,
45 InvalidURL,
46 ProxyError,
47 ReadTimeout,
48 RetryError,
49 SSLError,
50)
51from .models import Response
52from .structures import CaseInsensitiveDict
53from .utils import (
54 DEFAULT_CA_BUNDLE_PATH,
55 get_auth_from_url,
56 get_encoding_from_headers,
57 prepend_scheme_if_needed,
58 select_proxy,
59 urldefragauth,
60)
62try:
63 from urllib3.contrib.socks import SOCKSProxyManager # type: ignore[assignment]
64except ImportError:
66 def SOCKSProxyManager(*args: Any, **kwargs: Any) -> None:
67 raise InvalidSchema("Missing dependencies for SOCKS support.")
70if typing.TYPE_CHECKING:
71 from urllib3.connectionpool import HTTPConnectionPool
72 from urllib3.poolmanager import PoolManager as _PoolManager
74 from . import _types as _t
75 from .models import PreparedRequest
77from ._types import is_prepared as _is_prepared
79DEFAULT_POOLBLOCK = False
80DEFAULT_POOLSIZE = 10
81DEFAULT_RETRIES = 0
82DEFAULT_POOL_TIMEOUT = None
85def _urllib3_request_context(
86 request: PreparedRequest,
87 verify: bool | str | None,
88 client_cert: tuple[str, str] | str | None,
89 poolmanager: PoolManager,
90) -> tuple[dict[str, Any], dict[str, Any]]:
91 host_params: dict[str, Any] = {}
92 pool_kwargs: dict[str, Any] = {}
93 parsed_request_url = urlparse(request.url)
94 scheme = parsed_request_url.scheme.lower()
95 port = parsed_request_url.port
97 cert_reqs = "CERT_REQUIRED"
98 if verify is False:
99 cert_reqs = "CERT_NONE"
100 elif isinstance(verify, str):
101 if not os.path.isdir(verify):
102 pool_kwargs["ca_certs"] = verify
103 else:
104 pool_kwargs["ca_cert_dir"] = verify
105 pool_kwargs["cert_reqs"] = cert_reqs
106 if client_cert is not None:
107 if isinstance(client_cert, tuple) and len(client_cert) == 2:
108 pool_kwargs["cert_file"] = client_cert[0]
109 pool_kwargs["key_file"] = client_cert[1]
110 else:
111 # According to our docs, we allow users to specify just the client
112 # cert path
113 pool_kwargs["cert_file"] = client_cert
114 host_params = {
115 "scheme": scheme,
116 "host": parsed_request_url.hostname,
117 "port": port,
118 }
119 return host_params, pool_kwargs
122class BaseAdapter:
123 """The Base Transport Adapter"""
125 def __init__(self) -> None:
126 super().__init__()
128 def send(
129 self,
130 request: PreparedRequest,
131 stream: bool = False,
132 timeout: _t.TimeoutType = None,
133 verify: _t.VerifyType = True,
134 cert: _t.CertType = None,
135 proxies: dict[str, str] | None = None,
136 ) -> Response:
137 """Sends PreparedRequest object. Returns Response object.
139 :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
140 :param stream: (optional) Whether to stream the request content.
141 :param timeout: (optional) How long to wait for the server to send
142 data before giving up, as a float, or a :ref:`(connect timeout,
143 read timeout) <timeouts>` tuple.
144 :type timeout: float or tuple
145 :param verify: (optional) Either a boolean, in which case it controls whether we verify
146 the server's TLS certificate, or a string, in which case it must be a path
147 to a CA bundle to use
148 :param cert: (optional) Any user-provided SSL certificate to be trusted.
149 :param proxies: (optional) The proxies dictionary to apply to the request.
150 """
151 raise NotImplementedError
153 def close(self) -> None:
154 """Cleans up adapter specific items."""
155 raise NotImplementedError
158class HTTPAdapter(BaseAdapter):
159 """The built-in HTTP Adapter for urllib3.
161 Provides a general-case interface for Requests sessions to contact HTTP and
162 HTTPS urls by implementing the Transport Adapter interface. This class will
163 usually be created by the :class:`Session <Session>` class under the
164 covers.
166 :param pool_connections: The number of urllib3 connection pools to cache.
167 :param pool_maxsize: The maximum number of connections to save in the pool.
168 :param max_retries: The maximum number of retries each connection
169 should attempt. Note, this applies only to failed DNS lookups, socket
170 connections and connection timeouts, never to requests where data has
171 made it to the server. By default, Requests does not retry failed
172 connections. If you need granular control over the conditions under
173 which we retry a request, import urllib3's ``Retry`` class and pass
174 that instead.
175 :param pool_block: Whether the connection pool should block for connections.
177 Usage::
179 >>> import requests
180 >>> s = requests.Session()
181 >>> a = requests.adapters.HTTPAdapter(max_retries=3)
182 >>> s.mount('http://', a)
183 """
185 __attrs__: list[str] = [
186 "max_retries",
187 "config",
188 "_pool_connections",
189 "_pool_maxsize",
190 "_pool_block",
191 ]
193 max_retries: Retry
194 config: dict[str, Any]
195 proxy_manager: dict[str, Any]
196 _pool_connections: int
197 _pool_maxsize: int
198 _pool_block: bool
199 poolmanager: _PoolManager
201 def __init__(
202 self,
203 pool_connections: int = DEFAULT_POOLSIZE,
204 pool_maxsize: int = DEFAULT_POOLSIZE,
205 max_retries: int | Retry = DEFAULT_RETRIES,
206 pool_block: bool = DEFAULT_POOLBLOCK,
207 ) -> None:
208 if max_retries == DEFAULT_RETRIES:
209 self.max_retries = Retry(0, read=False)
210 else:
211 self.max_retries = Retry.from_int(max_retries)
212 self.config = {}
213 self.proxy_manager = {}
215 super().__init__()
217 self._pool_connections = pool_connections
218 self._pool_maxsize = pool_maxsize
219 self._pool_block = pool_block
221 self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
223 def __getstate__(self) -> dict[str, Any]:
224 return {attr: getattr(self, attr, None) for attr in self.__attrs__}
226 def __setstate__(self, state: dict[str, Any]) -> None:
227 # Can't handle by adding 'proxy_manager' to self.__attrs__ because
228 # self.poolmanager uses a lambda function, which isn't pickleable.
229 self.proxy_manager = {}
230 self.config = {}
232 for attr, value in state.items():
233 setattr(self, attr, value)
235 self.init_poolmanager(
236 self._pool_connections, self._pool_maxsize, block=self._pool_block
237 )
239 def init_poolmanager(
240 self,
241 connections: int,
242 maxsize: int,
243 block: bool = DEFAULT_POOLBLOCK,
244 **pool_kwargs: Any,
245 ) -> None:
246 """Initializes a urllib3 PoolManager.
248 This method should not be called from user code, and is only
249 exposed for use when subclassing the
250 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
252 :param connections: The number of urllib3 connection pools to cache.
253 :param maxsize: The maximum number of connections to save in the pool.
254 :param block: Block when no free connections are available.
255 :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
256 """
257 # save these values for pickling
258 self._pool_connections = connections
259 self._pool_maxsize = maxsize
260 self._pool_block = block
262 self.poolmanager = PoolManager(
263 num_pools=connections,
264 maxsize=maxsize,
265 block=block,
266 **pool_kwargs,
267 )
269 def proxy_manager_for(self, proxy: str, **proxy_kwargs: Any) -> Any:
270 """Return urllib3 ProxyManager for the given proxy.
272 This method should not be called from user code, and is only
273 exposed for use when subclassing the
274 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
276 :param proxy: The proxy to return a urllib3 ProxyManager for.
277 :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
278 :returns: ProxyManager
279 :rtype: urllib3.ProxyManager
280 """
281 if proxy in self.proxy_manager:
282 manager = self.proxy_manager[proxy]
283 elif proxy.lower().startswith("socks"):
284 username, password = get_auth_from_url(proxy)
285 manager = self.proxy_manager[proxy] = SOCKSProxyManager(
286 proxy,
287 username=username,
288 password=password,
289 num_pools=self._pool_connections,
290 maxsize=self._pool_maxsize,
291 block=self._pool_block,
292 **proxy_kwargs,
293 )
294 else:
295 proxy_headers = self.proxy_headers(proxy)
296 manager = self.proxy_manager[proxy] = proxy_from_url(
297 proxy,
298 proxy_headers=proxy_headers,
299 num_pools=self._pool_connections,
300 maxsize=self._pool_maxsize,
301 block=self._pool_block,
302 **proxy_kwargs,
303 )
305 return manager
307 def cert_verify(
308 self, conn: Any, url: str, verify: _t.VerifyType, cert: _t.CertType
309 ) -> None:
310 """Verify a SSL certificate. This method should not be called from user
311 code, and is only exposed for use when subclassing the
312 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
314 :param conn: The urllib3 connection object associated with the cert.
315 :param url: The requested URL.
316 :param verify: Either a boolean, in which case it controls whether we verify
317 the server's TLS certificate, or a string, in which case it must be a path
318 to a CA bundle to use
319 :param cert: The SSL certificate to verify.
320 """
321 if url.lower().startswith("https") and verify:
322 cert_loc = None
324 # Allow self-specified cert location.
325 if verify is not True:
326 cert_loc = verify
328 if not cert_loc:
329 cert_loc = DEFAULT_CA_BUNDLE_PATH
331 if not cert_loc or not os.path.exists(cert_loc):
332 raise OSError(
333 f"Could not find a suitable TLS CA certificate bundle, "
334 f"invalid path: {cert_loc}"
335 )
337 conn.cert_reqs = "CERT_REQUIRED"
339 if not os.path.isdir(cert_loc):
340 conn.ca_certs = cert_loc
341 else:
342 conn.ca_cert_dir = cert_loc
343 else:
344 conn.cert_reqs = "CERT_NONE"
345 conn.ca_certs = None
346 conn.ca_cert_dir = None
348 if cert:
349 if not isinstance(cert, basestring):
350 conn.cert_file = cert[0]
351 conn.key_file = cert[1]
352 else:
353 conn.cert_file = cert
354 conn.key_file = None
355 if conn.cert_file and not os.path.exists(conn.cert_file):
356 raise OSError(
357 f"Could not find the TLS certificate file, "
358 f"invalid path: {conn.cert_file}"
359 )
360 if conn.key_file and not os.path.exists(conn.key_file):
361 raise OSError(
362 f"Could not find the TLS key file, invalid path: {conn.key_file}"
363 )
365 def build_response(self, req: PreparedRequest, resp: Any) -> Response:
366 """Builds a :class:`Response <requests.Response>` object from a urllib3
367 response. This should not be called from user code, and is only exposed
368 for use when subclassing the
369 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`
371 :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.
372 :param resp: The urllib3 response object.
373 :rtype: requests.Response
374 """
375 assert _is_prepared(req)
376 response = Response()
378 # Fallback to None if there's no status_code, for whatever reason.
379 response.status_code = getattr(resp, "status", None) # type: ignore[assignment]
381 # Make headers case-insensitive.
382 response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
384 # Set encoding.
385 response.encoding = get_encoding_from_headers(response.headers)
386 response.raw = resp
387 response.reason = response.raw.reason
389 if isinstance(req.url, bytes):
390 response.url = req.url.decode("utf-8")
391 else:
392 response.url = req.url
394 # Add new cookies from the server.
395 extract_cookies_to_jar(response.cookies, req, resp)
397 # Give the Response some context.
398 response.request = req
399 response.connection = self
401 return response
403 def build_connection_pool_key_attributes(
404 self, request: PreparedRequest, verify: _t.VerifyType, cert: _t.CertType = None
405 ) -> tuple[dict[str, Any], dict[str, Any]]:
406 """Build the PoolKey attributes used by urllib3 to return a connection.
408 This looks at the PreparedRequest, the user-specified verify value,
409 and the value of the cert parameter to determine what PoolKey values
410 to use to select a connection from a given urllib3 Connection Pool.
412 The SSL related pool key arguments are not consistently set. As of
413 this writing, use the following to determine what keys may be in that
414 dictionary:
416 * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the
417 default Requests SSL Context
418 * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but
419 ``"cert_reqs"`` will be set
420 * If ``verify`` is a string, (i.e., it is a user-specified trust bundle)
421 ``"ca_certs"`` will be set if the string is not a directory recognized
422 by :py:func:`os.path.isdir`, otherwise ``"ca_cert_dir"`` will be
423 set.
424 * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If
425 ``"cert"`` is a tuple with a second item, ``"key_file"`` will also
426 be present
428 To override these settings, one may subclass this class, call this
429 method and use the above logic to change parameters as desired. For
430 example, if one wishes to use a custom :py:class:`ssl.SSLContext` one
431 must both set ``"ssl_context"`` and based on what else they require,
432 alter the other keys to ensure the desired behaviour.
434 :param request:
435 The PreparedRequest being sent over the connection.
436 :type request:
437 :class:`~requests.models.PreparedRequest`
438 :param verify:
439 Either a boolean, in which case it controls whether
440 we verify the server's TLS certificate, or a string, in which case it
441 must be a path to a CA bundle to use.
442 :param cert:
443 (optional) Any user-provided SSL certificate for client
444 authentication (a.k.a., mTLS). This may be a string (i.e., just
445 the path to a file which holds both certificate and key) or a
446 tuple of length 2 with the certificate file path and key file
447 path.
448 :returns:
449 A tuple of two dictionaries. The first is the "host parameters"
450 portion of the Pool Key including scheme, hostname, and port. The
451 second is a dictionary of SSLContext related parameters.
452 """
453 return _urllib3_request_context(request, verify, cert, self.poolmanager)
455 def get_connection_with_tls_context(
456 self,
457 request: PreparedRequest,
458 verify: _t.VerifyType,
459 proxies: dict[str, str] | None = None,
460 cert: _t.CertType = None,
461 ) -> HTTPConnectionPool:
462 """Returns a urllib3 connection for the given request and TLS settings.
463 This should not be called from user code, and is only exposed for use
464 when subclassing the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
466 :param request:
467 The :class:`PreparedRequest <PreparedRequest>` object to be sent
468 over the connection.
469 :param verify:
470 Either a boolean, in which case it controls whether we verify the
471 server's TLS certificate, or a string, in which case it must be a
472 path to a CA bundle to use.
473 :param proxies:
474 (optional) The proxies dictionary to apply to the request.
475 :param cert:
476 (optional) Any user-provided SSL certificate to be used for client
477 authentication (a.k.a., mTLS).
478 :rtype:
479 urllib3.HTTPConnectionPool
480 """
481 assert _is_prepared(request)
483 proxy = select_proxy(request.url, proxies)
484 try:
485 host_params, pool_kwargs = self.build_connection_pool_key_attributes(
486 request,
487 verify,
488 cert,
489 )
490 except ValueError as e:
491 raise InvalidURL(e, request=request)
492 if proxy:
493 proxy = prepend_scheme_if_needed(proxy, "http")
494 proxy_url = parse_url(proxy)
495 if not proxy_url.host:
496 raise InvalidProxyURL(
497 "Please check proxy URL. It is malformed "
498 "and could be missing the host."
499 )
500 proxy_manager = self.proxy_manager_for(proxy)
501 conn = proxy_manager.connection_from_host(
502 **host_params, pool_kwargs=pool_kwargs
503 )
504 else:
505 # Only scheme should be lower case
506 conn = self.poolmanager.connection_from_host(
507 **host_params, pool_kwargs=pool_kwargs
508 )
510 return conn
512 def get_connection(
513 self, url: str, proxies: dict[str, str] | None = None
514 ) -> HTTPConnectionPool:
515 """DEPRECATED: Users should move to `get_connection_with_tls_context`
516 for all subclasses of HTTPAdapter using Requests>=2.32.2.
518 Returns a urllib3 connection for the given URL. This should not be
519 called from user code, and is only exposed for use when subclassing the
520 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
522 :param url: The URL to connect to.
523 :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
524 :rtype: urllib3.HTTPConnectionPool
525 """
526 warnings.warn(
527 (
528 "`get_connection` has been deprecated in favor of "
529 "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses "
530 "will need to migrate for Requests>=2.32.2. Please see "
531 "https://github.com/psf/requests/pull/6710 for more details."
532 ),
533 DeprecationWarning,
534 )
535 proxy = select_proxy(url, proxies)
537 if proxy:
538 proxy = prepend_scheme_if_needed(proxy, "http")
539 proxy_url = parse_url(proxy)
540 if not proxy_url.host:
541 raise InvalidProxyURL(
542 "Please check proxy URL. It is malformed "
543 "and could be missing the host."
544 )
545 proxy_manager = self.proxy_manager_for(proxy)
546 conn = proxy_manager.connection_from_url(url)
547 else:
548 # Only scheme should be lower case
549 parsed = urlparse(url)
550 url = parsed.geturl()
551 conn = self.poolmanager.connection_from_url(url)
553 return conn
555 def close(self) -> None:
556 """Disposes of any internal state.
558 Currently, this closes the PoolManager and any active ProxyManager,
559 which closes any pooled connections.
560 """
561 self.poolmanager.clear()
562 for proxy in self.proxy_manager.values():
563 proxy.clear()
565 def request_url(
566 self, request: PreparedRequest, proxies: dict[str, str] | None
567 ) -> str:
568 """Obtain the url to use when making the final request.
570 If the message is being sent through a HTTP proxy, the full URL has to
571 be used. Otherwise, we should only use the path portion of the URL.
573 This should not be called from user code, and is only exposed for use
574 when subclassing the
575 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
577 :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
578 :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
579 :rtype: str
580 """
581 assert _is_prepared(request)
583 proxy = select_proxy(request.url, proxies)
584 scheme = urlparse(request.url).scheme
586 is_proxied_http_request = proxy and scheme != "https"
587 using_socks_proxy = False
588 if proxy:
589 proxy_scheme = urlparse(proxy).scheme.lower()
590 using_socks_proxy = proxy_scheme.startswith("socks")
592 url = request.path_url
594 if is_proxied_http_request and not using_socks_proxy:
595 url = urldefragauth(request.url)
597 return url
599 def add_headers(self, request: PreparedRequest, **kwargs: Any) -> None:
600 """Add any headers needed by the connection. As of v2.0 this does
601 nothing by default, but is left for overriding by users that subclass
602 the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
604 This should not be called from user code, and is only exposed for use
605 when subclassing the
606 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
608 :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to.
609 :param kwargs: The keyword arguments from the call to send().
610 """
611 pass
613 def proxy_headers(self, proxy: str) -> dict[str, str]:
614 """Returns a dictionary of the headers to add to any request sent
615 through a proxy. This works with urllib3 magic to ensure that they are
616 correctly sent to the proxy, rather than in a tunnelled request if
617 CONNECT is being used.
619 This should not be called from user code, and is only exposed for use
620 when subclassing the
621 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
623 :param proxy: The url of the proxy being used for this request.
624 :rtype: dict
625 """
626 headers: dict[str, str] = {}
627 username, password = get_auth_from_url(proxy)
629 if username:
630 headers["Proxy-Authorization"] = _basic_auth_str(username, password)
632 return headers
634 def send(
635 self,
636 request: PreparedRequest,
637 stream: bool = False,
638 timeout: _t.TimeoutType = None,
639 verify: _t.VerifyType = True,
640 cert: _t.CertType = None,
641 proxies: dict[str, str] | None = None,
642 ) -> Response:
643 """Sends PreparedRequest object. Returns Response object.
645 :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
646 :param stream: (optional) Whether to stream the request content.
647 :param timeout: (optional) How long to wait for the server to send
648 data before giving up, as a float, or a :ref:`(connect timeout,
649 read timeout) <timeouts>` tuple.
650 :type timeout: float or tuple or urllib3 Timeout object
651 :param verify: (optional) Either a boolean, in which case it controls whether
652 we verify the server's TLS certificate, or a string, in which case it
653 must be a path to a CA bundle to use
654 :param cert: (optional) Any user-provided SSL certificate to be trusted.
655 :param proxies: (optional) The proxies dictionary to apply to the request.
656 :rtype: requests.Response
657 """
659 assert _is_prepared(request)
661 try:
662 conn = self.get_connection_with_tls_context(
663 request, verify, proxies=proxies, cert=cert
664 )
665 except LocationValueError as e:
666 raise InvalidURL(e, request=request)
668 self.cert_verify(conn, request.url, verify, cert)
669 url = self.request_url(request, proxies)
670 self.add_headers(
671 request,
672 stream=stream,
673 timeout=timeout,
674 verify=verify,
675 cert=cert,
676 proxies=proxies,
677 )
679 chunked = not (request.body is None or "Content-Length" in request.headers)
681 if isinstance(timeout, tuple):
682 try:
683 connect, read = timeout
684 resolved_timeout = TimeoutSauce(connect=connect, read=read)
685 except ValueError:
686 raise ValueError(
687 f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
688 f"or a single float to set both timeouts to the same value."
689 )
690 elif isinstance(timeout, TimeoutSauce):
691 resolved_timeout = timeout
692 else:
693 resolved_timeout = TimeoutSauce(connect=timeout, read=timeout)
695 try:
696 resp = conn.urlopen(
697 method=request.method,
698 url=url,
699 body=request.body, # type: ignore[arg-type] # urllib3 stubs don't accept Iterable[bytes | str]
700 headers=request.headers, # type: ignore[arg-type] # urllib3#3072
701 redirect=False,
702 assert_same_host=False,
703 preload_content=False,
704 decode_content=False,
705 retries=self.max_retries,
706 timeout=resolved_timeout,
707 chunked=chunked,
708 )
710 except (ProtocolError, OSError) as err:
711 raise ConnectionError(err, request=request)
713 except MaxRetryError as e:
714 if isinstance(e.reason, ConnectTimeoutError):
715 # TODO: Remove this in 3.0.0: see #2811
716 if not isinstance(e.reason, NewConnectionError):
717 raise ConnectTimeout(e, request=request)
719 if isinstance(e.reason, ResponseError):
720 raise RetryError(e, request=request)
722 if isinstance(e.reason, _ProxyError):
723 raise ProxyError(e, request=request)
725 if isinstance(e.reason, _SSLError):
726 # This branch is for urllib3 v1.22 and later.
727 raise SSLError(e, request=request)
729 raise ConnectionError(e, request=request)
731 except ClosedPoolError as e:
732 raise ConnectionError(e, request=request)
734 except _ProxyError as e:
735 raise ProxyError(e)
737 except (_SSLError, _HTTPError) as e:
738 if isinstance(e, _SSLError):
739 # This branch is for urllib3 versions earlier than v1.22
740 raise SSLError(e, request=request)
741 elif isinstance(e, ReadTimeoutError):
742 raise ReadTimeout(e, request=request)
743 elif isinstance(e, _InvalidHeader):
744 raise InvalidHeader(e, request=request)
745 else:
746 raise
748 return self.build_response(request, resp)