]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Try harder to return response in the same type as the request. 15969/head
authorMiod Vallat <miod.vallat@powerdns.com>
Fri, 8 Aug 2025 06:31:22 +0000 (08:31 +0200)
committerMiod Vallat <miod.vallat@powerdns.com>
Fri, 8 Aug 2025 08:04:43 +0000 (10:04 +0200)
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 <miod.vallat@powerdns.com>
pdns/webserver.cc
regression-tests.api/test_Zones.py

index c65bce3ef0f9e76d88c02b4a4aa6ebd9b7048290..334f42356f0e13af8afae077a4d513e990fa6061 100644 (file)
@@ -268,9 +268,14 @@ void WebServer::handleRequest(HttpRequest& req, HttpResponse& resp) const
     SLOG(g_log<<Logger::Debug<<req.logprefix<<"Handling request \"" << req.url.path << "\"" << endl,
          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;
index 097faf8816b4c3676ed848abcd2273dce7590ef9..24a6ea11a66d431a4af6b76736e2a52ba92a43af 100644 (file)
@@ -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')