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 _XMLRPCCLIENT_H_
19 #define _XMLRPCCLIENT_H_
20 
21 #if defined(_MSC_VER)
22 # pragma warning(disable:4786)    // identifier was truncated in debug info
23 #endif
24 
25 
26 #include <string>
27 
28 #include "XmlRpcDispatch.h"
29 #include "XmlRpcSource.h"
30 
31 namespace XmlRpc {
32 
33   extern std::string pname;
34 
35   extern void set_pname(std::string pn);
36 
37   // Arguments and results are represented by XmlRpcValues
38   class XmlRpcValue;
39 
40   //! A class to send XML RPC requests to a server and return the results.
41   class XmlRpcClient : public XmlRpcSource {
42   public:
43 
44     //! Construct a client to connect to the server at the specified host:port address
45     //!  @param host The name of the remote machine hosting the server, eg "myserver.mycompany.com"
46     //!  @param port The port on the remote machine where the server is listening
47     //!  @param uri  An optional string to be sent as the URI in the HTTP GET header
48     //! Note that the host is not a URL, do not prepend "http://" or other protocol specifiers.
49     XmlRpcClient(const char* host, int port, const char* uri=0);
50 
51     //! Construct a client to connect to the server at the specified host:port address including HTTP authentication
52     //!  @param host  The name of the remote machine hosting the server
53     //!  @param port  The port on the remote machine where the server is listening
54     //!  @param login The username passed to the server
55     //!  @param pass  The password passed to the server
56     //!  @param uri   An optional string to be sent as the URI in the HTTP GET header
57     XmlRpcClient(const char* host, int port, const char* login, const char* password, const char* uri=0);
58 
59     //! Destructor
60     virtual ~XmlRpcClient();
61 
62     //! Execute the named procedure on the remote server.
63     //!  @param method The name of the remote procedure to execute
64     //!  @param params An array of the arguments for the method
65     //!  @param result The result value to be returned to the client
66     //!  @param timeoutSeconds Seconds to wait for a response (defaults to forever)
67     //!  @return true if the request was sent and a result received
68     //!   (although the result might be a fault).
69     //!
70     //! Currently this is a synchronous (blocking) implementation (execute
71     //! does not return until it receives a response or an error). Use isFault()
72     //! to determine whether the result is a fault response.
73     bool execute(const char* method, XmlRpcValue const& params, XmlRpcValue& result, double timeoutSeconds = -1);
74 
75     //! Returns true if the result of the last execute() was a fault response.
isFault()76     bool isFault() const { return _isFault; }
77 
78     //! Return the host name of the server
host()79     const char* const host() const { return _host.c_str(); }
80 
81     //! Return the port
port()82     int port() const { return _port; }
83 
84     //! Return the URI
uri()85     const char* const uri() const { return _uri.c_str(); }
86 
87     // XmlRpcSource interface implementation
88     //! Close the connection
89     virtual void close();
90 
91     //! Handle server responses. Called by the event dispatcher during execute.
92     //!  @param eventType The type of event that occurred.
93     //!  @see XmlRpcDispatch::EventType
94     virtual unsigned handleEvent(unsigned eventType);
95 
96   protected:
97     // Execution processing helpers
98     virtual bool doConnect();
99     virtual bool setupConnection();
100 
101     virtual bool generateRequest(const char* method, XmlRpcValue const& params);
102     virtual std::string generateHeader(std::string const& body);
103     virtual bool writeRequest();
104     virtual bool readHeader();
105     virtual bool parseHeader();
106     virtual bool readResponse();
107     virtual bool parseResponse(XmlRpcValue& result);
108 
109     // Possible IO states for the connection
110     enum ClientConnectionState { NO_CONNECTION, CONNECTING, WRITE_REQUEST, READ_HEADER, READ_RESPONSE, IDLE };
111     ClientConnectionState _connectionState;
112 
113     // Server location
114     std::string _host;
115     std::string _uri;
116     int _port;
117 
118     // Login information for HTTP authentication
119     std::string _login;
120     std::string _password;
121 
122     // The xml-encoded request, http header of response, and response xml
123     std::string _request;
124     std::string _header;
125     std::string _response;
126 
127     // Number of times the client has attempted to send the request
128     int _sendAttempts;
129 
130     // Number of bytes of the request that have been written to the socket so far
131     int _bytesWritten;
132 
133     // True if we are currently executing a request. If you want to multithread,
134     // each thread should have its own client.
135     bool _executing;
136 
137     // True if the server closed the connection
138     bool _eof;
139 
140     // True if a fault response was returned by the server
141     bool _isFault;
142 
143     // Number of bytes expected in the response body (parsed from response header)
144     int _contentLength;
145 
146     // Event dispatcher
147     XmlRpcDispatch _disp;
148 
149   };	// class XmlRpcClient
150 
151 }	// namespace XmlRpc
152 
153 #endif	// _XMLRPCCLIENT_H_
154