From: Miod Vallat Date: Fri, 8 Aug 2025 06:31:22 +0000 (+0200) Subject: Try harder to return response in the same type as the request. X-Git-Tag: rec-5.4.0-alpha1~327^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d970ca9d3189dcc7a2d393628477b4e776748702;p=thirdparty%2Fpdns.git 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 --- 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')