Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py: 20%

347 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-25 06:37 +0000

1from __future__ import absolute_import 

2 

3import errno 

4import logging 

5import re 

6import socket 

7import sys 

8import warnings 

9from socket import error as SocketError 

10from socket import timeout as SocketTimeout 

11 

12from .connection import ( 

13 BaseSSLError, 

14 BrokenPipeError, 

15 DummyConnection, 

16 HTTPConnection, 

17 HTTPException, 

18 HTTPSConnection, 

19 VerifiedHTTPSConnection, 

20 port_by_scheme, 

21) 

22from .exceptions import ( 

23 ClosedPoolError, 

24 EmptyPoolError, 

25 HeaderParsingError, 

26 HostChangedError, 

27 InsecureRequestWarning, 

28 LocationValueError, 

29 MaxRetryError, 

30 NewConnectionError, 

31 ProtocolError, 

32 ProxyError, 

33 ReadTimeoutError, 

34 SSLError, 

35 TimeoutError, 

36) 

37from .packages import six 

38from .packages.six.moves import queue 

39from .request import RequestMethods 

40from .response import HTTPResponse 

41from .util.connection import is_connection_dropped 

42from .util.proxy import connection_requires_http_tunnel 

43from .util.queue import LifoQueue 

44from .util.request import set_file_position 

45from .util.response import assert_header_parsing 

46from .util.retry import Retry 

47from .util.ssl_match_hostname import CertificateError 

48from .util.timeout import Timeout 

49from .util.url import Url, _encode_target 

50from .util.url import _normalize_host as normalize_host 

51from .util.url import get_host, parse_url 

52 

53try: # Platform-specific: Python 3 

54 import weakref 

55 

56 weakref_finalize = weakref.finalize 

57except AttributeError: # Platform-specific: Python 2 

58 from .packages.backports.weakref_finalize import weakref_finalize 

59 

60xrange = six.moves.xrange 

61 

62log = logging.getLogger(__name__) 

63 

64_Default = object() 

65 

66 

67# Pool objects 

68class ConnectionPool(object): 

69 """ 

70 Base class for all connection pools, such as 

71 :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. 

72 

73 .. note:: 

74 ConnectionPool.urlopen() does not normalize or percent-encode target URIs 

75 which is useful if your target server doesn't support percent-encoded 

76 target URIs. 

77 """ 

78 

79 scheme = None 

80 QueueCls = LifoQueue 

81 

82 def __init__(self, host, port=None): 

83 if not host: 

84 raise LocationValueError("No host specified.") 

85 

86 self.host = _normalize_host(host, scheme=self.scheme) 

87 self._proxy_host = host.lower() 

88 self.port = port 

89 

90 def __str__(self): 

91 return "%s(host=%r, port=%r)" % (type(self).__name__, self.host, self.port) 

92 

93 def __enter__(self): 

94 return self 

95 

96 def __exit__(self, exc_type, exc_val, exc_tb): 

97 self.close() 

98 # Return False to re-raise any potential exceptions 

99 return False 

100 

101 def close(self): 

102 """ 

103 Close all pooled connections and disable the pool. 

104 """ 

105 pass 

106 

107 

108# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 

109_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK} 

110 

111 

112class HTTPConnectionPool(ConnectionPool, RequestMethods): 

113 """ 

114 Thread-safe connection pool for one host. 

115 

116 :param host: 

117 Host used for this HTTP Connection (e.g. "localhost"), passed into 

118 :class:`http.client.HTTPConnection`. 

119 

120 :param port: 

121 Port used for this HTTP Connection (None is equivalent to 80), passed 

122 into :class:`http.client.HTTPConnection`. 

123 

124 :param strict: 

125 Causes BadStatusLine to be raised if the status line can't be parsed 

126 as a valid HTTP/1.0 or 1.1 status line, passed into 

127 :class:`http.client.HTTPConnection`. 

128 

129 .. note:: 

130 Only works in Python 2. This parameter is ignored in Python 3. 

131 

132 :param timeout: 

133 Socket timeout in seconds for each individual connection. This can 

134 be a float or integer, which sets the timeout for the HTTP request, 

135 or an instance of :class:`urllib3.util.Timeout` which gives you more 

136 fine-grained control over request timeouts. After the constructor has 

137 been parsed, this is always a `urllib3.util.Timeout` object. 

138 

139 :param maxsize: 

140 Number of connections to save that can be reused. More than 1 is useful 

141 in multithreaded situations. If ``block`` is set to False, more 

142 connections will be created but they will not be saved once they've 

143 been used. 

144 

145 :param block: 

146 If set to True, no more than ``maxsize`` connections will be used at 

147 a time. When no free connections are available, the call will block 

148 until a connection has been released. This is a useful side effect for 

149 particular multithreaded situations where one does not want to use more 

150 than maxsize connections per host to prevent flooding. 

151 

152 :param headers: 

153 Headers to include with all requests, unless other headers are given 

154 explicitly. 

155 

156 :param retries: 

157 Retry configuration to use by default with requests in this pool. 

158 

159 :param _proxy: 

160 Parsed proxy URL, should not be used directly, instead, see 

161 :class:`urllib3.ProxyManager` 

162 

163 :param _proxy_headers: 

164 A dictionary with proxy headers, should not be used directly, 

165 instead, see :class:`urllib3.ProxyManager` 

166 

167 :param \\**conn_kw: 

168 Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, 

169 :class:`urllib3.connection.HTTPSConnection` instances. 

170 """ 

