Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/requests/adapters.py: 22%

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

238 statements  

1""" 

2requests.adapters 

3~~~~~~~~~~~~~~~~~ 

4 

5This module contains the transport adapters that Requests uses to define 

6and maintain connections. 

7""" 

8 

9import os.path 

10import socket # noqa: F401 

11import typing 

12import warnings 

13 

14from urllib3.exceptions import ( 

15 ClosedPoolError, 

16 ConnectTimeoutError, 

17 LocationValueError, 

18 MaxRetryError, 

19 NewConnectionError, 

20 ProtocolError, 

21 ReadTimeoutError, 

22 ResponseError, 

23) 

24from urllib3.exceptions import HTTPError as _HTTPError 

25from urllib3.exceptions import InvalidHeader as _InvalidHeader 

26from urllib3.exceptions import ProxyError as _ProxyError 

27from urllib3.exceptions import SSLError as _SSLError 

28from urllib3.poolmanager import PoolManager, proxy_from_url 

29from urllib3.util import Timeout as TimeoutSauce 

30from urllib3.util import parse_url 

31from urllib3.util.retry import Retry 

32 

33from .auth import _basic_auth_str 

34from .compat import basestring, urlparse 

35from .cookies import extract_cookies_to_jar 

36from .exceptions import ( 

37 ConnectionError, 

38 ConnectTimeout, 

39 InvalidHeader, 

40 InvalidProxyURL, 

41 InvalidSchema, 

42 InvalidURL, 

43 ProxyError, 

44 ReadTimeout, 

45 RetryError, 

46 SSLError, 

47) 

48from .models import Response 

49from .structures import CaseInsensitiveDict 

50from .utils import ( 

51 DEFAULT_CA_BUNDLE_PATH, 

52 get_auth_from_url, 

53 get_encoding_from_headers, 

54 prepend_scheme_if_needed, 

55 select_proxy, 

56 urldefragauth, 

57) 

58 

59try: 

60 from urllib3.contrib.socks import SOCKSProxyManager 

61except ImportError: 

62 

63 def SOCKSProxyManager(*args, **kwargs): 

64 raise InvalidSchema("Missing dependencies for SOCKS support.") 

65 

66 

67if typing.TYPE_CHECKING: 

68 from .models import PreparedRequest 

69 

70 

71DEFAULT_POOLBLOCK = False 

72DEFAULT_POOLSIZE = 10 

73DEFAULT_RETRIES = 0 

74DEFAULT_POOL_TIMEOUT = None 

75 

76 

77def _urllib3_request_context( 

78 request: "PreparedRequest", 

79 verify: "bool | str | None", 

80 client_cert: "tuple[str, str] | str | None", 

81 poolmanager: "PoolManager", 

82) -> "(dict[str, typing.Any], dict[str, typing.Any])": 

83 host_params = {} 

84 pool_kwargs = {} 

85 parsed_request_url = urlparse(request.url) 

86 scheme = parsed_request_url.scheme.lower() 

87 port = parsed_request_url.port 

88 

89 cert_reqs = "CERT_REQUIRED" 

90 if verify is False: 

91 cert_reqs = "CERT_NONE" 

92 elif isinstance(verify, str): 

93 if not os.path.isdir(verify): 

94 pool_kwargs["ca_certs"] = verify 

95 else: 

96 pool_kwargs["ca_cert_dir"] = verify 

97 pool_kwargs["cert_reqs"] = cert_reqs 

98 if client_cert is not None: 

99 if isinstance(client_cert, tuple) and len(client_cert) == 2: 

100 pool_kwargs["cert_file"] = client_cert[0] 

101 pool_kwargs["key_file"] = client_cert[1] 

102 else: 

103 # According to our docs, we allow users to specify just the client 

104 # cert path 

105 pool_kwargs["cert_file"] = client_cert 

106 host_params = { 

107 "scheme": scheme, 

108 "host": parsed_request_url.hostname, 

109 "port": port, 

110 } 

111 return host_params, pool_kwargs 

112 

113 

114class BaseAdapter: 

115 """The Base Transport Adapter""" 

116 

117 def __init__(self): 

118 super().__init__() 

119 

120 def send( 

121 self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None 

122 ): 

