1 // ---------------------------------------------------------------------------- 2 // 3 // flxmlrpc Copyright (c) 2015 by W1HKJ, Dave Freese <iam_w1hkj@w1hkj.com> 4 // 5 // XmlRpc++ Copyright (c) 2002-2008 by Chris Morley 6 // 7 // This file is part of fldigi 8 // 9 // flxmlrpc is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU Lesser General Public License as published by 11 // the Free Software Foundation; either version 3 of the License, or 12 // (at your option) any later version. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 // ---------------------------------------------------------------------------- 17 18 #ifndef _XMLRPCSERVER_H_ 19 #define _XMLRPCSERVER_H_ 20 21 #if defined(_MSC_VER) 22 # pragma warning(disable:4786) // identifier was truncated in debug info 23 #endif 24 25 #include <map> 26 #include <string> 27 28 29 #include "XmlRpcDispatch.h" 30 #include "XmlRpcSource.h" 31 32 namespace XmlRpc { 33 34 extern std::string request_str; 35 extern std::string client_id; 36 37 // An abstract class supporting XML RPC methods 38 class XmlRpcServerMethod; 39 40 // Class representing connections to specific clients 41 class XmlRpcServerConnection; 42 43 // Class representing argument and result values 44 class XmlRpcValue; 45 46 47 //! A class to handle XML RPC requests 48 class XmlRpcServer : public XmlRpcSource { 49 public: 50 //! Create a server object. 51 XmlRpcServer(); 52 //! Destructor. 53 virtual ~XmlRpcServer(); 54 55 //! Specify whether introspection is enabled or not. Default is not enabled. 56 void enableIntrospection(bool enabled=true); 57 58 //! Add a command to the RPC server 59 void addMethod(XmlRpcServerMethod* method); 60 61 //! Remove a command from the RPC server 62 void removeMethod(XmlRpcServerMethod* method); 63 64 //! Remove a command from the RPC server by name 65 void removeMethod(const std::string& methodName); 66 67 //! Look up a method by name 68 XmlRpcServerMethod* findMethod(const std::string& name) const; 69 70 //! Create a socket, bind to the specified port, and 71 //! set it in listen mode to make it available for clients. 72 //! @param port The port to bind and listen on (zero to choose an arbitrary port) 73 bool bindAndListen(int port, int backlog = 5); 74 75 //! Get the port number this server is listening on. 76 int getPort(void) const; 77 78 //! Process client requests for the specified time (in seconds) 79 void work(double timeSeconds); 80 81 //! Temporarily stop processing client requests and exit the work() method. 82 void exit(); 83 84 //! Close all connections with clients and the socket file descriptor 85 void shutdown(); 86 87 //! Introspection support 88 void listMethods(XmlRpcValue& result); 89 90 91 //! Parses the request xml, runs the method, generates the response (header+xml). 92 //! Returns a fault response if an error occurs during method execution. 93 virtual std::string executeRequest(std::string const& request); 94 95 96 // XmlRpcSource interface implementation 97 98 //! Handle client connection requests 99 virtual unsigned handleEvent(unsigned eventType); 100 101 //! Remove a connection from the dispatcher 102 virtual void removeConnection(XmlRpcServerConnection*); 103 104 protected: 105 106 // Static data 107 static const char METHODNAME_TAG[]; 108 static const char PARAMS_TAG[]; 109 static const char PARAM_TAG[]; 110 111 static const std::string SYSTEM_MULTICALL; 112 static const std::string METHODNAME; 113 static const std::string PARAMS; 114 115 static const std::string FAULTCODE; 116 static const std::string FAULTSTRING; 117 118 //! Accept a client connection request 119 virtual void acceptConnection(); 120 121 //! Create a new connection object for processing requests from a specific client. 122 //! If the client is not authorized to connect, close the socket and return 0. 123 virtual XmlRpcServerConnection* createConnection(XmlRpcSocket::Socket socket); 124 125 //! Hand off a new connection object to a dispatcher. 126 virtual void dispatchConnection(XmlRpcServerConnection* sc); 127 128 129 //! Parse the methodName and parameters from the request. 130 //! @returns the methodName 131 std::string parseRequest(std::string const& request, XmlRpcValue& params); 132 133 //! Execute a named method with the specified params. 134 bool executeMethod(const std::string& methodName, XmlRpcValue& params, XmlRpcValue& result); 135 136 //! Execute multiple calls and return the results in an array. 137 //! System.multicall implementation 138 bool executeMulticall(const std::string& methodName, XmlRpcValue& params, XmlRpcValue& result); 139 140 //! Construct a response from the result XML. 141 std::string generateResponse(std::string const& resultXml); 142 143 //! Construct a fault response. 144 std::string generateFaultResponse(std::string const& msg, int errorCode = -1); 145 146 //! Return the appropriate headers for the response. 147 std::string generateHeader(std::string const& body); 148 149 150 151 //! Whether the introspection API is supported by this server 152 bool _introspectionEnabled; 153 154 //! Event dispatcher 155 XmlRpcDispatch _disp; 156 157 //! Collection of methods. This could be a set keyed on method name if we wanted... 158 typedef std::map< std::string, XmlRpcServerMethod* > MethodMap; 159 160 //! Registered RPC methods. 161 MethodMap _methods; 162 163 //! List all registered RPC methods (only available if introspection is enabled) 164 XmlRpcServerMethod* _listMethods; 165 166 //! Return help string for a specified method (only available if introspection is enabled) 167 XmlRpcServerMethod* _methodHelp; 168 169 }; 170 } // namespace XmlRpc 171 172 #endif //_XMLRPCSERVER_H_ 173