171 

172 scheme = "http" 

173 ConnectionCls = HTTPConnection 

174 ResponseCls = HTTPResponse 

175 

176 def __init__( 

177 self, 

178 host, 

179 port=None, 

180 strict=False, 

181 timeout=Timeout.DEFAULT_TIMEOUT, 

182 maxsize=1, 

183 block=False, 

184 headers=None, 

185 retries=None, 

186 _proxy=None, 

187 _proxy_headers=None, 

188 _proxy_config=None, 

189 **conn_kw 

190 ): 

191 ConnectionPool.__init__(self, host, port) 

192 RequestMethods.__init__(self, headers) 

193 

194 self.strict = strict 

195 

196 if not isinstance(timeout, Timeout): 

197 timeout = Timeout.from_float(timeout) 

198 

199 if retries is None: 

200 retries = Retry.DEFAULT 

201 

202 self.timeout = timeout 

203 self.retries = retries 

204 

205 self.pool = self.QueueCls(maxsize) 

206 self.block = block 

207 

208 self.proxy = _proxy 

209 self.proxy_headers = _proxy_headers or {} 

210 self.proxy_config = _proxy_config 

211 

212 # Fill the queue up so that doing get() on it will block properly 

213 for _ in xrange(maxsize): 

214 self.pool.put(None) 

215 

216 # These are mostly for testing and debugging purposes. 

217 self.num_connections = 0 

218 self.num_requests = 0 

219 self.conn_kw = conn_kw 

220 

221 if self.proxy: 

222 # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. 

223 # We cannot know if the user has added default socket options, so we cannot replace the 

224 # list. 

225 self.conn_kw.setdefault("socket_options", []) 

226 

227 self.conn_kw["proxy"] = self.proxy 

228 self.conn_kw["proxy_config"] = self.proxy_config 

229 

230 # Do not pass 'self' as callback to 'finalize'. 

231 # Then the 'finalize' would keep an endless living (leak) to self. 

232 # By just passing a reference to the pool allows the garbage collector 

233 # to free self if nobody else has a reference to it. 

234 pool = self.pool 

235 

236 # Close all the HTTPConnections in the pool before the 

237 # HTTPConnectionPool object is garbage collected. 

238 weakref_finalize(self, _close_pool_connections, pool) 

239 

240 def _new_conn(self): 

241 """ 

242 Return a fresh :class:`HTTPConnection`. 

243 """ 

244 self.num_connections += 1 

245 log.debug( 

246 "Starting new HTTP connection (%d): %s:%s", 

247 self.num_connections, 

248 self.host, 

249 self.port or "80", 

250 ) 

251 

252 conn = self.ConnectionCls( 

253 host=self.host, 

254 port=self.port, 

255 timeout=self.timeout.connect_timeout, 

256 strict=self.strict, 

257 **self.conn_kw 

258 ) 

259 return conn 

260 

261 def _get_conn(self, timeout=None): 

262 """ 

263 Get a connection. Will return a pooled connection if one is available. 

264 

265 If no connections are available and :prop:`.block` is ``False``, then a 

266 fresh connection is returned. 

267 

268 :param timeout: 

269 Seconds to wait before giving up and raising 

270 :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and 

271 :prop:`.block` is ``True``. 

272 """ 

273 conn = None 

274 try: 

275 conn = self.pool.get(block=self.block, timeout=timeout) 

276 

277 except AttributeError: # self.pool is None 

278 raise ClosedPoolError(self, "Pool is closed.") 

279 

280 except queue.Empty: 

281 if self.block: 

282 raise EmptyPoolError( 

283 self, 

284 "Pool reached maximum size and no more connections are allowed.", 

285 ) 

286 pass # Oh well, we'll create a new connection then 

287 

288 # If this is a persistent connection, check if it got disconnected 

289 if conn and is_connection_dropped(conn): 

290 log.debug("Resetting dropped connection: %s", self.host) 

291 conn.close() 

292 if getattr(conn, "auto_open", 1) == 0: 

293 # This is a proxied connection that has been mutated by 

294 # http.client._tunnel() and cannot be reused (since it would 

295 # attempt to bypass the proxy) 

296 conn = None 

297 

