]> granicus.if.org Git - pdns/commitdiff
ws: clean up how we return errors as JSON
authorChristian Hofstaedtler <christian@hofstaedtler.name>
Sat, 5 Oct 2013 13:24:52 +0000 (15:24 +0200)
committerChristian Hofstaedtler <christian@hofstaedtler.name>
Mon, 14 Oct 2013 13:16:52 +0000 (15:16 +0200)
pdns/json.cc
pdns/json.hh
pdns/json_ws.cc
pdns/ws.cc

index 2f350460090be4bcc33921dd526b9e1fa4b9b705..59e44386aebcf50129547c050774222b22cde28e 100644 (file)
@@ -76,6 +76,15 @@ string returnJSONObject(const map<string, string>& items)
   return makeStringFromDocument(doc);
 }
 
+string returnJSONError(const string& error)
+{
+  Document doc;
+  doc.SetObject();
+  Value jerror(error.c_str(), doc.GetAllocator()); // copy
+  doc.AddMember("error", jerror, doc.GetAllocator());
+  return makeStringFromDocument(doc);
+}
+
 string makeLogGrepJSON(map<string, string>& varmap, const string& fname, const string& prefix)
 {
   FILE* ptr = fopen(fname.c_str(), "r");
index dd61ed74ff186a31e649a2b56a61a85baabee0a8..00e573e35c13c460b366ab0a46bbc0a16a9f8f23 100644 (file)
@@ -22,5 +22,6 @@
 #include "rapidjson/document.h"
 
 std::string returnJSONObject(const std::map<std::string, std::string>& items);
+std::string returnJSONError(const std::string& error);
 std::string makeLogGrepJSON(std::map<std::string, std::string>& varmap, const std::string& fname, const std::string& prefix="");
 std::string makeStringFromDocument(const rapidjson::Document& doc);
index d63c6416757de5448b92b6c9ee05db7685800494..c7cd8b6856216cfe19989d7a816e1ea748db020a 100644 (file)
@@ -203,9 +203,7 @@ string JWebserver::handleRequest(const string &method, const string &uri, const
       doc.AddMember("zone", root, doc.GetAllocator());
       content += makeStringFromDocument(doc);
     } else {
-      map<string, string> err;
-      err["error"] = "Could not find domain '"+varmap["zone"]+"'";
-      content += returnJSONObject(err);
+      content += returnJSONError("Could not find domain '"+varmap["zone"]+"'");
     }
   }
   else if(command == "flush-cache") {
index 0d848a7845d3bb61b8bf13b04f7c686be751a0b7..1ea34b983d287cf158078a7a7d2225424a12f2d6 100644 (file)
@@ -280,11 +280,8 @@ static int intFromJson(const Value& val) {
 static string getZone(const string& zonename) {
   UeberBackend B;
   DomainInfo di;
-  if(!B.getDomainInfo(zonename, di)) {
-    map<string, string> err;
-    err["error"] = "Could not find domain '"+zonename+"'";
-    return returnJSONObject(err);
-  }
+  if(!B.getDomainInfo(zonename, di))
+    return returnJSONError("Could not find domain '"+zonename+"'");
 
   Document doc;
   doc.SetObject();
@@ -336,24 +333,15 @@ static string createOrUpdateZone(const string& zonename, bool onlyCreate, varmap
   DomainInfo di;
 
   bool exists = B.getDomainInfo(zonename, di);
-  if(exists && onlyCreate) {
-    map<string, string> err;
-    err["error"] = "Domain '"+zonename+"' already exists";
-    return returnJSONObject(err);
-  }
+  if(exists && onlyCreate)
+    return returnJSONError("Domain '"+zonename+"' already exists");
 
   if(!exists) {
-    if(!B.createDomain(zonename, &di.backend)) {
-      map<string, string> err;
-      err["error"] = "Creating domain '"+zonename+"' failed";
-      return returnJSONObject(err);
-    }
+    if(!B.createDomain(zonename, &di.backend))
+      return returnJSONError("Creating domain '"+zonename+"' failed");
 
-    if(!B.getDomainInfo(zonename, di)) {
-      map<string, string> err;
-      err["error"] = "Creating domain '"+zonename+"' failed: lookup of domain ID failed";
-      return returnJSONObject(err);
-    }
+    if(!B.getDomainInfo(zonename, di))
+      return returnJSONError("Creating domain '"+zonename+"' failed: lookup of domain ID failed");
 
     // create SOA record so zone "really" exists
     DNSResourceRecord soa;
@@ -441,16 +429,13 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v
     return returnJSONObject(object);
   }
   else if(command == "pdns-control") {
-    if(method!="POST") {
-      map<string, string> m;
-      m["error"]="pdns-control requires a POST";
-      return returnJSONObject(m);
-    }
+    // TODO: turn this into a 405
+    if(method!="POST")
+      return returnJSONError("pdns-control requires a POST");
     // cout<<"post: "<<post<<endl;
     rapidjson::Document document;
-    if(document.Parse<0>(post.c_str()).HasParseError()) {
-      return "{\"error\": \"Unable to parse JSON\"}";
-    }
+    if(document.Parse<0>(post.c_str()).HasParseError())
+      return returnJSONError("Unable to parse JSON");
     // cout<<"Parameters: '"<<document["parameters"].GetString()<<"'\n";
     vector<string> parameters;
     stringtok(parameters, document["parameters"].GetString(), " \t");
@@ -471,15 +456,12 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v
     vector<string> parts;
     stringtok(parts, varmap["rest"], "/");
     if(parts.size() != 3) 
-      return "{\"error\": \"Could not parse rest parameter\"}";
+      return returnJSONError("Could not parse rest parameter");
     UeberBackend B;
     SOAData sd;
     sd.db = (DNSBackend*)-1;
-    if(!B.getSOA(parts[0], sd) || !sd.db) {
-      map<string, string> err;
-      err["error"]= "Could not find domain '"+parts[0]+"'";
-      return returnJSONObject(err);
-    }
+    if(!B.getSOA(parts[0], sd) || !sd.db)
+      return returnJSONError("Could not find domain '"+parts[0]+"'");
     
     QType qtype;
     qtype=parts[2];
@@ -516,9 +498,8 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v
     }
     else if(method=="POST") {
       rapidjson::Document document;
-      if(document.Parse<0>(post.c_str()).HasParseError()) {
-        return "{\"error\": \"Unable to parse JSON\"";
-      }
+      if(document.Parse<0>(post.c_str()).HasParseError())
+        return returnJSONError("Unable to parse JSON");
       
       DNSResourceRecord rr;
       vector<DNSResourceRecord> rrset;
@@ -544,9 +525,7 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v
         }
         catch(std::exception& e) 
         {
-          map<string, string> err;
-          err["error"]= "Following record had a problem: "+rr.qname+" IN " +rr.qtype.getName()+ " " + rr.content+": "+e.what();
-          return returnJSONObject(err);
+         return returnJSONError("Following record had a problem: "+rr.qname+" IN " +rr.qtype.getName()+ " " + rr.content+": "+e.what());
         }
       }
       // but now what
@@ -558,11 +537,8 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v
   }
   else if(command == "zone") {
     string zonename = varmap["zone"];
-    if (zonename.empty()) {
-      map<string, string> err;
-      err["error"] = "Must give zone parameter";
-      return returnJSONObject(err);
-    }
+    if (zonename.empty())
+      return returnJSONError("Must give zone parameter");
 
     if(method == "GET") {
       // get current zone
@@ -577,22 +553,15 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v
       // delete
       UeberBackend B;
       DomainInfo di;
-      if(!B.getDomainInfo(zonename, di)) {
-        map<string, string> err;
-        err["error"] = "Deleting domain '"+zonename+"' failed: domain does not exist";
-        return returnJSONObject(err);
-      }
-      if (!di.backend->deleteDomain(zonename)) {
-        map<string, string> err;
-        err["error"] = "Deleting domain '"+zonename+"' failed: backend delete failed/unsupported";
-        return returnJSONObject(err);
-      }
+      if(!B.getDomainInfo(zonename, di))
+       return returnJSONError("Deleting domain '"+zonename+"' failed: domain does not exist");
+      if(!di.backend->deleteDomain(zonename))
+       return returnJSONError("Deleting domain '"+zonename+"' failed: backend delete failed/unsupported");
       map<string, string> success; // empty success object
       return returnJSONObject(success);
     } else {
-      map<string, string> err;
-      err["error"] = "Method not allowed";
-      return returnJSONObject(err);
+      // TODO: turn this into a 405
+      return returnJSONError("Method not allowed");
     }
   }
   else if(command=="log-grep") {
@@ -630,9 +599,7 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v
     return makeStringFromDocument(doc);
   }
 
-  map<string, string> err;
-  err["error"] = "No or unknown command given";
-  return returnJSONObject(err);
+  return returnJSONError("No or unknown command given");
 }
 
 string StatWebServer::jsonstat(const string& method, const string& post, const map<string,string> &varmap, void *ptr, bool *custom)