123 """Sends PreparedRequest object. Returns Response object. 

124 

125 :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. 

126 :param stream: (optional) Whether to stream the request content. 

127 :param timeout: (optional) How long to wait for the server to send 

128 data before giving up, as a float, or a :ref:`(connect timeout, 

129 read timeout) <timeouts>` tuple. 

130 :type timeout: float or tuple 

131 :param verify: (optional) Either a boolean, in which case it controls whether we verify 

132 the server's TLS certificate, or a string, in which case it must be a path 

133 to a CA bundle to use 

134 :param cert: (optional) Any user-provided SSL certificate to be trusted. 

135 :param proxies: (optional) The proxies dictionary to apply to the request. 

136 """ 

137 raise NotImplementedError 

138 

139 def close(self): 

140 """Cleans up adapter specific items.""" 

141 raise NotImplementedError 

142 

143 

144class HTTPAdapter(BaseAdapter): 

145 """The built-in HTTP Adapter for urllib3. 

146 

147 Provides a general-case interface for Requests sessions to contact HTTP and 

148 HTTPS urls by implementing the Transport Adapter interface. This class will 

149 usually be created by the :class:`Session <Session>` class under the 

150 covers. 

151 

152 :param pool_connections: The number of urllib3 connection pools to cache. 

153 :param pool_maxsize: The maximum number of connections to save in the pool. 

154 :param max_retries: The maximum number of retries each connection 

155 should attempt. Note, this applies only to failed DNS lookups, socket 

156 connections and connection timeouts, never to requests where data has 

157 made it to the server. By default, Requests does not retry failed 

158 connections. If you need granular control over the conditions under 

159 which we retry a request, import urllib3's ``Retry`` class and pass 

160 that instead. 

161 :param pool_block: Whether the connection pool should block for connections. 

162 

163 Usage:: 

164 

165 >>> import requests 

166 >>> s = requests.Session() 

167 >>> a = requests.adapters.HTTPAdapter(max_retries=3) 

168 >>> s.mount('http://', a) 

169 """ 

170 

171 __attrs__ = [ 

172 "max_retries", 

173 "config", 

174 "_pool_connections", 

175 "_pool_maxsize", 

176 "_pool_block", 

177 ] 

178 

179 def __init__( 

180 self, 

181 pool_connections=DEFAULT_POOLSIZE, 

182 pool_maxsize=DEFAULT_POOLSIZE, 

183 max_retries=DEFAULT_RETRIES, 

184 pool_block=DEFAULT_POOLBLOCK, 

185 ): 

186 if max_retries == DEFAULT_RETRIES: 

187 self.max_retries = Retry(0, read=False) 

188 else: 

189 self.max_retries = Retry.from_int(max_retries) 

190 self.config = {} 

191 self.proxy_manager = {} 

192 

193 super().__init__() 

194 

195 self._pool_connections = pool_connections 

196 self._pool_maxsize = pool_maxsize 

197 self._pool_block = pool_block 

198 

199 self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) 

200 

201 def __getstate__(self): 

202 return {attr: getattr(self, attr, None) for attr in self.__attrs__} 

203 

204 def __setstate__(self, state): 

205 # Can't handle by adding 'proxy_manager' to self.__attrs__ because 

206 # self.poolmanager uses a lambda function, which isn't pickleable. 

207 self.proxy_manager = {} 

208 self.config = {} 

209 

210 for attr, value in state.items(): 

211 setattr(self, attr, value) 

212 

213 self.init_poolmanager( 

214 self._pool_connections, self._pool_maxsize, block=self._pool_block 

215 ) 

216 

217 def init_poolmanager( 

218 self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs 

219 ): 

220 """Initializes a urllib3 PoolManager. 

221 

222 This method should not be called from user code, and is only 

223 exposed for use when subclassing the 

224 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

225 

226 :param connections: The number of urllib3 connection pools to cache. 

227 :param maxsize: The maximum number of connections to save in the pool. 

228 :param block: Block when no free connections are available. 

229 :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. 

230 """ 

231 # save these values for pickling 

232 self._pool_connections = connections 

233 self._pool_maxsize = maxsize 

234 self._pool_block = block 

