| """ | |
| This file includes code adapted from HTTPX's utility module | |
| (https://github.com/encode/httpx/blob/336204f0121a9aefdebac5cacd81f912bafe8057/httpx/_utils.py). | |
| We implement custom proxy handling to support configurations like `socket_options`, | |
| which are not currently configurable through the HTTPX client. | |
| For more context, see: https://github.com/encode/httpx/discussions/3514 | |
| """ | |
| from __future__ import annotations | |
| import ipaddress | |
| from typing import Mapping | |
| from urllib.request import getproxies | |
| def is_ipv4_hostname(hostname: str) -> bool: | |
| try: | |
| ipaddress.IPv4Address(hostname.split("/")[0]) | |
| except Exception: | |
| return False | |
| return True | |
| def is_ipv6_hostname(hostname: str) -> bool: | |
| try: | |
| ipaddress.IPv6Address(hostname.split("/")[0]) | |
| except Exception: | |
| return False | |
| return True | |
| def get_environment_proxies() -> Mapping[str, str | None]: | |
| """ | |
| Gets the proxy mappings based on environment variables. | |
| We use our own logic to parse these variables, as HTTPX | |
| doesn’t allow full configuration of the underlying | |
| transport when proxies are set via environment variables. | |
| """ | |
| proxy_info = getproxies() | |
| mounts: dict[str, str | None] = {} | |
| for scheme in ("http", "https", "all"): | |
| if proxy_info.get(scheme): | |
| hostname = proxy_info[scheme] | |
| mounts[f"{scheme}://"] = hostname if "://" in hostname else f"http://{hostname}" | |
| no_proxy_hosts = [host.strip() for host in proxy_info.get("no", "").split(",")] | |
| for hostname in no_proxy_hosts: | |
| if hostname == "*": | |
| return {} | |
| elif hostname: | |
| if "://" in hostname: | |
| mounts[hostname] = None | |
| elif is_ipv4_hostname(hostname): | |
| mounts[f"all://{hostname}"] = None | |
| elif is_ipv6_hostname(hostname): | |
| mounts[f"all://[{hostname}]"] = None | |
| elif hostname.lower() == "localhost": | |
| mounts[f"all://{hostname}"] = None | |
| else: | |
| mounts[f"all://*{hostname}"] = None | |
| return mounts | |