298 return conn or self._new_conn() 

299 

300 def _put_conn(self, conn): 

301 """ 

302 Put a connection back into the pool. 

303 

304 :param conn: 

305 Connection object for the current host and port as returned by 

306 :meth:`._new_conn` or :meth:`._get_conn`. 

307 

308 If the pool is already full, the connection is closed and discarded 

309 because we exceeded maxsize. If connections are discarded frequently, 

310 then maxsize should be increased. 

311 

312 If the pool is closed, then the connection will be closed and discarded. 

313 """ 

314 try: 

315 self.pool.put(conn, block=False) 

316 return # Everything is dandy, done. 

317 except AttributeError: 

318 # self.pool is None. 

319 pass 

320 except queue.Full: 

321 # This should never happen if self.block == True 

322 log.warning( 

323 "Connection pool is full, discarding connection: %s. Connection pool size: %s", 

324 self.host, 

325 self.pool.qsize(), 

326 ) 

327 # Connection never got put back into the pool, close it. 

328 if conn: 

329 conn.close() 

330 

331 def _validate_conn(self, conn): 

332 """ 

333 Called right before a request is made, after the socket is created. 

334 """ 

335 pass 

336 

337 def _prepare_proxy(self, conn): 

338 # Nothing to do for HTTP connections. 

339 pass 

340 

341 def _get_timeout(self, timeout): 

342 """Helper that always returns a :class:`urllib3.util.Timeout`""" 

343 if timeout is _Default: 

344 return self.timeout.clone() 

345 

346 if isinstance(timeout, Timeout): 

347 return timeout.clone() 

348 else: 

349 # User passed us an int/float. This is for backwards compatibility, 

350 # can be removed later 

351 return Timeout.from_float(timeout) 

352 

353 def _raise_timeout(self, err, url, timeout_value): 

354 """Is the error actually a timeout? Will raise a ReadTimeout or pass""" 

355 

356 if isinstance(err, SocketTimeout): 

357 raise ReadTimeoutError( 

358 self, url, "Read timed out. (read timeout=%s)" % timeout_value 

359 ) 

360 

361 # See the above comment about EAGAIN in Python 3. In Python 2 we have 

362 # to specifically catch it and throw the timeout error 

363 if hasattr(err, "errno") and err.errno in _blocking_errnos: 

364 raise ReadTimeoutError( 

365 self, url, "Read timed out. (read timeout=%s)" % timeout_value 

366 ) 

367 

368 # Catch possible read timeouts thrown as SSL errors. If not the 

369 # case, rethrow the original. We need to do this because of: 

370 # http://bugs.python.org/issue10272 

371 if "timed out" in str(err) or "did not complete (read)" in str( 

372 err 

373 ): # Python < 2.7.4 

374 raise ReadTimeoutError( 

375 self, url, "Read timed out. (read timeout=%s)" % timeout_value 

376 ) 

377 

378 def _make_request( 

379 self, conn, method, url, timeout=_Default, chunked=False, **httplib_request_kw 

380 ): 

381 """ 

382 Perform a request on a given urllib connection object taken from our 

383 pool. 

384 

385 :param conn: 

386 a connection from one of our connection pools 

387 

388 :param timeout: 

389 Socket timeout in seconds for the request. This can be a 

390 float or integer, which will set the same timeout value for 

391 the socket connect and the socket read, or an instance of 

392 :class:`urllib3.util.Timeout`, which gives you more fine-grained 

393 control over your timeouts. 

394 """ 

395 self.num_requests += 1 

396 

397 timeout_obj = self._get_timeout(timeout) 

398 timeout_obj.start_connect() 

399 conn.timeout = Timeout.resolve_default_timeout(timeout_obj.connect_timeout) 

400 

401 # Trigger any extra validation we need to do. 

402 try: 

403 self._validate_conn(conn) 

404 except (SocketTimeout, BaseSSLError) as e: 

405 # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. 

406 self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) 

407 raise 

408 

409 # conn.request() calls http.client.*.request, not the method in 

410 # urllib3.request. It also calls makefile (recv) on the socket. 

411 try: 

412 if chunked: 

413 conn.request_chunked(method, url, **httplib_request_kw) 

414 else: 

415 conn.request(method, url, **httplib_request_kw) 

416 

417 # We are swallowing BrokenPipeError (errno.EPIPE) since the server is 

418 # legitimately able to close the connection after sending a valid response. 

419 # With this behaviour, the received response is still readable. 

420 except BrokenPipeError: 

421 # Python 3 

422 pass 

423 except IOError as e: 

424 # Python 2 and macOS/Linux 

425 # EPIPE and ESHUTDOWN are BrokenPipeError on Python 2, and EPROTOTYPE is needed on macOS 

426 # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/ 

427 if e.errno not in { 

428 errno.EPIPE, 

429 errno.ESHUTDOWN, 

430 errno.EPROTOTYPE, 

431 }: 

