123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- from __future__ import annotations
- import os
- import typing
- # use http.client.HTTPException for consistency with non-emscripten
- from http.client import HTTPException as HTTPException # noqa: F401
- from http.client import ResponseNotReady
- from ..._base_connection import _TYPE_BODY
- from ...connection import HTTPConnection, ProxyConfig, port_by_scheme
- from ...exceptions import TimeoutError
- from ...response import BaseHTTPResponse
- from ...util.connection import _TYPE_SOCKET_OPTIONS
- from ...util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT
- from ...util.url import Url
- from .fetch import _RequestError, _TimeoutError, send_request, send_streaming_request
- from .request import EmscriptenRequest
- from .response import EmscriptenHttpResponseWrapper, EmscriptenResponse
- if typing.TYPE_CHECKING:
- from ..._base_connection import BaseHTTPConnection, BaseHTTPSConnection
- class EmscriptenHTTPConnection:
- default_port: typing.ClassVar[int] = port_by_scheme["http"]
- default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
- timeout: None | (float)
- host: str
- port: int
- blocksize: int
- source_address: tuple[str, int] | None
- socket_options: _TYPE_SOCKET_OPTIONS | None
- proxy: Url | None
- proxy_config: ProxyConfig | None
- is_verified: bool = False
- proxy_is_verified: bool | None = None
- _response: EmscriptenResponse | None
- def __init__(
- self,
- host: str,
- port: int = 0,
- *,
- timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
- source_address: tuple[str, int] | None = None,
- blocksize: int = 8192,
- socket_options: _TYPE_SOCKET_OPTIONS | None = None,
- proxy: Url | None = None,
- proxy_config: ProxyConfig | None = None,
- ) -> None:
- self.host = host
- self.port = port
- self.timeout = timeout if isinstance(timeout, float) else 0.0
- self.scheme = "http"
- self._closed = True
- self._response = None
- # ignore these things because we don't
- # have control over that stuff
- self.proxy = None
- self.proxy_config = None
- self.blocksize = blocksize
- self.source_address = None
- self.socket_options = None
- self.is_verified = False
- def set_tunnel(
- self,
- host: str,
- port: int | None = 0,
- headers: typing.Mapping[str, str] | None = None,
- scheme: str = "http",
- ) -> None:
- pass
- def connect(self) -> None:
- pass
- def request(
- self,
- method: str,
- url: str,
- body: _TYPE_BODY | None = None,
- headers: typing.Mapping[str, str] | None = None,
- # We know *at least* botocore is depending on the order of the
- # first 3 parameters so to be safe we only mark the later ones
- # as keyword-only to ensure we have space to extend.
- *,
- chunked: bool = False,
- preload_content: bool = True,
- decode_content: bool = True,
- enforce_content_length: bool = True,
- ) -> None:
- self._closed = False
- if url.startswith("/"):
- # no scheme / host / port included, make a full url
- url = f"{self.scheme}://{self.host}:{self.port}" + url
- request = EmscriptenRequest(
- url=url,
- method=method,
- timeout=self.timeout if self.timeout else 0,
- decode_content=decode_content,
- )
- request.set_body(body)
- if headers:
- for k, v in headers.items():
- request.set_header(k, v)
- self._response = None
- try:
- if not preload_content:
- self._response = send_streaming_request(request)
- if self._response is None:
- self._response = send_request(request)
- except _TimeoutError as e:
- raise TimeoutError(e.message) from e
- except _RequestError as e:
- raise HTTPException(e.message) from e
- def getresponse(self) -> BaseHTTPResponse:
- if self._response is not None:
- return EmscriptenHttpResponseWrapper(
- internal_response=self._response,
- url=self._response.request.url,
- connection=self,
- )
- else:
- raise ResponseNotReady()
- def close(self) -> None:
- self._closed = True
- self._response = None
- @property
- def is_closed(self) -> bool:
- """Whether the connection either is brand new or has been previously closed.
- If this property is True then both ``is_connected`` and ``has_connected_to_proxy``
- properties must be False.
- """
- return self._closed
- @property
- def is_connected(self) -> bool:
- """Whether the connection is actively connected to any origin (proxy or target)"""
- return True
- @property
- def has_connected_to_proxy(self) -> bool:
- """Whether the connection has successfully connected to its proxy.
- This returns False if no proxy is in use. Used to determine whether
- errors are coming from the proxy layer or from tunnelling to the target origin.
- """
- return False
- class EmscriptenHTTPSConnection(EmscriptenHTTPConnection):
- default_port = port_by_scheme["https"]
- # all this is basically ignored, as browser handles https
- cert_reqs: int | str | None = None
- ca_certs: str | None = None
- ca_cert_dir: str | None = None
- ca_cert_data: None | str | bytes = None
- cert_file: str | None
- key_file: str | None
- key_password: str | None
- ssl_context: typing.Any | None
- ssl_version: int | str | None = None
- ssl_minimum_version: int | None = None
- ssl_maximum_version: int | None = None
- assert_hostname: None | str | typing.Literal[False]
- assert_fingerprint: str | None = None
- def __init__(
- self,
- host: str,
- port: int = 0,
- *,
- timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
- source_address: tuple[str, int] | None = None,
- blocksize: int = 16384,
- socket_options: (
- None | _TYPE_SOCKET_OPTIONS
- ) = HTTPConnection.default_socket_options,
- proxy: Url | None = None,
- proxy_config: ProxyConfig | None = None,
- cert_reqs: int | str | None = None,
- assert_hostname: None | str | typing.Literal[False] = None,
- assert_fingerprint: str | None = None,
- server_hostname: str | None = None,
- ssl_context: typing.Any | None = None,
- ca_certs: str | None = None,
- ca_cert_dir: str | None = None,
- ca_cert_data: None | str | bytes = None,
- ssl_minimum_version: int | None = None,
- ssl_maximum_version: int | None = None,
- ssl_version: int | str | None = None, # Deprecated
- cert_file: str | None = None,
- key_file: str | None = None,
- key_password: str | None = None,
- ) -> None:
- super().__init__(
- host,
- port=port,
- timeout=timeout,
- source_address=source_address,
- blocksize=blocksize,
- socket_options=socket_options,
- proxy=proxy,
- proxy_config=proxy_config,
- )
- self.scheme = "https"
- self.key_file = key_file
- self.cert_file = cert_file
- self.key_password = key_password
- self.ssl_context = ssl_context
- self.server_hostname = server_hostname
- self.assert_hostname = assert_hostname
- self.assert_fingerprint = assert_fingerprint
- self.ssl_version = ssl_version
- self.ssl_minimum_version = ssl_minimum_version
- self.ssl_maximum_version = ssl_maximum_version
- self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
- self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
- self.ca_cert_data = ca_cert_data
- self.cert_reqs = None
- # The browser will automatically verify all requests.
- # We have no control over that setting.
- self.is_verified = True
- def set_cert(
- self,
- key_file: str | None = None,
- cert_file: str | None = None,
- cert_reqs: int | str | None = None,
- key_password: str | None = None,
- ca_certs: str | None = None,
- assert_hostname: None | str | typing.Literal[False] = None,
- assert_fingerprint: str | None = None,
- ca_cert_dir: str | None = None,
- ca_cert_data: None | str | bytes = None,
- ) -> None:
- pass
- # verify that this class implements BaseHTTP(s) connection correctly
- if typing.TYPE_CHECKING:
- _supports_http_protocol: BaseHTTPConnection = EmscriptenHTTPConnection("", 0)
- _supports_https_protocol: BaseHTTPSConnection = EmscriptenHTTPSConnection("", 0)
|