add fallback
This commit is contained in:
parent
7e04edbc48
commit
fa34e459cb
5 changed files with 55 additions and 6 deletions
|
|
@ -6,6 +6,8 @@ import requests
|
|||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
|
||||
from utils.http_fallback import request_with_ssl_fallback
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CACHE_KEY_TEMPLATE = "proxy_upstream_openapi_schema_{service}"
|
||||
|
|
@ -37,7 +39,7 @@ def _fetch_service_schema(service, base_url, schema_path):
|
|||
|
||||
url = f"{base_url.rstrip('/')}{schema_path}"
|
||||
try:
|
||||
response = requests.get(url, timeout=FETCH_TIMEOUT_SECONDS)
|
||||
response = request_with_ssl_fallback("GET", url, timeout=FETCH_TIMEOUT_SECONDS)
|
||||
response.raise_for_status()
|
||||
schema = response.json()
|
||||
except (requests.RequestException, ValueError) as exc:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ from django.utils.decorators import method_decorator
|
|||
from django.views import View
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from utils.http_fallback import request_with_ssl_fallback
|
||||
|
||||
# Headers that must not be copied verbatim between hops (RFC 7230 6.1) plus
|
||||
# framing headers that HttpResponse recomputes itself.
|
||||
HOP_BY_HOP_HEADERS = {
|
||||
|
|
@ -54,9 +56,9 @@ class ServiceProxyView(View):
|
|||
target_url = f"{target_url}?{query_string}"
|
||||
|
||||
try:
|
||||
upstream = requests.request(
|
||||
method=request.method,
|
||||
url=target_url,
|
||||
upstream = request_with_ssl_fallback(
|
||||
request.method,
|
||||
target_url,
|
||||
headers=_incoming_headers(request),
|
||||
data=request.body,
|
||||
timeout=settings.SERVICE_REQUEST_TIMEOUT,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from httpx import Request
|
|||
from utils.clients.gooyal_accounts_client import AuthenticatedClient
|
||||
from utils.clients.gooyal_accounts_client.models import Account
|
||||
from utils.clients.gooyal_accounts_client.api.users import (users_api_users_details_retrieve)
|
||||
from utils.http_fallback import request_with_ssl_fallback, resolve_verify_ssl
|
||||
|
||||
|
||||
|
||||
|
|
@ -31,7 +32,7 @@ def login_as_client_credentials():
|
|||
}
|
||||
auth = (settings.OAUTH2_PROVIDER_CLIENT_ID, settings.OAUTH2_PROVIDER_CLIENT_SECRET)
|
||||
|
||||
response = requests.post(f'{settings.OAUTH2_PROVIDER_BASE_PUBLIC_URL}/token/',
|
||||
response = request_with_ssl_fallback('POST', f'{settings.OAUTH2_PROVIDER_BASE_PUBLIC_URL}/token/',
|
||||
data=data,
|
||||
auth=auth)
|
||||
print(response.content)
|
||||
|
|
@ -57,7 +58,9 @@ def log_response(response):
|
|||
|
||||
def get_client():
|
||||
access_token = login_as_client_credentials()['access_token']
|
||||
verify_ssl = resolve_verify_ssl(settings.ACCOUNTS_BASE_PUBLIC_URL)
|
||||
client = AuthenticatedClient(base_url=settings.ACCOUNTS_BASE_PUBLIC_URL, token=access_token,
|
||||
verify_ssl=verify_ssl,
|
||||
httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
|
||||
)
|
||||
return client
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from utils.clients.gooyal_advertising_client.api.crm.crm_application_tickets_lis
|
|||
from utils.clients.gooyal_advertising_client.api.suggestions.suggestions_suggest_list import sync as suggestions_suggest_list_sync
|
||||
from utils.clients.gooyal_advertising_client.models.paginated_ticket_list import PaginatedTicketList
|
||||
from utils.clients.gooyal_advertising_client.models.paginated_suggestion_list import PaginatedSuggestionList
|
||||
from utils.http_fallback import request_with_ssl_fallback, resolve_verify_ssl
|
||||
|
||||
|
||||
def login_as_client_credentials():
|
||||
|
|
@ -27,7 +28,8 @@ def login_as_client_credentials():
|
|||
}
|
||||
auth = (settings.OAUTH2_PROVIDER_CLIENT_ID, settings.OAUTH2_PROVIDER_CLIENT_SECRET)
|
||||
|
||||
response = requests.post(
|
||||
response = request_with_ssl_fallback(
|
||||
'POST',
|
||||
f'{settings.OAUTH2_PROVIDER_BASE_PUBLIC_URL}/token/',
|
||||
data=data,
|
||||
auth=auth,
|
||||
|
|
@ -56,9 +58,11 @@ def log_response(response):
|
|||
|
||||
def get_client():
|
||||
access_token = login_as_client_credentials()['access_token']
|
||||
verify_ssl = resolve_verify_ssl(settings.ADVERTISING_BASE_PUBLIC_URL)
|
||||
client = AuthenticatedClient(
|
||||
base_url=settings.ADVERTISING_BASE_PUBLIC_URL,
|
||||
token=access_token,
|
||||
verify_ssl=verify_ssl,
|
||||
httpx_args={
|
||||
'event_hooks': {
|
||||
'request': [log_request],
|
||||
|
|
|
|||
38
utils/http_fallback.py
Normal file
38
utils/http_fallback.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
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
|
||||
Loading…
Add table
Reference in a new issue