From ed8ec8f092cadb94e5ebb4fdcdaf3102074ee31a Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <torsten@t3r.de> Date: Fri, 7 Mar 2014 21:53:51 +0100 Subject: [PATCH] JSON: make the response configurable, set encoding add request parameter 'i' and 'd' if i=y, indent the output to make it human readable if i is missing or anything else, send the output unformatted to save bandwith 'd' defines recursion depth with a default of 1 to show the requested node and the immediate childs (if it has any) call /json/?i=y&d=999 for a complete property tree backup (use with caution!) Also set the encoding to UTF-8 as required per RFC 4627 --- src/Network/http/JsonUriHandler.cxx | 40 +++++++++++++++++------------ 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/Network/http/JsonUriHandler.cxx b/src/Network/http/JsonUriHandler.cxx index 3c67e8546..22e18d0ba 100644 --- a/src/Network/http/JsonUriHandler.cxx +++ b/src/Network/http/JsonUriHandler.cxx @@ -48,19 +48,26 @@ static const char * getPropertyTypeString( simgear::props::Type type ) } } -static cJSON * PropToJson( SGPropertyNode_ptr n ) +static cJSON * PropToJson( SGPropertyNode_ptr n, int depth ) { - cJSON * jsonProp = cJSON_CreateObject(); - cJSON_AddItemToObject(jsonProp, "path", cJSON_CreateString(n->getPath(true).c_str())); - cJSON_AddItemToObject(jsonProp, "name", cJSON_CreateString(n->getName())); - cJSON_AddItemToObject(jsonProp, "value", cJSON_CreateString(n->getStringValue())); - cJSON_AddItemToObject(jsonProp, "type", cJSON_CreateString(getPropertyTypeString(n->getType()))); - return jsonProp; + cJSON * json = cJSON_CreateObject(); + cJSON_AddItemToObject(json, "path", cJSON_CreateString(n->getPath(true).c_str())); + cJSON_AddItemToObject(json, "name", cJSON_CreateString(n->getName())); + cJSON_AddItemToObject(json, "value", cJSON_CreateString(n->getStringValue())); + cJSON_AddItemToObject(json, "type", cJSON_CreateString(getPropertyTypeString(n->getType()))); + + if( depth > 0 && n->nChildren() > 0 ) { + cJSON * jsonArray = cJSON_CreateArray(); + for( int i = 0; i < n->nChildren(); i++ ) + cJSON_AddItemToArray( jsonArray, PropToJson( n->getChild(i), depth-1 ) ); + cJSON_AddItemToObject( json, "children", jsonArray ); + } + return json; } bool JsonUriHandler::handleGetRequest( const HTTPRequest & request, HTTPResponse & response ) { - response.Header["Content-Type"] = "application/json; charset=ISO-8859-1"; + response.Header["Content-Type"] = "application/json; charset=UTF-8"; string propertyPath = request.Uri; @@ -77,6 +84,13 @@ bool JsonUriHandler::handleGetRequest( const HTTPRequest & request, HTTPResponse while( false == propertyPath.empty() && propertyPath[ propertyPath.length()-1 ] == '/' ) propertyPath = propertyPath.substr(0,propertyPath.length()-1); + // max recursion depth + int depth = atoi(request.RequestVariables.get("d").c_str()); + if( depth < 1 ) depth = 1; // at least one level + + // pretty print (y) or compact print (default) + bool indent = request.RequestVariables.get("i") == "y"; + SGPropertyNode_ptr node = fgGetNode( string("/") + propertyPath ); if( false == node.valid() ) { response.StatusCode = 400; @@ -86,15 +100,9 @@ bool JsonUriHandler::handleGetRequest( const HTTPRequest & request, HTTPResponse } - cJSON * json = PropToJson( node ); - if( node->nChildren() > 0 ) { - cJSON * jsonArray = cJSON_CreateArray(); - for( int i = 0; i < node->nChildren(); i++ ) - cJSON_AddItemToArray( jsonArray, PropToJson( node->getChild(i) ) ); - cJSON_AddItemToObject( json, "children", jsonArray ); - } + cJSON * json = PropToJson( node, depth ); - char * jsonString = cJSON_Print( json ); + char * jsonString = indent ? cJSON_Print( json ) : cJSON_PrintUnformatted( json ); response.Content = jsonString; free( jsonString ); cJSON_Delete( json );