432 raise 

433 

434 # Reset the timeout for the recv() on the socket 

435 read_timeout = timeout_obj.read_timeout 

436 

437 # App Engine doesn't have a sock attr 

438 if getattr(conn, "sock", None): 

439 # In Python 3 socket.py will catch EAGAIN and return None when you 

440 # try and read into the file pointer created by http.client, which 

441 # instead raises a BadStatusLine exception. Instead of catching 

442 # the exception and assuming all BadStatusLine exceptions are read 

443 # timeouts, check for a zero timeout before making the request. 

444 if read_timeout == 0: 

445 raise ReadTimeoutError( 

446 self, url, "Read timed out. (read timeout=%s)" % read_timeout 

447 ) 

448 if read_timeout is Timeout.DEFAULT_TIMEOUT: 

449 conn.sock.settimeout(socket.getdefaulttimeout()) 

450 else: # None or a value 

451 conn.sock.settimeout(read_timeout) 

452 

453 # Receive the response from the server 

454 try: 

455 try: 

456 # Python 2.7, use buffering of HTTP responses 

457 httplib_response = conn.getresponse(buffering=True) 

458 except TypeError: 

459 # Python 3 

460 try: 

461 httplib_response = conn.getresponse() 

462 except BaseException as e: 

463 # Remove the TypeError from the exception chain in 

464 # Python 3 (including for exceptions like SystemExit). 

465 # Otherwise it looks like a bug in the code. 

466 six.raise_from(e, None) 

467 except (SocketTimeout, BaseSSLError, SocketError) as e: 

468 self._raise_timeout(err=e, url=url, timeout_value=read_timeout) 

469 raise 

470 

471 # AppEngine doesn't have a version attr. 

472 http_version = getattr(conn, "_http_vsn_str", "HTTP/?") 

473 log.debug( 

474 '%s://%s:%s "%s %s %s" %s %s', 

475 self.scheme, 

476 self.host, 

477 self.port, 

478 method, 

479 url, 

480 http_version, 

481 httplib_response.status, 

482 httplib_response.length, 

483 ) 

484 

485 try: 

486 assert_header_parsing(httplib_response.msg) 

487 except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 

488 log.warning( 

489 "Failed to parse headers (url=%s): %s", 

490 self._absolute_url(url), 

491 hpe, 

492 exc_info=True, 

493 ) 

494 

495 return httplib_response 

496 

497 def _absolute_url(self, path): 

498 return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url 

499 

500 def close(self): 

501 """ 

502 Close all pooled connections and disable the pool. 

503 """ 

504 if self.pool is None: 

505 return 

506 # Disable access to the pool 

507 old_pool, self.pool = self.pool, None 

508 

509 # Close all the HTTPConnections in the pool. 

510 _close_pool_connections(old_pool) 

511 

512 def is_same_host(self, url): 

513 """ 

514 Check if the given ``url`` is a member of the same host as this 

515 connection pool. 

516 """ 

517 if url.startswith("/"): 

518 return True 

519 

520 # TODO: Add optional support for socket.gethostbyname checking. 

521 scheme, host, port = get_host(url) 

522 if host is not None: 

523 host = _normalize_host(host, scheme=scheme) 

524 

525 # Use explicit default port for comparison when none is given 

526 if self.port and not port: 

527 port = port_by_scheme.get(scheme) 

528 elif not self.port and port == port_by_scheme.get(scheme): 

529 port = None 

530 

531 return (scheme, host, port) == (self.scheme, self.host, self.port) 

532 

533 def urlopen( 

534 self, 

535 method, 

536 url, 

537 body=None, 

538 headers=None, 

539 retries=None, 

540 redirect=True, 

541 assert_same_host=True, 

542 timeout=_Default, 

543 pool_timeout=None, 

544 release_conn=None, 

545 chunked=False, 

546 body_pos=None, 

547 **response_kw 

548 ): 

