1 // JsonUriHandler.cxx -- json interface to the property tree
3 // Written by Torsten Dreyer, started April 2014.
5 // Copyright (C) 2014 Torsten Dreyer
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "JsonUriHandler.hxx"
23 #include "jsonprops.hxx"
24 #include <Main/fg_props.hxx>
28 namespace flightgear {
31 bool JsonUriHandler::handleRequest( const HTTPRequest & request, HTTPResponse & response, Connection * connection )
33 response.Header["Content-Type"] = "application/json; charset=UTF-8";
34 response.Header["Access-Control-Allow-Origin"] = "*";
35 response.Header["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST";
36 response.Header["Access-Control-Allow-Headers"] = "Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token";
38 if( request.Method == "OPTIONS" ){
39 return true; // OPTIONS only needs the headers
42 if( request.Method == "GET" ){
44 // max recursion depth
45 int depth = atoi(request.RequestVariables.get("d").c_str());
46 if( depth < 1 ) depth = 1; // at least one level
48 // pretty print (y) or compact print (default)
49 bool indent = request.RequestVariables.get("i") == "y";
50 bool timestamp = request.RequestVariables.get("t") == "y";
52 SGPropertyNode_ptr node = getRequestedNode(request );
53 if( false == node.valid() ) {
54 response.StatusCode = 404;
55 response.Content = "{}";
59 response.Content = JSON::toJsonString( indent, node, depth, timestamp ? fgGetDouble("/sim/time/elapsed-sec") : -1.0 );
64 if( request.Method == "POST" ) {
65 SGPropertyNode_ptr node = getRequestedNode(request );
66 if( false == node.valid() ) {
67 response.StatusCode = 404;
68 response.Content = "{}";
72 SG_LOG(SG_NETWORK,SG_INFO, "JsonUriHandler: setting property from'" << request.Content << "'" );
73 cJSON * json = cJSON_Parse( request.Content.c_str() );
75 JSON::toProp( json, node );
79 response.Content = "{}";
83 SG_LOG(SG_NETWORK,SG_INFO, "JsonUriHandler: invalid request method '" << request.Method << "'" );
84 response.Header["Allow"] = "OPTIONS, GET, POST";
85 response.StatusCode = 405;
86 response.Content = "{}";
91 SGPropertyNode_ptr JsonUriHandler::getRequestedNode(const HTTPRequest & request)
93 SG_LOG(SG_NETWORK,SG_INFO, "JsonUriHandler: request is '" << request.Uri << "'" );
94 string propertyPath = request.Uri;
95 propertyPath = propertyPath.substr( getUri().size() );
97 // skip trailing '/' - not very efficient but shouldn't happen too often
98 while( false == propertyPath.empty() && propertyPath[ propertyPath.length()-1 ] == '/' )
99 propertyPath = propertyPath.substr(0,propertyPath.length()-1);
101 SGPropertyNode_ptr reply = fgGetNode( string("/") + propertyPath );
102 if( false == reply.valid() ) {
103 SG_LOG(SG_NETWORK,SG_WARN, "JsonUriHandler: requested node not found: '" << propertyPath << "'");
110 } // namespace flightgear