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