549 """ 

550 Get a connection from the pool and perform an HTTP request. This is the 

551 lowest level call for making a request, so you'll need to specify all 

552 the raw details. 

553 

554 .. note:: 

555 

556 More commonly, it's appropriate to use a convenience method provided 

557 by :class:`.RequestMethods`, such as :meth:`request`. 

558 

559 .. note:: 

560 

561 `release_conn` will only behave as expected if 

562 `preload_content=False` because we want to make 

563 `preload_content=False` the default behaviour someday soon without 

564 breaking backwards compatibility. 

565 

566 :param method: 

567 HTTP request method (such as GET, POST, PUT, etc.) 

568 

569 :param url: 

570 The URL to perform the request on. 

571 

572 :param body: 

573 Data to send in the request body, either :class:`str`, :class:`bytes`, 

574 an iterable of :class:`str`/:class:`bytes`, or a file-like object. 

575 

576 :param headers: 

577 Dictionary of custom headers to send, such as User-Agent, 

578 If-None-Match, etc. If None, pool headers are used. If provided, 

579 these headers completely replace any pool-specific headers. 

580 

581 :param retries: 

582 Configure the number of retries to allow before raising a 

583 :class:`~urllib3.exceptions.MaxRetryError` exception. 

584 

585 Pass ``None`` to retry until you receive a response. Pass a 

586 :class:`~urllib3.util.retry.Retry` object for fine-grained control 

587 over different types of retries. 

588 Pass an integer number to retry connection errors that many times, 

589 but no other types of errors. Pass zero to never retry. 

590 

591 If ``False``, then retries are disabled and any exception is raised 

592 immediately. Also, instead of raising a MaxRetryError on redirects, 

593 the redirect response will be returned. 

594 

595 :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. 

596 

597 :param redirect: 

598 If True, automatically handle redirects (status codes 301, 302, 

599 303, 307, 308). Each redirect counts as a retry. Disabling retries 

600 will disable redirect, too. 

601 

602 :param assert_same_host: 

603 If ``True``, will make sure that the host of the pool requests is 

604 consistent else will raise HostChangedError. When ``False``, you can 

605 use the pool on an HTTP proxy and request foreign hosts. 

606 

607 :param timeout: 

608 If specified, overrides the default timeout for this one 

609 request. It may be a float (in seconds) or an instance of 

610 :class:`urllib3.util.Timeout`. 

611 

612 :param pool_timeout: 

613 If set and the pool is set to block=True, then this method will 

614 block for ``pool_timeout`` seconds and raise EmptyPoolError if no 

615 connection is available within the time period. 

616 

617 :param release_conn: 

618 If False, then the urlopen call will not release the connection 

619 back into the pool once a response is received (but will release if 

620 you read the entire contents of the response such as when 

621 `preload_content=True`). This is useful if you're not preloading 

622 the response's content immediately. You will need to call 

623 ``r.release_conn()`` on the response ``r`` to return the connection 

624 back into the pool. If None, it takes the value of 

625 ``response_kw.get('preload_content', True)``. 

626 

627 :param chunked: 

628 If True, urllib3 will send the body using chunked transfer 

629 encoding. Otherwise, urllib3 will send the body using the standard 

630 content-length form. Defaults to False. 

631 

632 :param int body_pos: 

633 Position to seek to in file-like body in the event of a retry or 

634 redirect. Typically this won't need to be set because urllib3 will 

635 auto-populate the value when needed. 

636 

637 :param \\**response_kw: 

638 Additional parameters are passed to 

639 :meth:`urllib3.response.HTTPResponse.from_httplib` 

640 """ 

641 

642 parsed_url = parse_url(url) 

643 destination_scheme = parsed_url.scheme 

644 

645 if headers is None: 

646 headers = self.headers 

647 

648 if not isinstance(retries, Retry): 

649 retries = Retry.from_int(retries, redirect=redirect, default=self.retries) 

650 

651 if release_conn is None: 

652 release_conn = response_kw.get("preload_content", True) 

653 

654 # Check host 

655 if assert_same_host and not self.is_same_host(url): 

656 raise HostChangedError(self, url, retries) 

657 

658 # Ensure that the URL we're connecting to is properly encoded 

659 if url.startswith("/"): 

660 url = six.ensure_str(_encode_target(url)) 

661 else: 

662 url = six.ensure_str(parsed_url.url) 

663 

664 conn = None 

665 

666 # Track whether `conn` needs to be released before 

667 # returning/raising/recursing. Update this variable if necessary, and 

668 # leave `release_conn` constant throughout the function. That way, if 

669 # the function recurses, the original value of `release_conn` will be 

670 # passed down into the recursive call, and its value will be respected. 

671 # 

672 # See issue #651 [1] for details. 

673 # 

674 # [1] <https://github.com/urllib3/urllib3/issues/651> 

675 release_this_conn = release_conn 

676 

677 http_tunnel_required = connection_requires_http_tunnel( 

678 self.proxy, self.proxy_config, destination_scheme 

679 ) 

680 

681 # Merge the proxy headers. Only done when not using HTTP CONNECT. We 

682 # have to copy the headers dict so we can safely change it without those 

683 # changes being reflected in anyone else's copy. 

684 if not http_tunnel_required: 

685 headers = headers.copy() 

686 headers.update(self.proxy_headers) 

687 

688 # Must keep the exception bound to a separate variable or else Python 3 

689 # complains about UnboundLocalError. 

690 err = None 

691 

692 # Keep track of whether we cleanly exited the except block. This 

693 # ensures we do proper cleanup in finally. 

694 clean_exit = False 

695 

696 # Rewind body position, if needed. Record current position 

697 # for future rewinds in the event of a redirect/retry. 

698 body_pos = set_file_position(body, body_pos) 