235 

236 self.poolmanager = PoolManager( 

237 num_pools=connections, 

238 maxsize=maxsize, 

239 block=block, 

240 **pool_kwargs, 

241 ) 

242 

243 def proxy_manager_for(self, proxy, **proxy_kwargs): 

244 """Return urllib3 ProxyManager for the given proxy. 

245 

246 This method should not be called from user code, and is only 

247 exposed for use when subclassing the 

248 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

249 

250 :param proxy: The proxy to return a urllib3 ProxyManager for. 

251 :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. 

252 :returns: ProxyManager 

253 :rtype: urllib3.ProxyManager 

254 """ 

255 if proxy in self.proxy_manager: 

256 manager = self.proxy_manager[proxy] 

257 elif proxy.lower().startswith("socks"): 

258 username, password = get_auth_from_url(proxy) 

259 manager = self.proxy_manager[proxy] = SOCKSProxyManager( 

260 proxy, 

261 username=username, 

262 password=password, 

263 num_pools=self._pool_connections, 

264 maxsize=self._pool_maxsize, 

265 block=self._pool_block, 

266 **proxy_kwargs, 

267 ) 

268 else: 

269 proxy_headers = self.proxy_headers(proxy) 

270 manager = self.proxy_manager[proxy] = proxy_from_url( 

271 proxy, 

272 proxy_headers=proxy_headers, 

273 num_pools=self._pool_connections, 

274 maxsize=self._pool_maxsize, 

275 block=self._pool_block, 

276 **proxy_kwargs, 

277 ) 

278 

279 return manager 

280 

281 def cert_verify(self, conn, url, verify, cert): 

282 """Verify a SSL certificate. This method should not be called from user 

283 code, and is only exposed for use when subclassing the 

284 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

285 

286 :param conn: The urllib3 connection object associated with the cert. 

287 :param url: The requested URL. 

288 :param verify: Either a boolean, in which case it controls whether we verify 

289 the server's TLS certificate, or a string, in which case it must be a path 

290 to a CA bundle to use 

291 :param cert: The SSL certificate to verify. 

292 """ 

293 if url.lower().startswith("https") and verify: 

294 cert_loc = None 

295 

296 # Allow self-specified cert location. 

297 if verify is not True: 

298 cert_loc = verify 

299 

300 if not cert_loc: 

301 cert_loc = DEFAULT_CA_BUNDLE_PATH 

302 

303 if not cert_loc or not os.path.exists(cert_loc): 

304 raise OSError( 

305 f"Could not find a suitable TLS CA certificate bundle, " 

306 f"invalid path: {cert_loc}" 

307 ) 

308 

309 conn.cert_reqs = "CERT_REQUIRED" 

310 

311 if not os.path.isdir(cert_loc): 

312 conn.ca_certs = cert_loc 

313 else: 

314 conn.ca_cert_dir = cert_loc 

315 else: 

316 conn.cert_reqs = "CERT_NONE" 

317 conn.ca_certs = None 

318 conn.ca_cert_dir = None 

319 

320 if cert: 

321 if not isinstance(cert, basestring): 

322 conn.cert_file = cert[0] 

323 conn.key_file = cert[1] 

324 else: 

325 conn.cert_file = cert 

326 conn.key_file = None 

327 if conn.cert_file and not os.path.exists(conn.cert_file): 

328 raise OSError( 

329 f"Could not find the TLS certificate file, " 

330 f"invalid path: {conn.cert_file}" 

331 ) 

332 if conn.key_file and not os.path.exists(conn.key_file): 

333 raise OSError( 

334 f"Could not find the TLS key file, invalid path: {conn.key_file}" 

335 ) 

336 

337 def build_response(self, req, resp): 

338 """Builds a :class:`Response <requests.Response>` object from a urllib3 

339 response. This should not be called from user code, and is only exposed 

340 for use when subclassing the 

341 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>` 

342 

343 :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response. 

344 :param resp: The urllib3 response object. 

345 :rtype: requests.Response 

346 """ 

347 response = Response() 

348 

349 # Fallback to None if there's no status_code, for whatever reason. 

350 response.status_code = getattr(resp, "status", None) 

351 

352 # Make headers case-insensitive. 

353 response.headers = CaseInsensitiveDict(getattr(resp, "headers", {})) 

354 

355 # Set encoding. 

356 response.encoding = get_encoding_from_headers(response.headers) 

357 response.raw = resp 

358 response.reason = response.raw.reason 

359 

360 if isinstance(req.url, bytes): 

361 response.url = req.url.decode("utf-8") 

362 else: 

363 response.url = req.url 

364 

365 # Add new cookies from the server. 

366 extract_cookies_to_jar(response.cookies, req, resp) 

367 

368 # Give the Response some context. 

369 response.request = req 

370 response.connection = self 

371 

372 return response 

373 

374 def build_connection_pool_key_attributes(self, request, verify, cert=None): 

375 """Build the PoolKey attributes used by urllib3 to return a connection. 

376 

377 This looks at the PreparedRequest, the user-specified verify value, 

378 and the value of the cert parameter to determine what PoolKey values 

379 to use to select a connection from a given urllib3 Connection Pool. 

380 

381 The SSL related pool key arguments are not consistently set. As of 

382 this writing, use the following to determine what keys may be in that 

383 dictionary: 

384 

385 * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the 

386 default Requests SSL Context 

387 * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but 

388 ``"cert_reqs"`` will be set 

389 * If ``verify`` is a string, (i.e., it is a user-specified trust bundle) 

390 ``"ca_certs"`` will be set if the string is not a directory recognized 

391 by :py:func:`os.path.isdir`, otherwise ``"ca_cert_dir"`` will be 

392 set. 

393 * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If 

394 ``"cert"`` is a tuple with a second item, ``"key_file"`` will also 

395 be present 

396 

397 To override these settings, one may subclass this class, call this 

398 method and use the above logic to change parameters as desired. For 

399 example, if one wishes to use a custom :py:class:`ssl.SSLContext` one 

400 must both set ``"ssl_context"`` and based on what else they require, 

401 alter the other keys to ensure the desired behaviour. 

402 

403 :param request: 

404 The PreparedReqest being sent over the connection. 

405 :type request: 

406 :class:`~requests.models.PreparedRequest` 

407 :param verify: 

408 Either a boolean, in which case it controls whether 

409 we verify the server's TLS certificate, or a string, in which case it 

410 must be a path to a CA bundle to use. 

411 :param cert: 

412 (optional) Any user-provided SSL certificate for client 

413 authentication (a.k.a., mTLS). This may be a string (i.e., just 

414 the path to a file which holds both certificate and key) or a 

415 tuple of length 2 with the certificate file path and key file 

416 path. 

417 :returns: 

418 A tuple of two dictionaries. The first is the "host parameters" 

419 portion of the Pool Key including scheme, hostname, and port. The 

420 second is a dictionary of SSLContext related parameters. 

421 """ 

422 return _urllib3_request_context(request, verify, cert, self.poolmanager) 

423 

424 def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None): 

425 """Returns a urllib3 connection for the given request and TLS settings. 

426 This should not be called from user code, and is only exposed for use 

427 when subclassing the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

428 

429 :param request: 

430 The :class:`PreparedRequest <PreparedRequest>` object to be sent 

431 over the connection. 

432 :param verify: 

433 Either a boolean, in which case it controls whether we verify the 

434 server's TLS certificate, or a string, in which case it must be a 

435 path to a CA bundle to use. 

436 :param proxies: 

437 (optional) The proxies dictionary to apply to the request. 

438 :param cert: 

439 (optional) Any user-provided SSL certificate to be used for client 

440 authentication (a.k.a., mTLS). 

441 :rtype: 

442 urllib3.ConnectionPool 

443 """ 

444 proxy = select_proxy(request.url, proxies) 

445 try: 

446 host_params, pool_kwargs = self.build_connection_pool_key_attributes( 

447 request, 

448 verify, 

449 cert, 

450 ) 

451 except ValueError as e: 

452 raise InvalidURL(e, request=request) 

453 if proxy: 

454 proxy = prepend_scheme_if_needed(proxy, "http") 

455 proxy_url = parse_url(proxy) 

456 if not proxy_url.host: 

457 raise InvalidProxyURL( 

458 "Please check proxy URL. It is malformed " 

459 "and could be missing the host." 

460 ) 

461 proxy_manager = self.proxy_manager_for(proxy) 

462 conn = proxy_manager.connection_from_host( 

463 **host_params, pool_kwargs=pool_kwargs 

464 ) 

465 else: 

466 # Only scheme should be lower case 

467 conn = self.poolmanager.connection_from_host( 

468 **host_params, pool_kwargs=pool_kwargs 

469 ) 

470 

471 return conn 

472 

473 def get_connection(self, url, proxies=None): 

474 """DEPRECATED: Users should move to `get_connection_with_tls_context` 

475 for all subclasses of HTTPAdapter using Requests>=2.32.2. 

476 

477 Returns a urllib3 connection for the given URL. This should not be 

478 called from user code, and is only exposed for use when subclassing the 

479 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

480 

481 :param url: The URL to connect to. 

482 :param proxies: (optional) A Requests-style dictionary of proxies used on this request. 

483 :rtype: urllib3.ConnectionPool 

484 """ 

485 warnings.warn( 

486 ( 

487 "`get_connection` has been deprecated in favor of " 

488 "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses " 

489 "will need to migrate for Requests>=2.32.2. Please see " 

490 "https://github.com/psf/requests/pull/6710 for more details." 

491 ), 

492 DeprecationWarning, 

493 ) 

494 proxy = select_proxy(url, proxies) 

495 

496 if proxy: 

497 proxy = prepend_scheme_if_needed(proxy, "http") 

498 proxy_url = parse_url(proxy) 

499 if not proxy_url.host: 

500 raise InvalidProxyURL( 

501 "Please check proxy URL. It is malformed " 

502 "and could be missing the host." 

503 ) 

504 proxy_manager = self.proxy_manager_for(proxy) 

505 conn = proxy_manager.connection_from_url(url) 

506 else: 

507 # Only scheme should be lower case 

508 parsed = urlparse(url) 

509 url = parsed.geturl() 

510 conn = self.poolmanager.connection_from_url(url) 

511 

512 return conn 

513 

514 def close(self): 

515 """Disposes of any internal state. 

516 

517 Currently, this closes the PoolManager and any active ProxyManager, 

518 which closes any pooled connections. 

519 """ 

520 self.poolmanager.clear() 

521 for proxy in self.proxy_manager.values(): 

522 proxy.clear() 

523 

524 def request_url(self, request, proxies): 

525 """Obtain the url to use when making the final request. 

526 

527 If the message is being sent through a HTTP proxy, the full URL has to 

528 be used. Otherwise, we should only use the path portion of the URL. 

529 

530 This should not be called from user code, and is only exposed for use 

531 when subclassing the 

532 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

533 

534 :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. 

535 :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. 

536 :rtype: str 

537 """ 

538 proxy = select_proxy(request.url, proxies) 

539 scheme = urlparse(request.url).scheme 

540 

541 is_proxied_http_request = proxy and scheme != "https" 

542 using_socks_proxy = False 

543 if proxy: 

544 proxy_scheme = urlparse(proxy).scheme.lower() 

545 using_socks_proxy = proxy_scheme.startswith("socks") 

546 

547 url = request.path_url 

548 if url.startswith("//"): # Don't confuse urllib3 

549 url = f"/{url.lstrip('/')}" 

550 

551 if is_proxied_http_request and not using_socks_proxy: 

552 url = urldefragauth(request.url) 

553 

554 return url 

555 

556 def add_headers(self, request, **kwargs): 

557 """Add any headers needed by the connection. As of v2.0 this does 

558 nothing by default, but is left for overriding by users that subclass 

559 the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

560 

561 This should not be called from user code, and is only exposed for use 

562 when subclassing the 

563 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

564 

565 :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to. 

566 :param kwargs: The keyword arguments from the call to send(). 

567 """ 

568 pass 

569 

570 def proxy_headers(self, proxy): 

571 """Returns a dictionary of the headers to add to any request sent 

572 through a proxy. This works with urllib3 magic to ensure that they are 

573 correctly sent to the proxy, rather than in a tunnelled request if 

574 CONNECT is being used. 

575 

576 This should not be called from user code, and is only exposed for use 

577 when subclassing the 

578 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

579 

580 :param proxy: The url of the proxy being used for this request. 

581 :rtype: dict 

582 """ 

