]> git.mxchange.org Git - flightgear.git/commitdiff
Initial work for a PKG http service
authorTorsten Dreyer <torsten@ŧ3r.de>
Mon, 16 Feb 2015 21:58:17 +0000 (22:58 +0100)
committerTorsten Dreyer <torsten@ŧ3r.de>
Tue, 17 Feb 2015 11:06:50 +0000 (12:06 +0100)
src/Network/HTTPClient.cxx
src/Network/http/CMakeLists.txt
src/Network/http/PkgUriHandler.cxx [new file with mode: 0644]
src/Network/http/PkgUriHandler.hxx [new file with mode: 0644]
src/Network/http/httpd.cxx

index de6a3d11f75b48202fd204136097395d998e747e..cda73102fc8a9ea3030aee5e360d394d8143cea5 100644 (file)
@@ -146,7 +146,7 @@ void FGHTTPClient::init()
       // always show this message
       SG_LOG(SG_GENERAL, SG_ALERT, "default catalog not found, installing...");
       pkg::Catalog::createFromUrl(packageRoot,
-          "http://fgfs.goneabitbursar.com/pkg/" FLIGHTGEAR_VERSION "/default-catalog.xml");
+          "http://localhost:8080/default-catalog.xml");
     }
     
     // start a refresh now
