BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
XmlRpc::XmlRpcClient Class Reference

A class to send XML RPC requests to a server and return the results. More...

#include <XmlRpcClient.h>

Inheritance diagram for XmlRpc::XmlRpcClient:

Public Member Functions

 XmlRpcClient (const char *host, int port, const char *uri=0)
virtual ~XmlRpcClient ()
 Destructor.
bool execute (const char *method, XmlRpcValue const &params, XmlRpcValue &result)
bool isFault () const
 Returns true if the result of the last execute() was a fault response.
virtual void close ()
 Close the connection.
virtual unsigned handleEvent (unsigned eventType)
Public Member Functions inherited from XmlRpc::XmlRpcSource
 XmlRpcSource (int fd=-1, bool deleteOnClose=false)
virtual ~XmlRpcSource ()
 Destructor.
int getfd () const
 Return the file descriptor being monitored.
void setfd (int fd)
 Specify the file descriptor to monitor.
bool getKeepOpen () const
 Return whether the file descriptor should be kept open if it is no longer monitored.
void setKeepOpen (bool b=true)
 Specify whether the file descriptor should be kept open if it is no longer monitored.

Static Public Attributes

static const char REQUEST_BEGIN []
static const char REQUEST_END_METHODNAME [] = "</methodName>\r\n"
static const char PARAMS_TAG [] = "<params>"
static const char PARAMS_ETAG [] = "</params>"
static const char PARAM_TAG [] = "<param>"
static const char PARAM_ETAG [] = "</param>"
static const char REQUEST_END [] = "</methodCall>\r\n"
static const char METHODRESPONSE_TAG [] = "<methodResponse>"
static const char FAULT_TAG [] = "<fault>"

Protected Types

enum  ClientConnectionState {
  NO_CONNECTION , CONNECTING , WRITE_REQUEST , READ_HEADER ,
  READ_RESPONSE , IDLE
}

Protected Member Functions

virtual bool doConnect ()
virtual bool setupConnection ()
virtual bool generateRequest (const char *method, XmlRpcValue const &params)
virtual std::string generateHeader (std::string const &body)
virtual bool writeRequest ()
virtual bool readHeader ()
virtual bool readResponse ()
virtual bool parseResponse (XmlRpcValue &result)

Protected Attributes

ClientConnectionState _connectionState
std::string _host
std::string _uri
int _port
std::string _request
std::string _header
std::string _response
int _sendAttempts
int _bytesWritten
bool _executing
bool _eof
bool _isFault
int _contentLength
XmlRpcDispatch _disp

Detailed Description

A class to send XML RPC requests to a server and return the results.

Definition at line 24 of file XmlRpcClient.h.

Member Enumeration Documentation

◆ ClientConnectionState

Enumerator
NO_CONNECTION 
CONNECTING 
WRITE_REQUEST 
READ_HEADER 
READ_RESPONSE 
IDLE 

Definition at line 84 of file XmlRpcClient.h.

Constructor & Destructor Documentation

◆ XmlRpcClient()

XmlRpcClient::XmlRpcClient ( const char * host,
int port,
const char * uri = 0 )

Construct a client to connect to the server at the specified host:port address

Parameters
hostThe name of the remote machine hosting the server
portThe port on the remote machine where the server is listening
uriAn optional string to be sent as the URI in the HTTP GET header

Definition at line 27 of file XmlRpcClient.cpp.

27 {
28 XmlRpcUtil::log( 1, "XmlRpcClient new client: host %s, port %d.", host, port );
29
30 _host = host;
31 _port = port;
32 if ( uri ) _uri = uri;
33 else _uri = "/RPC2";
35 _executing = false;
36 _eof = false;
37
38 // Default to keeping the connection open until an explicit close is done
40}
ClientConnectionState _connectionState
void setKeepOpen(bool b=true)
Specify whether the file descriptor should be kept open if it is no longer monitored.
static void log(int level, const char *fmt,...)
Dump messages somewhere.

◆ ~XmlRpcClient()

XmlRpcClient::~XmlRpcClient ( )
virtual

Destructor.

Definition at line 42 of file XmlRpcClient.cpp.

42{}