583 headers = {} 

584 username, password = get_auth_from_url(proxy) 

585 

586 if username: 

587 headers["Proxy-Authorization"] = _basic_auth_str(username, password) 

588 

589 return headers 

590 

591 def send( 

592 self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None 

593 ): 

594 """Sends PreparedRequest object. Returns Response object. 

595 

596 :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. 

597 :param stream: (optional) Whether to stream the request content. 

598 :param timeout: (optional) How long to wait for the server to send 

599 data before giving up, as a float, or a :ref:`(connect timeout, 

600 read timeout) <timeouts>` tuple. 

601 :type timeout: float or tuple or urllib3 Timeout object 

602 :param verify: (optional) Either a boolean, in which case it controls whether 

603 we verify the server's TLS certificate, or a string, in which case it 

604 must be a path to a CA bundle to use 

605 :param cert: (optional) Any user-provided SSL certificate to be trusted. 

606 :param proxies: (optional) The proxies dictionary to apply to the request. 

607 :rtype: requests.Response 

608 """ 

609 

610 try: 

611 conn = self.get_connection_with_tls_context( 

612 request, verify, proxies=proxies, cert=cert 

613 ) 

614 except LocationValueError as e: 

615 raise InvalidURL(e, request=request) 

616 

617 self.cert_verify(conn, request.url, verify, cert) 

618 url = self.request_url(request, proxies) 

619 self.add_headers( 

620 request, 

621 stream=stream, 

622 timeout=timeout, 

623 verify=verify, 

624 cert=cert, 

625 proxies=proxies, 

626 ) 

627 

628 chunked = not (request.body is None or "Content-Length" in request.headers) 

629 

630 if isinstance(timeout, tuple): 

631 try: 

632 connect, read = timeout 

633 timeout = TimeoutSauce(connect=connect, read=read) 

634 except ValueError: 

635 raise ValueError( 

636 f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " 

637 f"or a single float to set both timeouts to the same value." 

638 ) 

639 elif isinstance(timeout, TimeoutSauce): 

640 pass 

641 else: 

642 timeout = TimeoutSauce(connect=timeout, read=timeout) 

643 

644 try: 

645 resp = conn.urlopen( 

646 method=request.method, 

647 url=url, 

648 body=request.body, 

649 headers=request.headers, 

650 redirect=False, 

651 assert_same_host=False, 

652 preload_content=False, 

653 decode_content=False, 

654 retries=self.max_retries, 

655 timeout=timeout, 

656 chunked=chunked, 

657 ) 

658 

659 except (ProtocolError, OSError) as err: 

660 raise ConnectionError(err, request=request) 

661 

662 except MaxRetryError as e: 

663 if isinstance(e.reason, ConnectTimeoutError): 

664 # TODO: Remove this in 3.0.0: see #2811 

665 if not isinstance(e.reason, NewConnectionError): 

666 raise ConnectTimeout(e, request=request) 

667 

668 if isinstance(e.reason, ResponseError): 

669 raise RetryError(e, request=request) 

670 

671 if isinstance(e.reason, _ProxyError): 

672 raise ProxyError(e, request=request) 

673 

674 if isinstance(e.reason, _SSLError): 

675 # This branch is for urllib3 v1.22 and later. 

676 raise SSLError(e, request=request) 

677 

678 raise ConnectionError(e, request=request) 

679 

680 except ClosedPoolError as e: 

681 raise ConnectionError(e, request=request) 

682 

683 except _ProxyError as e: 

684 raise ProxyError(e) 

685 

686 except (_SSLError, _HTTPError) as e: 

687 if isinstance(e, _SSLError): 

688 # This branch is for urllib3 versions earlier than v1.22 

689 raise SSLError(e, request=request) 

690 elif isinstance(e, ReadTimeoutError): 

691 raise ReadTimeout(e, request=request) 

692 elif isinstance(e, _InvalidHeader): 

693 raise InvalidHeader(e, request=request) 

694 else: 

695 raise 

696 

697 return self.build_response(request, resp)