index c2e02f86535d33ca37682487e42695810207d24a..44078faf10739524777165bb2d21f34f5a4a7ce1 100644 (file)
@@ -5,6 +5,7 @@ set(SOURCES
        ScreenshotUriHandler.cxx
        PropertyUriHandler.cxx
        JsonUriHandler.cxx
+       PkgUriHandler.cxx
        RunUriHandler.cxx
        NavdbUriHandler.cxx
        PropertyChangeWebsocket.cxx
@@ -18,6 +19,7 @@ set(HEADERS
        ScreenshotUriHandler.hxx
        PropertyUriHandler.hxx
        JsonUriHandler.hxx
+       PkgUriHandler.hxx
        RunUriHandler.hxx
        NavdbUriHandler.hxx
        HTTPRequest.hxx
diff --git a/src/Network/http/PkgUriHandler.cxx b/src/Network/http/PkgUriHandler.cxx
new file mode 100644 (file)
index 0000000..7488a7c
--- /dev/null
@@ -0,0 +1,227 @@
+// PkgUriHandler.cxx -- service for the package system
+//
+// Written by Torsten Dreyer, started February 2015.
+//
+// Copyright (C) 2014  Torsten Dreyer
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+#include "PkgUriHandler.hxx"
+#include <3rdparty/cjson/cJSON.h>
+
+#include <simgear/package/Root.hxx>
+#include <simgear/package/Catalog.hxx>
+#include <simgear/package/Delegate.hxx>
+#include <simgear/package/Install.hxx>
+#include <simgear/package/Package.hxx>
+
+#include <Main/fg_props.hxx>
+
+using std::string;
+
+namespace flightgear {
+namespace http {
+
+/*
+url: /pkg/command/args
+
+Examples:
+/pkg/path
+
+Input:
+{
+  command: "command",
+  args: {
+  }
+}
+
+Output:
+{
+}
+*/
+
+static cJSON * StringListToJson( const string_list & l )
+{
+  cJSON * jsonArray = cJSON_CreateArray();
+  for( string_list::const_iterator it = l.begin(); it != l.end(); ++it )
+      cJSON_AddItemToArray(jsonArray, cJSON_CreateString((*it).c_str()) );
+  return jsonArray;
+}
+
+static cJSON * PackageToJson( simgear::pkg::Package * p )
+{
+  cJSON * json = cJSON_CreateObject();
+  if( p ) {
+    cJSON_AddItemToObject(json, "id", cJSON_CreateString( p->id().c_str() ));
+    cJSON_AddItemToObject(json, "name", cJSON_CreateString( p->name().c_str() ));
+    cJSON_AddItemToObject(json, "description", cJSON_CreateString( p->description().c_str() ));
+    cJSON_AddItemToObject(json, "installed", cJSON_CreateBool( p->isInstalled() ));
+    cJSON_AddItemToObject(json, "thumbnails", StringListToJson( p->thumbnailUrls() ));
+    cJSON_AddItemToObject(json, "variants", StringListToJson( p->variants() ));
+    cJSON_AddItemToObject(json, "revision", cJSON_CreateNumber( p->revision() ));
+    cJSON_AddItemToObject(json, "fileSize", cJSON_CreateNumber( p->fileSizeBytes() ));
+    cJSON_AddItemToObject(json, "author", cJSON_CreateString( p->getLocalisedProp("author").c_str() ));
+    cJSON_AddItemToObject(json, "ratingFdm", cJSON_CreateString( p->getLocalisedProp("rating/FDM").c_str() ));
+    cJSON_AddItemToObject(json, "ratingCockpit", cJSON_CreateString( p->getLocalisedProp("rating/cockpit").c_str() ));
+    cJSON_AddItemToObject(json, "ratingModel", cJSON_CreateString( p->getLocalisedProp("rating/model").c_str() ));
+    cJSON_AddItemToObject(json, "ratingSystems", cJSON_CreateString( p->getLocalisedProp("rating/systems").c_str() ));
+  }
+  return json;
+}
+
+static cJSON * PackageListToJson( const simgear::pkg::PackageList & l )
+{
+  cJSON * jsonArray = cJSON_CreateArray();
+  for( simgear::pkg::PackageList::const_iterator it = l.begin(); it != l.end(); ++it ) {
+    cJSON_AddItemToArray(jsonArray, PackageToJson(*it) );
+  }
+  return jsonArray;
+}
+
+static cJSON * CatalogToJson( simgear::pkg::Catalog * c )
+{
+  cJSON * json = cJSON_CreateObject();
+  if( c ) {
+    cJSON_AddItemToObject(json, "id", cJSON_CreateString( c->id().c_str() ));
+    cJSON_AddItemToObject(json, "installRoot", cJSON_CreateString( c->installRoot().str().c_str() ));
+    cJSON_AddItemToObject(json, "url", cJSON_CreateString( c->url().c_str() ));
+    cJSON_AddItemToObject(json, "description", cJSON_CreateString( c->description().c_str() ));
+    cJSON_AddItemToObject(json, "packages", PackageListToJson(c->packages()) );
+    cJSON_AddItemToObject(json, "needingUpdate", PackageListToJson(c->packagesNeedingUpdate()) );
+    cJSON_AddItemToObject(json, "installed", PackageListToJson(c->installedPackages()) );
+  }
+  return json;
+}
+
+
+static string PackageRootCommand( simgear::pkg::Root* packageRoot, const string & command, const string & args )
+{
+  cJSON * json = cJSON_CreateObject();
+
+  if( command == "path" ) {
+
+    cJSON_AddItemToObject(json, "path", cJSON_CreateString( packageRoot->path().str().c_str() ));
+
+  } else if( command == "version" ) {
+
+    cJSON_AddItemToObject(json, "version", cJSON_CreateString( packageRoot->catalogVersion().c_str() ));
+
+  } else if( command == "refresh" ) {
+    packageRoot->refresh(true);
+    cJSON_AddItemToObject(json, "refresh", cJSON_CreateString( "OK" ));
+
+  } else if( command == "catalogs" ) {
+
+    cJSON * jsonArray = cJSON_CreateArray();
+    simgear::pkg::CatalogList catalogList = packageRoot->catalogs();
+    for( simgear::pkg::CatalogList::iterator it = catalogList.begin(); it != catalogList.end(); ++it ) {
+      cJSON_AddItemToArray(jsonArray, CatalogToJson(*it) );
+    }
+    cJSON_AddItemToObject(json, "catalogs", jsonArray );
+
+  } else if( command == "packageById" ) {
+
+    simgear::pkg::PackageRef p = packageRoot->getPackageById(args);
+    cJSON_AddItemToObject(json, "package", PackageToJson( p ));
+
+  } else if( command == "catalogById" ) {
+
+    simgear::pkg::CatalogRef p = packageRoot->getCatalogById(args);
+    cJSON_AddItemToObject(json, "catalog", CatalogToJson( p ));
+
+  } else if( command == "search" ) {
+
+    SGPropertyNode_ptr query(new SGPropertyNode);
+    simgear::pkg::PackageList packageList = packageRoot->packagesMatching(query);
+    cJSON_AddItemToObject(json, "packages", PackageListToJson(packageList) );
+
+  } else if( command == "install" ) {
+
+         simgear::pkg::PackageRef package = packageRoot->getPackageById(args);
+         if( NULL == package ) {
+                 SG_LOG(SG_NETWORK,SG_WARN,"Can't install package '" << args << "', package not found" );
+                   cJSON_Delete( json );
+                   return string("");
+         }
+         package->existingInstall();
+
+  } else {
+    SG_LOG( SG_NETWORK,SG_WARN, "Unhandled pkg command : '" << command << "'" );
+    cJSON_Delete( json );
+    return string("");
+  }
+
+  char * jsonString = cJSON_PrintUnformatted( json );
+  string reply(jsonString);
+  free( jsonString );
+  cJSON_Delete( json );
+  return reply;
+}
+
+static  string findCommand( const string & uri, string & outArgs )
+{
+  size_t n = uri.find_first_of('/');
+  if( n == string::npos ) outArgs = string("");
+  else outArgs = uri.substr( n+1 );
+  return uri.substr( 0, n );
+}
+
+bool PkgUriHandler::handleRequest( const HTTPRequest & request, HTTPResponse & response, Connection * connection )
+{
+  response.Header["Content-Type"] = "application/json; charset=UTF-8";
+  response.Header["Access-Control-Allow-Origin"] = "*";
+  response.Header["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST";
+  response.Header["Access-Control-Allow-Headers"] = "Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token";
+
+  if( request.Method == "OPTIONS" ){
+      return true; // OPTIONS only needs the headers
+  }
+
+  simgear::pkg::Root* packageRoot = globals->packageRoot();
+  if( NULL == packageRoot ) {
+    SG_LOG( SG_NETWORK,SG_WARN, "NO PackageRoot" );
+    response.StatusCode = 500;
+    response.Content = "{}";
+    return true; 
+  }
+
+  string argString;
+  string command = findCommand( string(request.Uri).substr(getUri().size()), argString );
+  
+
+  SG_LOG(SG_NETWORK,SG_INFO, "Request is for command '"  << command << "' with arg='" << argString << "'" );
+
+  if( request.Method == "GET" ){
+  } else if( request.Method == "POST" ) {
+  } else {
+    SG_LOG(SG_NETWORK,SG_INFO, "PkgUriHandler: invalid request method '" << request.Method << "'" );
+    response.Header["Allow"] = "OPTIONS, GET, POST";
+    response.StatusCode = 405;
+    response.Content = "{}";
+    return true; 
+  }
+
+  response.Content = PackageRootCommand( packageRoot, command, argString );
+  if( response.Content.empty() ) {
+    response.StatusCode = 404;
+    response.Content = "{}";
+  }
+  return true; 
+}
+
+} // namespace http
+} // namespace flightgear
+
diff --git a/src/Network/http/PkgUriHandler.hxx b/src/Network/http/PkgUriHandler.hxx
new file mode 100644 (file)
index 0000000..05d58be
--- /dev/null
@@ -0,0 +1,40 @@
+// PkgUriHandler.hxx -- service for the package system
+//
+// Written by Torsten Dreyer, started February 2015.
+//
+// Copyright (C) 2014  Torsten Dreyer
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#ifndef __FG_PKG_URI_HANDLER_HXX
+#define __FG_PKG_URI_HANDLER_HXX
+
+#include "urihandler.hxx"
+#include <simgear/props/props.hxx>
+
+namespace flightgear {
+namespace http {
+
+class PkgUriHandler : public URIHandler {
+public:
+  PkgUriHandler( const char * uri = "/pkg/" ) : URIHandler( uri  ) {}
+  virtual bool handleRequest( const HTTPRequest & request, HTTPResponse & response, Connection * connection );
+private:
+};
+
+} // namespace http
+} // namespace flightgear
+
+#endif //#define __FG_PKG_URI_HANDLER_HXX
index 38860930dd6e706cb40d96aa9c28160fc2dcbd9e..829acf69a8399da018b9752489fd10a985b5956c 100644 (file)
@@ -24,6 +24,7 @@
 #include "ScreenshotUriHandler.hxx"
 #include "PropertyUriHandler.hxx"
 #include "JsonUriHandler.hxx"
+#include "PkgUriHandler.hxx"
 #include "RunUriHandler.hxx"
 #include "NavdbUriHandler.hxx"
 #include "PropertyChangeObserver.hxx"
@@ -451,6 +452,13 @@ void MongooseHttpd::init()
       _uriHandler.push_back(new flightgear::http::JsonUriHandler(uri));
     }
 
+//#ifdef ENABLE_PACKAGE_SYSTEM
+    if ((uri = n->getStringValue("pkg"))[0] != 0) {
+      SG_LOG(SG_NETWORK, SG_INFO, "httpd: adding pkg uri handler at " << uri);
+      _uriHandler.push_back(new flightgear::http::PkgUriHandler(uri));
+    }
+//#endif
+
     if ((uri = n->getStringValue("run"))[0] != 0) {
       SG_LOG(SG_NETWORK, SG_INFO, "httpd: adding run uri handler at " << uri);
       _uriHandler.push_back(new flightgear::http::RunUriHandler(uri));