699 

700 try: 

701 # Request a connection from the queue. 

702 timeout_obj = self._get_timeout(timeout) 

703 conn = self._get_conn(timeout=pool_timeout) 

704 

705 conn.timeout = timeout_obj.connect_timeout 

706 

707 is_new_proxy_conn = self.proxy is not None and not getattr( 

708 conn, "sock", None 

709 ) 

710 if is_new_proxy_conn and http_tunnel_required: 

711 self._prepare_proxy(conn) 

712 

713 # Make the request on the httplib connection object. 

714 httplib_response = self._make_request( 

715 conn, 

716 method, 

717 url, 

718 timeout=timeout_obj, 

719 body=body, 

720 headers=headers, 

721 chunked=chunked, 

722 ) 

723 

724 # If we're going to release the connection in ``finally:``, then 

725 # the response doesn't need to know about the connection. Otherwise 

726 # it will also try to release it and we'll have a double-release 

727 # mess. 

728 response_conn = conn if not release_conn else None 

729 

730 # Pass method to Response for length checking 

731 response_kw["request_method"] = method 

732 

733 # Import httplib's response into our own wrapper object 

734 response = self.ResponseCls.from_httplib( 

735 httplib_response, 

736 pool=self, 

737 connection=response_conn, 

738 retries=retries, 

739 **response_kw 

740 ) 

741 

742 # Everything went great! 

743 clean_exit = True 

744 

745 except EmptyPoolError: 

746 # Didn't get a connection from the pool, no need to clean up 

747 clean_exit = True 

748 release_this_conn = False 

749 raise 

750 

751 except ( 

752 TimeoutError, 

753 HTTPException, 

754 SocketError, 

755 ProtocolError, 

756 BaseSSLError, 

757 SSLError, 

758 CertificateError, 

759 ) as e: 

760 # Discard the connection for these exceptions. It will be 

761 # replaced during the next _get_conn() call. 

762 clean_exit = False 

763 

764 def _is_ssl_error_message_from_http_proxy(ssl_error): 

765 # We're trying to detect the message 'WRONG_VERSION_NUMBER' but 

766 # SSLErrors are kinda all over the place when it comes to the message, 

767 # so we try to cover our bases here! 

768 message = " ".join(re.split("[^a-z]", str(ssl_error).lower())) 

769 return ( 

770 "wrong version number" in message or "unknown protocol" in message 

771 ) 

772 

773 # Try to detect a common user error with proxies which is to 

774 # set an HTTP proxy to be HTTPS when it should be 'http://' 

775 # (ie {'http': 'http://proxy', 'https': 'https://proxy'}) 

776 # Instead we add a nice error message and point to a URL. 

777 if ( 

778 isinstance(e, BaseSSLError) 

779 and self.proxy 

780 and _is_ssl_error_message_from_http_proxy(e) 

781 and conn.proxy 

782 and conn.proxy.scheme == "https" 

783 ): 

784 e = ProxyError( 

785 "Your proxy appears to only use HTTP and not HTTPS, " 

786 "try changing your proxy URL to be HTTP. See: " 

787 "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" 

788 "#https-proxy-error-http-proxy", 

789 SSLError(e), 

790 ) 

791 elif isinstance(e, (BaseSSLError, CertificateError)): 

792 e = SSLError(e) 

793 elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: 

794 e = ProxyError("Cannot connect to proxy.", e) 

795 elif isinstance(e, (SocketError, HTTPException)): 

796 e = ProtocolError("Connection aborted.", e) 

797 

798 retries = retries.increment( 

799 method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2] 

800 ) 

801 retries.sleep() 

802 

803 # Keep track of the error for the retry warning. 

804 err = e 

805 

806 finally: 

807 if not clean_exit: 

808 # We hit some kind of exception, handled or otherwise. We need 

809 # to throw the connection away unless explicitly told not to. 

810 # Close the connection, set the variable to None, and make sure 

811 # we put the None back in the pool to avoid leaking it. 

812 conn = conn and conn.close() 

813 release_this_conn = True 

814 

815 if release_this_conn: 

816 # Put the connection back to be reused. If the connection is 

817 # expired then it will be None, which will get replaced with a 

818 # fresh connection during _get_conn. 

819 self._put_conn(conn) 

820 

821 if not conn: 

822 # Try again 

823 log.warning( 

824 "Retrying (%r) after connection broken by '%r': %s", retries, err, url 

825 ) 

826 return self.urlopen( 

827 method, 

828 url, 

829 body, 

830 headers, 

831 retries, 

832 redirect, 

833 assert_same_host, 

834 timeout=timeout, 

835 pool_timeout=pool_timeout, 

836 release_conn=release_conn, 

837 chunked=chunked, 

838 body_pos=body_pos, 

839 **response_kw 

840 ) 

841 

842 # Handle redirect? 

