| """Simple requests package loader""" |
| |
| from __future__ import annotations |
| |
| import warnings |
| from typing import Any |
| from urllib.parse import urlsplit |
| |
| import requests |
| from urllib3.exceptions import InsecureRequestWarning |
| |
| import sphinx |
| |
| _USER_AGENT = (f'Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0 ' |
| f'Sphinx/{sphinx.__version__}') |
| |
| |
| def _get_tls_cacert(url: str, certs: str | dict[str, str] | None) -> str | bool: |
| """Get additional CA cert for a specific URL.""" |
| if not certs: |
| return True |
| elif isinstance(certs, (str, tuple)): |
| return certs |
| else: |
| hostname = urlsplit(url).netloc |
| if '@' in hostname: |
| _, hostname = hostname.split('@', 1) |
| |
| return certs.get(hostname, True) |
| |
| |
| def get(url: str, **kwargs: Any) -> requests.Response: |
| """Sends a GET request like requests.get(). |
| |
| This sets up User-Agent header and TLS verification automatically.""" |
| with _Session() as session: |
| return session.get(url, **kwargs) |
| |
| |
| def head(url: str, **kwargs: Any) -> requests.Response: |
| """Sends a HEAD request like requests.head(). |
| |
| This sets up User-Agent header and TLS verification automatically.""" |
| with _Session() as session: |
| return session.head(url, **kwargs) |
| |
| |
| class _Session(requests.Session): |
| def request( # type: ignore[override] |
| self, method: str, url: str, |
| _user_agent: str = '', |
| _tls_info: tuple[bool, str | dict[str, str] | None] = (), # type: ignore[assignment] |
| **kwargs: Any, |
| ) -> requests.Response: |
| """Sends a request with an HTTP verb and url. |
| |
| This sets up User-Agent header and TLS verification automatically.""" |
| headers = kwargs.setdefault('headers', {}) |
| headers.setdefault('User-Agent', _user_agent or _USER_AGENT) |
| if _tls_info: |
| tls_verify, tls_cacerts = _tls_info |
| verify = bool(kwargs.get('verify', tls_verify)) |
| kwargs.setdefault('verify', verify and _get_tls_cacert(url, tls_cacerts)) |
| else: |
| verify = kwargs.get('verify', True) |
| |
| if verify: |
| return super().request(method, url, **kwargs) |
| |
| with warnings.catch_warnings(): |
| # ignore InsecureRequestWarning if verify=False |
| warnings.filterwarnings("ignore", category=InsecureRequestWarning) |
| return super().request(method, url, **kwargs) |