From 5b4c719aa065b759aa5e9b7c5c99efe6820eec4f Mon Sep 17 00:00:00 2001 From: David Buxton Date: Tue, 8 Aug 2023 21:54:53 +0100 Subject: [PATCH] fix: Handle exceptions raised when fetching Django request data The Django helper calls `request.build_absolute_uri()`, but that may raise a DisallowedHost exception itself. Instead we catch any exception and log `None` as the URL. --- google/cloud/logging_v2/handlers/_helpers.py | 9 ++++++++- tests/unit/handlers/test__helpers.py | 13 +++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/google/cloud/logging_v2/handlers/_helpers.py b/google/cloud/logging_v2/handlers/_helpers.py index 32e70dfdd..43678ed0d 100644 --- a/google/cloud/logging_v2/handlers/_helpers.py +++ b/google/cloud/logging_v2/handlers/_helpers.py @@ -104,10 +104,17 @@ def get_request_data_from_django(): if request is None: return None, None, None, False + # Django can raise django.core.exceptions.DisallowedHost here for a + # malformed HTTP_HOST header. But we don't want to import Django modules. + try: + request_url = request.build_absolute_uri() + except Exception: + request_url = None + # build http_request http_request = { "requestMethod": request.method, - "requestUrl": request.build_absolute_uri(), + "requestUrl": request_url, "userAgent": request.META.get(_DJANGO_USERAGENT_HEADER), "protocol": request.META.get(_PROTOCOL_HEADER), } diff --git a/tests/unit/handlers/test__helpers.py b/tests/unit/handlers/test__helpers.py index 6a7ff245f..5eeae4ba4 100644 --- a/tests/unit/handlers/test__helpers.py +++ b/tests/unit/handlers/test__helpers.py @@ -242,6 +242,19 @@ def test_http_request_sparse(self): self.assertEqual(http_request["requestUrl"], expected_path) self.assertEqual(http_request["protocol"], "HTTP/1.1") + def test_invalid_host_header(self): + from django.test import RequestFactory + from google.cloud.logging_v2.handlers.middleware import request + + invalid_http_host = "testserver%7d" + django_request = RequestFactory().put("/", HTTP_HOST=invalid_http_host) + middleware = request.RequestMiddleware(None) + middleware(django_request) + http_request, *_ = self._call_fut() + self.assertEqual(http_request["requestMethod"], "PUT") + self.assertIsNone(http_request["requestUrl"]) + self.assertEqual(http_request["protocol"], "HTTP/1.1") + class Test_get_request_data(unittest.TestCase): @staticmethod