38 lines
1.5 KiB
Python
38 lines
1.5 KiB
Python
import logging
|
|
|
|
import requests
|
|
import urllib3
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
|
|
|
|
def request_with_ssl_fallback(method, url, **kwargs):
|
|
"""Issue a request; if it fails purely due to a TLS/SSL error (e.g. an
|
|
expired upstream certificate), retry the same request with certificate
|
|
verification disabled. Still encrypted, but no longer authenticates the
|
|
server -- only safe for known internal/staging hosts, never for
|
|
arbitrary user-supplied URLs."""
|
|
try:
|
|
return requests.request(method, url, **kwargs)
|
|
except requests.exceptions.SSLError:
|
|
logger.warning("TLS verification failed for %s; retrying with verification disabled", url)
|
|
return requests.request(method, url, **{**kwargs, "verify": False})
|
|
|
|
|
|
def resolve_verify_ssl(base_url, timeout=5):
|
|
"""Probe whether `base_url` currently presents a valid TLS certificate.
|
|
For callers stuck building an httpx-based client up front (e.g. the
|
|
generated SDK clients' `verify_ssl=`), whose requests happen lazily and
|
|
can't be retried after the fact."""
|
|
if not base_url.startswith("https://"):
|
|
return True
|
|
try:
|
|
requests.head(base_url, timeout=timeout)
|
|
return True
|
|
except requests.exceptions.SSLError:
|
|
logger.warning("TLS verification failed for %s; disabling verification for this client", base_url)
|
|
return False
|
|
except requests.exceptions.RequestException:
|
|
return True
|