| | 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) |
| |
|