From: Christian Hofstaedtler Date: Sat, 5 Oct 2013 13:24:52 +0000 (+0200) Subject: ws: clean up how we return errors as JSON X-Git-Tag: rec-3.6.0-rc1~416^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73301d73417580482441b2094e43b2d6749d29cd;p=pdns ws: clean up how we return errors as JSON --- diff --git a/pdns/json.cc b/pdns/json.cc index 2f3504600..59e44386a 100644 --- a/pdns/json.cc +++ b/pdns/json.cc @@ -76,6 +76,15 @@ string returnJSONObject(const map& 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& varmap, const string& fname, const string& prefix) { FILE* ptr = fopen(fname.c_str(), "r"); diff --git a/pdns/json.hh b/pdns/json.hh index dd61ed74f..00e573e35 100644 --- a/pdns/json.hh +++ b/pdns/json.hh @@ -22,5 +22,6 @@ #include "rapidjson/document.h" std::string returnJSONObject(const std::map& items); +std::string returnJSONError(const std::string& error); std::string makeLogGrepJSON(std::map& varmap, const std::string& fname, const std::string& prefix=""); std::string makeStringFromDocument(const rapidjson::Document& doc); diff --git a/pdns/json_ws.cc b/pdns/json_ws.cc index d63c64167..c7cd8b685 100644 --- a/pdns/json_ws.cc +++ b/pdns/json_ws.cc @@ -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 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") { diff --git a/pdns/ws.cc b/pdns/ws.cc index 0d848a784..1ea34b983 100644 --- a/pdns/ws.cc +++ b/pdns/ws.cc @@ -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 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 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 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 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 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.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: '"< parameters; stringtok(parameters, document["parameters"].GetString(), " \t"); @@ -471,15 +456,12 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v vector 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 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 rrset; @@ -544,9 +525,7 @@ static string jsonDispatch(const string& method, const string& post, varmap_t& v } catch(std::exception& e) { - map 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 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 err; - err["error"] = "Deleting domain '"+zonename+"' failed: domain does not exist"; - return returnJSONObject(err); - } - if (!di.backend->deleteDomain(zonename)) { - map 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 success; // empty success object return returnJSONObject(success); } else { - map 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 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 &varmap, void *ptr, bool *custom)