843 redirect_location = redirect and response.get_redirect_location() 

844 if redirect_location: 

845 if response.status == 303: 

846 method = "GET" 

847 

848 try: 

849 retries = retries.increment(method, url, response=response, _pool=self) 

850 except MaxRetryError: 

851 if retries.raise_on_redirect: 

852 response.drain_conn() 

853 raise 

854 return response 

855 

856 response.drain_conn() 

857 retries.sleep_for_retry(response) 

858 log.debug("Redirecting %s -> %s", url, redirect_location) 

859 return self.urlopen( 

860 method, 

861 redirect_location, 

862 body, 

863 headers, 

864 retries=retries, 

865 redirect=redirect, 

866 assert_same_host=assert_same_host, 

867 timeout=timeout, 

868 pool_timeout=pool_timeout, 

869 release_conn=release_conn, 

870 chunked=chunked, 

871 body_pos=body_pos, 

872 **response_kw 

873 ) 

874 

875 # Check if we should retry the HTTP response. 

876 has_retry_after = bool(response.headers.get("Retry-After")) 

877 if retries.is_retry(method, response.status, has_retry_after): 

878 try: 

879 retries = retries.increment(method, url, response=response, _pool=self) 

880 except MaxRetryError: 

881 if retries.raise_on_status: 

882 response.drain_conn() 

883 raise 

884 return response 

885 

886 response.drain_conn() 

887 retries.sleep(response) 

888 log.debug("Retry: %s", url) 

889 return self.urlopen( 

890 method, 

891 url, 

892 body, 

893 headers, 

894 retries=retries, 

895 redirect=redirect, 

896 assert_same_host=assert_same_host, 

897 timeout=timeout, 

898 pool_timeout=pool_timeout, 

899 release_conn=release_conn, 

900 chunked=chunked, 

901 body_pos=body_pos, 

902 **response_kw 

903 ) 

904 

905 return response 

906 

907 

908class HTTPSConnectionPool(HTTPConnectionPool): 

909 """ 

910 Same as :class:`.HTTPConnectionPool`, but HTTPS. 

911 

912 :class:`.HTTPSConnection` uses one of ``assert_fingerprint``, 

913 ``assert_hostname`` and ``host`` in this order to verify connections. 

914 If ``assert_hostname`` is False, no verification is done. 

915 

916 The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, 

917 ``ca_cert_dir``, ``ssl_version``, ``key_password`` are only used if :mod:`ssl` 

918 is available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade 

919 the connection socket into an SSL socket. 

920 """ 

921 

922 scheme = "https" 

923 ConnectionCls = HTTPSConnection 

924 

925 def __init__( 

926 self, 

927 host, 

928 port=None, 

929 strict=False, 

930 timeout=Timeout.DEFAULT_TIMEOUT, 

931 maxsize=1, 

932 block=False, 

933 headers=None, 

934 retries=None, 

935 _proxy=None, 

936 _proxy_headers=None, 

937 key_file=None, 

938 cert_file=None, 

939 cert_reqs=None, 

940 key_password=None, 

941 ca_certs=None, 

942 ssl_version=None, 

943 assert_hostname=None, 

944 assert_fingerprint=None, 

945 ca_cert_dir=None, 

946 **conn_kw 

947 ): 

948 

949 HTTPConnectionPool.__init__( 

950 self, 

951 host, 

952 port, 

953 strict, 

954 timeout, 

955 maxsize, 

956 block, 

957 headers, 

958 retries, 

959 _proxy, 

960 _proxy_headers, 

961 **conn_kw 

962 ) 

963 

964 self.key_file = key_file 

965 self.cert_file = cert_file 

966 self.cert_reqs = cert_reqs 

967 self.key_password = key_password 

968 self.ca_certs = ca_certs 

969 self.ca_cert_dir = ca_cert_dir 

970 self.ssl_version = ssl_version 

971 self.assert_hostname = assert_hostname 

972 self.assert_fingerprint = assert_fingerprint 

973 

974 def _prepare_conn(self, conn): 

975 """ 

976 Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` 

977 and establish the tunnel if proxy is used. 

978 """ 

979 

980 if isinstance(conn, VerifiedHTTPSConnection): 

981 conn.set_cert( 

982 key_file=self.key_file, 

983 key_password=self.key_password, 

984 cert_file=self.cert_file, 

985 cert_reqs=self.cert_reqs, 

986 ca_certs=self.ca_certs, 

987 ca_cert_dir=self.ca_cert_dir, 

988 assert_hostname=self.assert_hostname, 

989 assert_fingerprint=self.assert_fingerprint, 

990 ) 

991 conn.ssl_version = self.ssl_version 

992 return conn 

993 

994 def _prepare_proxy(self, conn): 

995 """ 

996 Establishes a tunnel connection through HTTP CONNECT. 

997 

998 Tunnel connection is established early because otherwise httplib would 

999 improperly set Host: header to proxy's IP:port. 

1000 """ 

