_base_connection.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. from __future__ import annotations
  2. import typing
  3. from .util.connection import _TYPE_SOCKET_OPTIONS
  4. from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT
  5. from .util.url import Url
  6. _TYPE_BODY = typing.Union[bytes, typing.IO[typing.Any], typing.Iterable[bytes], str]
  7. class ProxyConfig(typing.NamedTuple):
  8. ssl_context: ssl.SSLContext | None
  9. use_forwarding_for_https: bool
  10. assert_hostname: None | str | typing.Literal[False]
  11. assert_fingerprint: str | None
  12. class _ResponseOptions(typing.NamedTuple):
  13. # TODO: Remove this in favor of a better
  14. # HTTP request/response lifecycle tracking.
  15. request_method: str
  16. request_url: str
  17. preload_content: bool
  18. decode_content: bool
  19. enforce_content_length: bool
  20. if typing.TYPE_CHECKING:
  21. import ssl
  22. from typing import Protocol
  23. from .response import BaseHTTPResponse
  24. class BaseHTTPConnection(Protocol):
  25. default_port: typing.ClassVar[int]
  26. default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
  27. host: str
  28. port: int
  29. timeout: None | (
  30. float
  31. ) # Instance doesn't store _DEFAULT_TIMEOUT, must be resolved.
  32. blocksize: int
  33. source_address: tuple[str, int] | None
  34. socket_options: _TYPE_SOCKET_OPTIONS | None
  35. proxy: Url | None
  36. proxy_config: ProxyConfig | None
  37. is_verified: bool
  38. proxy_is_verified: bool | None
  39. def __init__(
  40. self,
  41. host: str,
  42. port: int | None = None,
  43. *,
  44. timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
  45. source_address: tuple[str, int] | None = None,
  46. blocksize: int = 8192,
  47. socket_options: _TYPE_SOCKET_OPTIONS | None = ...,
  48. proxy: Url | None = None,
  49. proxy_config: ProxyConfig | None = None,
  50. ) -> None: ...
  51. def set_tunnel(
  52. self,
  53. host: str,
  54. port: int | None = None,
  55. headers: typing.Mapping[str, str] | None = None,
  56. scheme: str = "http",
  57. ) -> None: ...
  58. def connect(self) -> None: ...
  59. def request(
  60. self,
  61. method: str,
  62. url: str,
  63. body: _TYPE_BODY | None = None,
  64. headers: typing.Mapping[str, str] | None = None,
  65. # We know *at least* botocore is depending on the order of the
  66. # first 3 parameters so to be safe we only mark the later ones
  67. # as keyword-only to ensure we have space to extend.
  68. *,
  69. chunked: bool = False,
  70. preload_content: bool = True,
  71. decode_content: bool = True,
  72. enforce_content_length: bool = True,
  73. ) -> None: ...
  74. def getresponse(self) -> BaseHTTPResponse: ...
  75. def close(self) -> None: ...
  76. @property
  77. def is_closed(self) -> bool:
  78. """Whether the connection either is brand new or has been previously closed.
  79. If this property is True then both ``is_connected`` and ``has_connected_to_proxy``
  80. properties must be False.
  81. """
  82. @property
  83. def is_connected(self) -> bool:
  84. """Whether the connection is actively connected to any origin (proxy or target)"""
  85. @property
  86. def has_connected_to_proxy(self) -> bool:
  87. """Whether the connection has successfully connected to its proxy.
  88. This returns False if no proxy is in use. Used to determine whether
  89. errors are coming from the proxy layer or from tunnelling to the target origin.
  90. """
  91. class BaseHTTPSConnection(BaseHTTPConnection, Protocol):
  92. default_port: typing.ClassVar[int]
  93. default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
  94. # Certificate verification methods
  95. cert_reqs: int | str | None
  96. assert_hostname: None | str | typing.Literal[False]
  97. assert_fingerprint: str | None
  98. ssl_context: ssl.SSLContext | None
  99. # Trusted CAs
  100. ca_certs: str | None
  101. ca_cert_dir: str | None
  102. ca_cert_data: None | str | bytes
  103. # TLS version
  104. ssl_minimum_version: int | None
  105. ssl_maximum_version: int | None
  106. ssl_version: int | str | None # Deprecated
  107. # Client certificates
  108. cert_file: str | None
  109. key_file: str | None
  110. key_password: str | None
  111. def __init__(
  112. self,
  113. host: str,
  114. port: int | None = None,
  115. *,
  116. timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
  117. source_address: tuple[str, int] | None = None,
  118. blocksize: int = 16384,
  119. socket_options: _TYPE_SOCKET_OPTIONS | None = ...,
  120. proxy: Url | None = None,
  121. proxy_config: ProxyConfig | None = None,
  122. cert_reqs: int | str | None = None,
  123. assert_hostname: None | str | typing.Literal[False] = None,
  124. assert_fingerprint: str | None = None,
  125. server_hostname: str | None = None,
  126. ssl_context: ssl.SSLContext | None = None,
  127. ca_certs: str | None = None,
  128. ca_cert_dir: str | None = None,
  129. ca_cert_data: None | str | bytes = None,
  130. ssl_minimum_version: int | None = None,
  131. ssl_maximum_version: int | None = None,
  132. ssl_version: int | str | None = None, # Deprecated
  133. cert_file: str | None = None,
  134. key_file: str | None = None,
  135. key_password: str | None = None,
  136. ) -> None: ...