| from __future__ import annotations |
|
|
| import os |
| import typing |
|
|
| |
| from http.client import HTTPException as HTTPException |
| 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 |
| |
| |
| 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, |
| |
| |
| |
| *, |
| chunked: bool = False, |
| preload_content: bool = True, |
| decode_content: bool = True, |
| enforce_content_length: bool = True, |
| ) -> None: |
| self._closed = False |
| if url.startswith("/"): |
| |
| 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"] |
| |
| 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, |
| 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 |
|
|
| |
| |
| 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 |
|
|
|
|
| |
| if typing.TYPE_CHECKING: |
| _supports_http_protocol: BaseHTTPConnection = EmscriptenHTTPConnection("", 0) |
| _supports_https_protocol: BaseHTTPSConnection = EmscriptenHTTPSConnection("", 0) |
|
|