1001 

1002 conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers) 

1003 

1004 if self.proxy.scheme == "https": 

1005 conn.tls_in_tls_required = True 

1006 

1007 conn.connect() 

1008 

1009 def _new_conn(self): 

1010 """ 

1011 Return a fresh :class:`http.client.HTTPSConnection`. 

1012 """ 

1013 self.num_connections += 1 

1014 log.debug( 

1015 "Starting new HTTPS connection (%d): %s:%s", 

1016 self.num_connections, 

1017 self.host, 

1018 self.port or "443", 

1019 ) 

1020 

1021 if not self.ConnectionCls or self.ConnectionCls is DummyConnection: 

1022 raise SSLError( 

1023 "Can't connect to HTTPS URL because the SSL module is not available." 

1024 ) 

1025 

1026 actual_host = self.host 

1027 actual_port = self.port 

1028 if self.proxy is not None: 

1029 actual_host = self.proxy.host 

1030 actual_port = self.proxy.port 

1031 

1032 conn = self.ConnectionCls( 

1033 host=actual_host, 

1034 port=actual_port, 

1035 timeout=self.timeout.connect_timeout, 

1036 strict=self.strict, 

1037 cert_file=self.cert_file, 

1038 key_file=self.key_file, 

1039 key_password=self.key_password, 

1040 **self.conn_kw 

1041 ) 

1042 

1043 return self._prepare_conn(conn) 

1044 

1045 def _validate_conn(self, conn): 

1046 """ 

1047 Called right before a request is made, after the socket is created. 

1048 """ 

1049 super(HTTPSConnectionPool, self)._validate_conn(conn) 

1050 

1051 # Force connect early to allow us to validate the connection. 

1052 if not getattr(conn, "sock", None): # AppEngine might not have `.sock` 

1053 conn.connect() 

1054 

1055 if not conn.is_verified: 

1056 warnings.warn( 

1057 ( 

1058 "Unverified HTTPS request is being made to host '%s'. " 

1059 "Adding certificate verification is strongly advised. See: " 

1060 "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" 

1061 "#ssl-warnings" % conn.host 

1062 ), 

1063 InsecureRequestWarning, 

1064 ) 

1065 

1066 if getattr(conn, "proxy_is_verified", None) is False: 

1067 warnings.warn( 

1068 ( 

1069 "Unverified HTTPS connection done to an HTTPS proxy. " 

1070 "Adding certificate verification is strongly advised. See: " 

1071 "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" 

1072 "#ssl-warnings" 

1073 ), 

1074 InsecureRequestWarning, 

1075 ) 

1076 

1077 

1078def connection_from_url(url, **kw): 

1079 """ 

1080 Given a url, return an :class:`.ConnectionPool` instance of its host. 

1081 

1082 This is a shortcut for not having to parse out the scheme, host, and port 

1083 of the url before creating an :class:`.ConnectionPool` instance. 

1084 

1085 :param url: 

1086 Absolute URL string that must include the scheme. Port is optional. 

1087 

1088 :param \\**kw: 

1089 Passes additional parameters to the constructor of the appropriate 

1090 :class:`.ConnectionPool`. Useful for specifying things like 

1091 timeout, maxsize, headers, etc. 

1092 

1093 Example:: 

1094 

1095 >>> conn = connection_from_url('http://google.com/') 

1096 >>> r = conn.request('GET', '/') 

1097 """ 

1098 scheme, host, port = get_host(url) 

1099 port = port or port_by_scheme.get(scheme, 80) 

1100 if scheme == "https": 

1101 return HTTPSConnectionPool(host, port=port, **kw) 

1102 else: 

1103 return HTTPConnectionPool(host, port=port, **kw) 

1104 

1105 

1106def _normalize_host(host, scheme): 

1107 """ 

1108 Normalize hosts for comparisons and use with sockets. 

1109 """ 

1110 

1111 host = normalize_host(host, scheme) 

1112 

1113 # httplib doesn't like it when we include brackets in IPv6 addresses 

1114 # Specifically, if we include brackets but also pass the port then 

1115 # httplib crazily doubles up the square brackets on the Host header. 

1116 # Instead, we need to make sure we never pass ``None`` as the port. 

1117 # However, for backward compatibility reasons we can't actually 

1118 # *assert* that. See http://bugs.python.org/issue28539 

1119 if host.startswith("[") and host.endswith("]"): 

1120 host = host[1:-1] 

1121 return host 

1122 

1123 

1124def _close_pool_connections(pool): 

1125 """Drains a queue of connections and closes each one.""" 

1126 try: 

1127 while True: 

1128 conn = pool.get(block=False) 

1129 if conn: 

1130 conn.close() 

1131 except queue.Empty: 

1132 pass # Done.