Member Function Documentation

◆ close()

void XmlRpcClient::close ( )
virtual

Close the connection.

Reimplemented from XmlRpc::XmlRpcSource.

Definition at line 45 of file XmlRpcClient.cpp.

45 {
46 XmlRpcUtil::log( 4, "XmlRpcClient::close: fd %d.", getfd() );
48 _disp.exit();
49 _disp.removeSource( this );
51}
XmlRpcDispatch _disp
virtual void close()
int getfd() const
Return the file descriptor being monitored.

Referenced by doConnect(), and setupConnection().

◆ doConnect()

bool XmlRpcClient::doConnect ( )
protectedvirtual

Definition at line 149 of file XmlRpcClient.cpp.

149 {
150 int fd = XmlRpcSocket::socket();
151 if ( fd < 0 )
152 {
153 XmlRpcUtil::error( "Error in XmlRpcClient::doConnect: Could not create socket (%s).",
155 return false;
156 }
157
158 XmlRpcUtil::log( 3, "XmlRpcClient::doConnect: fd %d.", fd );
159 this->setfd( fd );
160
161 // Don't block on connect/reads/writes
162 if ( !XmlRpcSocket::setNonBlocking( fd ) )
163 {
164 this->close();
166 "Error in XmlRpcClient::doConnect: Could not set socket to non-blocking IO mode (%s).",
168 return false;
169 }
170
171 if ( !XmlRpcSocket::connect( fd, _host, _port ) )
172 {
173 this->close();
174 XmlRpcUtil::error( "Error in XmlRpcClient::doConnect: Could not connect to server (%s).",
176 return false;
177 }
178
179 return true;
180}
virtual void close()
Close the connection.
static int socket()
Creates a stream (TCP) socket. Returns -1 on failure.
static bool connect(int socket, std::string &host, int port)
Connect a socket to a server (from a client).
static bool setNonBlocking(int socket)
Sets a stream (TCP) socket to perform non-blocking IO. Returns false on failure.
static std::string getErrorMsg()
Returns message corresponding to last error.
void setfd(int fd)
Specify the file descriptor to monitor.
static void error(const char *fmt,...)
Dump error messages somewhere.
char * c_str(Index i)

Referenced by setupConnection().

◆ execute()

bool XmlRpcClient::execute ( const char * method,
XmlRpcValue const & params,
XmlRpcValue & result )

Execute the named procedure on the remote server.

Parameters
methodThe name of the remote procedure to execute
paramsAn array of the arguments for the method
resultThe result value to be returned to the client
Returns
true if the request was sent and a result received (although the result might be a fault).

Currently this is a synchronous (blocking) implementation (execute does not return until it receives a response or an error). Use isFault() to determine whether the result is a fault response.

Definition at line 64 of file XmlRpcClient.cpp.

65 {
66 XmlRpcUtil::log( 1, "XmlRpcClient::execute: method %s (_connectionState %d).", method,
68 // std::cout<< "_connectionState "<<_connectionState << std::endl;//yzhang debug
69 // This is not a thread-safe operation, if you want to do multithreading, use separate
70 // clients for each thread. If you want to protect yourself from multiple threads
71 // accessing the same client, replace this code with a real mutex.
72 if ( _executing ) return false;
73
74 _executing = true;
75 ClearFlagOnExit cf( _executing );
76
77 _sendAttempts = 0;
78 _isFault = false;
79
80 if ( !setupConnection() ) return false;
81
82 if ( !generateRequest( method, params ) ) return false;
83 result.clear();
84 double msTime = 5.; // Process until exit is called //yzhang change
85 // double msTime = -1.0; // Process until exit is called //yzhang delete
86 _disp.work( msTime );
87
88 if ( _connectionState != IDLE ) // yzhang add
89 // if (_connectionState != IDLE || ! parseResponse(result))//yzhang delete
90 return false; // yzhang delete
91
92 XmlRpcUtil::log( 1, "XmlRpcClient::execute: method %s completed.", method );
93 _response = "";
94 return true;
95}
virtual bool setupConnection()
virtual bool generateRequest(const char *method, XmlRpcValue const &params)
void clear()
Erase the current value.
Definition XmlRpcValue.h:75

Referenced by getFnamesAtBkk(), main(), and JobInfoSvc::xmlrpc().

◆ generateHeader()

std::string XmlRpcClient::generateHeader ( std::string const & body)
protectedvirtual

Definition at line 222 of file XmlRpcClient.cpp.

222 {
223 std::string header = "POST " + _uri +
224 " HTTP/1.1\r\n"
225 "User-Agent: ";
226 header += XMLRPC_VERSION;
227 header += "\r\nHost: ";
228 header += _host;
229
230 char buff[40];
231 sprintf( buff, ":%d\r\n", _port );
232
233 header += buff;
234 header += "Content-Type: text/xml\r\nContent-length: ";
235
236 sprintf( buff, "%d\r\n\r\n", body.size() );
237
238 return header + buff;
239}
sprintf(cut, "kal_costheta0_em>-0.93&&kal_costheta0_em<0.93&&kal_pxy0_em>=0.05+%d*0.1&&kal_" "pxy0_em<0.15+%d*0.1&&NGch>=2", j, j)
const char XMLRPC_VERSION[]
Version identifier.

Referenced by generateRequest().

◆ generateRequest()

bool XmlRpcClient::generateRequest ( const char * method,
XmlRpcValue const & params )
protectedvirtual

Definition at line 183 of file XmlRpcClient.cpp.

183 {
184 std::string body = REQUEST_BEGIN;
185 body += methodName;
187
188 // If params is an array, each element is a separate parameter
189 if ( params.valid() )
190 {
191 body += PARAMS_TAG;
192 if ( params.getType() == XmlRpcValue::TypeArray )
193 {
194 for ( int i = 0; i < params.size(); ++i )
195 {
196 body += PARAM_TAG;
197 body += params[i].toXml();
198 body += PARAM_ETAG;
199 }
200 }
201 else
202 {
203 body += PARAM_TAG;
204 body += params.toXml();
205 body += PARAM_ETAG;
206 }
207
208 body += PARAMS_ETAG;
209 }
210 body += REQUEST_END;
211
212 std::string header = generateHeader( body );
214 "XmlRpcClient::generateRequest: header is %d bytes, content-length is %d.",
215 header.length(), body.length() );
216
217 _request = header + body;
218 return true;
219}
static const char PARAM_ETAG[]
static const char PARAMS_ETAG[]
static const char REQUEST_END[]
virtual std::string generateHeader(std::string const &body)
static const char REQUEST_END_METHODNAME[]
static const char REQUEST_BEGIN[]
static const char PARAM_TAG[]
static const char PARAMS_TAG[]

Referenced by execute().

◆ handleEvent()

unsigned XmlRpcClient::handleEvent ( unsigned eventType)
virtual

Handle server responses. Called by the event dispatcher during execute.

Parameters
eventTypeThe type of event that occurred.
See also
XmlRpcDispatch::EventType

Implements XmlRpc::XmlRpcSource.

Definition at line 99 of file XmlRpcClient.cpp.

99 {
100 if ( eventType == XmlRpcDispatch::Exception )
101 {
104 "Error in XmlRpcClient::handleEvent: could not connect to server (%s).",
106 else
107 XmlRpcUtil::error( "Error in XmlRpcClient::handleEvent (state %d): %s.",
109 return 0;
110 }
111
113 if ( !writeRequest() ) return 0;
114
116 if ( !readHeader() ) return 0;
117
119 if ( !readResponse() ) return 0;
120
121 // This should probably always ask for Exception events too
124}
virtual bool writeRequest()
virtual bool readResponse()
virtual bool readHeader()
@ ReadableEvent
data available to read
@ WritableEvent
connected/data can be written without blocking

◆ isFault()

bool XmlRpc::XmlRpcClient::isFault ( ) const
inline

Returns true if the result of the last execute() was a fault response.

Definition at line 60 of file XmlRpcClient.h.

60{ return _isFault; }

Referenced by getFnamesAtBkk(), and main().

◆ parseResponse()

bool XmlRpcClient::parseResponse ( XmlRpcValue & result)
protectedvirtual

Definition at line 375 of file XmlRpcClient.cpp.

375 {
376 // Parse response xml into result
377 int offset = 0;
379 {
380 XmlRpcUtil::error( "Error in XmlRpcClient::parseResponse: Invalid response - no "
381 "methodResponse. Response:\n%s",
382 _response.c_str() );
383 return false;
384 }
385
386 // Expect either <params><param>... or <fault>...
387 if ( ( XmlRpcUtil::nextTagIs( PARAMS_TAG, _response, &offset ) &&
389 // || XmlRpcUtil::nextTagIs(FAULT_TAG,_response,&offset) //yzhang delete
390 && ( _isFault = true ) )
391 {
392 if ( !result.fromXml( _response, &offset ) )
393 {
395 "Error in XmlRpcClient::parseResponse: Invalid response value. Response:\n%s",
396 _response.c_str() );
397 _response = "";
398 return false;
399 }
400 }
401 else
402 {
403 XmlRpcUtil::error( "Error in XmlRpcClient::parseResponse: Invalid response - no param or "
404 "fault tag. Response:\n%s",
405 _response.c_str() );
406 _response = "";
407 return false;
408 }
409
410 _response = "";
411 return result.valid();
412}
static const char METHODRESPONSE_TAG[]
static bool nextTagIs(const char *tag, std::string const &xml, int *offset)
static bool findTag(const char *tag, std::string const &xml, int *offset)
Returns true if the tag is found and updates offset to the char after the tag.
bool fromXml(std::string const &valueXml, int *offset)
Decode xml. Destroys any existing value.
bool valid() const
Return true if the value has been set to something.

◆ readHeader()

bool XmlRpcClient::readHeader ( )
protectedvirtual

Definition at line 268 of file XmlRpcClient.cpp.

268 {
269 // Read available data
270 if ( !XmlRpcSocket::nbRead( this->getfd(), _header, &_eof ) ||
271 ( _eof && _header.length() == 0 ) )
272 {
273
274 // If we haven't read any data yet and this is a keep-alive connection, the server may
275 // have timed out, so we try one more time.
276 if ( getKeepOpen() && _header.length() == 0 && _sendAttempts++ == 0 )
277 {
278 XmlRpcUtil::log( 4, "XmlRpcClient::readHeader: re-trying connection" );
281 _eof = false;
282 return setupConnection();
283 }
284
286 "Error in XmlRpcClient::readHeader: error while reading header (%s) on fd %d.",
288 return false;
289 }
290
291 XmlRpcUtil::log( 4, "XmlRpcClient::readHeader: client has read %d bytes", _header.length() );
292
293 char* hp = (char*)_header.c_str(); // Start of header
294 char* ep = hp + _header.length(); // End of string
295 char* bp = 0; // Start of body
296 char* lp = 0; // Start of content-length value
297
298 for ( char* cp = hp; ( bp == 0 ) && ( cp < ep ); ++cp )
299 {
300 if ( ( ep - cp > 16 ) && ( strncasecmp( cp, "Content-length: ", 16 ) == 0 ) ) lp = cp + 16;
301 else if ( ( ep - cp > 4 ) && ( strncmp( cp, "\r\n\r\n", 4 ) == 0 ) ) bp = cp + 4;
302 else if ( ( ep - cp > 2 ) && ( strncmp( cp, "\n\n", 2 ) == 0 ) ) bp = cp + 2;
303 }
304
305 // If we haven't gotten the entire header yet, return (keep reading)
306 if ( bp == 0 )
307 {
308 if ( _eof ) // EOF in the middle of a response is an error
309 {
310 XmlRpcUtil::error( "Error in XmlRpcClient::readHeader: EOF while reading header" );
311 return false; // Close the connection
312 }
313
314 return true; // Keep reading
315 }
316
317 // Decode content length
318 if ( lp == 0 )
319 {
320 XmlRpcUtil::error( "Error XmlRpcClient::readHeader: No Content-length specified" );
321 return false; // We could try to figure it out by parsing as we read, but for now...
322 }
323
324 _contentLength = atoi( lp );
325 if ( _contentLength <= 0 )
326 {
328 "Error in XmlRpcClient::readHeader: Invalid Content-length specified (%d).",
330 return false;
331 }
332
333 XmlRpcUtil::log( 4, "client read content length: %d", _contentLength );
334
335 // Otherwise copy non-header data to response buffer and set state to read response.
336 _response = bp;
337 _header = ""; // should parse out any interesting bits from the header (connection, etc)...
339 return true; // Continue monitoring this source
340}
static bool nbRead(int socket, std::string &s, bool *eof)
Read text from the specified socket. Returns false on error.
bool getKeepOpen() const
Return whether the file descriptor should be kept open if it is no longer monitored.
double int * ep
Definition qcdloop1.h:82

Referenced by handleEvent().

◆ readResponse()

bool XmlRpcClient::readResponse ( )
protectedvirtual

Definition at line 342 of file XmlRpcClient.cpp.

342 {
343 // If we dont have the entire response yet, read available data
344 if ( int( _response.length() ) < _contentLength )
345 {
346 if ( !XmlRpcSocket::nbRead( this->getfd(), _response, &_eof ) )
347 {
348 XmlRpcUtil::error( "Error in XmlRpcClient::readResponse: read error (%s).",
350 return false;
351 }
352
353 // If we haven't gotten the entire _response yet, return (keep reading)
354 if ( int( _response.length() ) < _contentLength )
355 {
356 if ( _eof )
357 {
358 XmlRpcUtil::error( "Error in XmlRpcClient::readResponse: EOF while reading response" );
359 return false;
360 }
361 return true;
362 }
363 }
364
365 // Otherwise, parse and return the result
366 XmlRpcUtil::log( 3, "XmlRpcClient::readResponse (read %d bytes)", _response.length() );
367 XmlRpcUtil::log( 5, "response:\n%s", _response.c_str() );
368
370
371 return false; // Stop monitoring this source (causes return from work)
372}

Referenced by handleEvent().

◆ setupConnection()

bool XmlRpcClient::setupConnection ( )
protectedvirtual

Definition at line 127 of file XmlRpcClient.cpp.

127 {
128 // If an error occurred last time through, or if the server closed the connection, close our
129 // end
131
132 _eof = false;
134 if ( !doConnect() ) return false;
135
136 // Prepare to write the request
138 _bytesWritten = 0;
139
140 // Notify the dispatcher to listen on this source (calls handleEvent when the socket is
141 // writable)
142 _disp.removeSource( this ); // Make sure nothing is left over
144
145 return true;
146}
virtual bool doConnect()

Referenced by execute(), and readHeader().

◆ writeRequest()

bool XmlRpcClient::writeRequest ( )
protectedvirtual

Definition at line 241 of file XmlRpcClient.cpp.

241 {
242 if ( _bytesWritten == 0 )
243 XmlRpcUtil::log( 5, "XmlRpcClient::writeRequest (attempt %d):\n%s\n", _sendAttempts + 1,
244 _request.c_str() );
245
246 // Try to write the request
248 {
249 XmlRpcUtil::error( "Error in XmlRpcClient::writeRequest: write error (%s).",
251 return false;
252 }
253
254 XmlRpcUtil::log( 3, "XmlRpcClient::writeRequest: wrote %d of %d bytes.", _bytesWritten,
255 _request.length() );
256
257 // Wait for the result
258 if ( _bytesWritten == int( _request.length() ) )
259 {
260 _header = "";
261 _response = "";
263 }
264 return true;
265}
static bool nbWrite(int socket, std::string &s, int *bytesSoFar)
Write text to the specified socket. Returns false on error.

Referenced by handleEvent().

Member Data Documentation

◆ _bytesWritten

int XmlRpc::XmlRpcClient::_bytesWritten
protected

Definition at line 108 of file XmlRpcClient.h.

Referenced by handleEvent(), setupConnection(), and writeRequest().

◆ _connectionState

ClientConnectionState XmlRpc::XmlRpcClient::_connectionState
protected

◆ _contentLength

int XmlRpc::XmlRpcClient::_contentLength
protected

Definition at line 121 of file XmlRpcClient.h.

Referenced by readHeader(), and readResponse().

◆ _disp

XmlRpcDispatch XmlRpc::XmlRpcClient::_disp
protected

Definition at line 124 of file XmlRpcClient.h.

Referenced by close(), execute(), and setupConnection().

◆ _eof

bool XmlRpc::XmlRpcClient::_eof
protected

Definition at line 115 of file XmlRpcClient.h.

Referenced by readHeader(), readResponse(), setupConnection(), and XmlRpcClient().

◆ _executing

bool XmlRpc::XmlRpcClient::_executing
protected

Definition at line 112 of file XmlRpcClient.h.

Referenced by execute(), and XmlRpcClient().

◆ _header

std::string XmlRpc::XmlRpcClient::_header
protected

Definition at line 101 of file XmlRpcClient.h.

Referenced by readHeader(), and writeRequest().

◆ _host

std::string XmlRpc::XmlRpcClient::_host
protected

Definition at line 95 of file XmlRpcClient.h.

Referenced by doConnect(), generateHeader(), and XmlRpcClient().

◆ _isFault

bool XmlRpc::XmlRpcClient::_isFault
protected

Definition at line 118 of file XmlRpcClient.h.

Referenced by execute(), isFault(), and parseResponse().

◆ _port

int XmlRpc::XmlRpcClient::_port
protected

Definition at line 97 of file XmlRpcClient.h.

Referenced by doConnect(), generateHeader(), and XmlRpcClient().

◆ _request

std::string XmlRpc::XmlRpcClient::_request
protected

Definition at line 100 of file XmlRpcClient.h.

Referenced by generateRequest(), and writeRequest().

◆ _response

std::string XmlRpc::XmlRpcClient::_response
protected

Definition at line 102 of file XmlRpcClient.h.

Referenced by execute(), parseResponse(), readHeader(), readResponse(), and writeRequest().

◆ _sendAttempts

int XmlRpc::XmlRpcClient::_sendAttempts
protected

Definition at line 105 of file XmlRpcClient.h.

Referenced by execute(), readHeader(), and writeRequest().

◆ _uri

std::string XmlRpc::XmlRpcClient::_uri
protected

Definition at line 96 of file XmlRpcClient.h.

Referenced by generateHeader(), and XmlRpcClient().

◆ FAULT_TAG

const char XmlRpcClient::FAULT_TAG = "<fault>"
static

Definition at line 36 of file XmlRpcClient.h.

◆ METHODRESPONSE_TAG

const char XmlRpcClient::METHODRESPONSE_TAG = "<methodResponse>"
static

Definition at line 35 of file XmlRpcClient.h.

Referenced by parseResponse().

◆ PARAM_ETAG

const char XmlRpcClient::PARAM_ETAG = "</param>"
static

Definition at line 32 of file XmlRpcClient.h.

Referenced by generateRequest().

◆ PARAM_TAG

const char XmlRpcClient::PARAM_TAG = "<param>"
static

Definition at line 31 of file XmlRpcClient.h.

Referenced by generateRequest(), and parseResponse().

◆ PARAMS_ETAG

const char XmlRpcClient::PARAMS_ETAG = "</params>"
static

Definition at line 30 of file XmlRpcClient.h.

Referenced by generateRequest().

◆ PARAMS_TAG

const char XmlRpcClient::PARAMS_TAG = "<params>"
static

Definition at line 29 of file XmlRpcClient.h.

Referenced by generateRequest(), and parseResponse().

◆ REQUEST_BEGIN

const char XmlRpcClient::REQUEST_BEGIN
static
Initial value:
= "<?xml version=\"1.0\"?>\r\n"
"<methodCall><methodName>"

Definition at line 27 of file XmlRpcClient.h.

Referenced by generateRequest().

◆ REQUEST_END

const char XmlRpcClient::REQUEST_END = "</methodCall>\r\n"
static

Definition at line 33 of file XmlRpcClient.h.

Referenced by generateRequest().

◆ REQUEST_END_METHODNAME

const char XmlRpcClient::REQUEST_END_METHODNAME = "</methodName>\r\n"
static

Definition at line 28 of file XmlRpcClient.h.

Referenced by generateRequest().


The documentation for this class was generated from the following files: