From d970ca9d3189dcc7a2d393628477b4e776748702 Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Fri, 8 Aug 2025 08:31:22 +0200 Subject: [PATCH] Try harder to return response in the same type as the request. We still heed the `accept' header to choose the preferred content type of the answer, but if it is missing, instead of defaulting to plain text, we try to match the content type of the request. This means that errors to json requests will now always get returned as json, unless the `accept' header requires a different type. Fixes: #7097 Signed-off-by: Miod Vallat --- pdns/webserver.cc | 11 ++++++++--- regression-tests.api/test_Zones.py | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pdns/webserver.cc b/pdns/webserver.cc index c65bce3ef0..334f42356f 100644 --- a/pdns/webserver.cc +++ b/pdns/webserver.cc @@ -268,9 +268,14 @@ void WebServer::handleRequest(HttpRequest& req, HttpResponse& resp) const SLOG(g_log<info(Logr::Debug, "Handling request")); - YaHTTP::strstr_map_t::iterator header; - - if ((header = req.headers.find("accept")) != req.headers.end()) { + // Decide which content type to use for the answer, based on the + // `accept' request header. If this header is missing, we try to + // reply with the same content type as the request. + auto header = req.headers.find("accept"); + if (header == req.headers.end()) { + header = req.headers.find("content-type"); + } + if (header != req.headers.end()) { // yaml wins over json, json wins over html if (header->second.find("application/x-yaml") != std::string::npos) { req.accept_yaml = true; diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 097faf8816..24a6ea11a6 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -282,6 +282,7 @@ class AuthZones(ApiTestCase, AuthZonesHelperMixin): data=json.dumps(payload), headers={'content-type': 'application/json'}) self.assertEqual(r.status_code, 409) # Conflict - already exists + self.assertIn("Conflict", r.json()['error']) def test_create_zone_with_soa_edit(self): name, payload, data = self.create_zone(soa_edit='INCEPTION-INCREMENT', soa_edit_api='SOA-EDIT-INCREASE') -- 2.47.3