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

A class to handle XML RPC requests from a particular client. More...

#include <XmlRpcServerConnection.h>

Inheritance diagram for XmlRpc::XmlRpcServerConnection:

Public Member Functions

 XmlRpcServerConnection (int fd, XmlRpcServer *server, bool deleteOnClose=false)
 Constructor.
virtual ~XmlRpcServerConnection ()
 Destructor.
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.
virtual void close ()

Static Public Attributes

static const char METHODNAME_TAG [] = "<methodName>"
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 std::string SYSTEM_MULTICALL = "system.multicall"
static const std::string METHODNAME = "methodName"
static const std::string PARAMS = "params"
static const std::string FAULTCODE = "faultCode"
static const std::string FAULTSTRING = "faultString"

Protected Types

enum  ServerConnectionState { READ_HEADER , READ_REQUEST , WRITE_RESPONSE }

Protected Member Functions

bool readHeader ()
bool readRequest ()
bool writeResponse ()
virtual void executeRequest ()
std::string parseRequest (XmlRpcValue &params)
bool executeMethod (const std::string &methodName, XmlRpcValue &params, XmlRpcValue &result)
bool executeMulticall (const std::string &methodName, XmlRpcValue &params, XmlRpcValue &result)
void generateResponse (std::string const &resultXml)
void generateFaultResponse (std::string const &msg, int errorCode=-1)
std::string generateHeader (std::string const &body)

Protected Attributes

XmlRpcServer_server
ServerConnectionState _connectionState
std::string _header
int _contentLength
std::string _request
std::string _response
int _bytesWritten
bool _keepAlive

Detailed Description

A class to handle XML RPC requests from a particular client.

Definition at line 24 of file XmlRpcServerConnection.h.

Member Enumeration Documentation

◆ ServerConnectionState

Constructor & Destructor Documentation

◆ XmlRpcServerConnection()

XmlRpcServerConnection::XmlRpcServerConnection ( int fd,
XmlRpcServer * server,
bool deleteOnClose = false )

Constructor.

Definition at line 29 of file XmlRpcServerConnection.cpp.

31 : XmlRpcSource( fd, deleteOnClose ) {
32 XmlRpcUtil::log( 2, "XmlRpcServerConnection: new socket %d.", fd );
33 _server = server;
35 _keepAlive = true;
36}
XmlRpcSource(int fd=-1, bool deleteOnClose=false)
static void log(int level, const char *fmt,...)
Dump messages somewhere.

◆ ~XmlRpcServerConnection()

XmlRpcServerConnection::~XmlRpcServerConnection ( )
virtual

Destructor.

Definition at line 38 of file XmlRpcServerConnection.cpp.

38 {
39 XmlRpcUtil::log( 4, "XmlRpcServerConnection dtor." );
40 _server->removeConnection( this );
41}

Member Function Documentation

◆ executeMethod()

bool XmlRpcServerConnection::executeMethod ( const std::string & methodName,
XmlRpcValue & params,
XmlRpcValue & result )
protected

Definition at line 257 of file XmlRpcServerConnection.cpp.

258 {
259 XmlRpcServerMethod* method = _server->findMethod( methodName );
260
261 if ( !method ) return false;
262
263 method->execute( params, result );
264
265 // Ensure a valid result value
266 if ( !result.valid() ) result = std::string();
267
268 return true;
269}
virtual void execute(XmlRpcValue &params, XmlRpcValue &result)=0
Execute the method. Subclasses must provide a definition for this method.
bool valid() const
Return true if the value has been set to something.

Referenced by executeMulticall(), and executeRequest().

◆ executeMulticall()

bool XmlRpcServerConnection::executeMulticall ( const std::string & methodName,
XmlRpcValue & params,
XmlRpcValue & result )
protected

Definition at line 272 of file XmlRpcServerConnection.cpp.

273 {
274 if ( methodName != SYSTEM_MULTICALL ) return false;
275
276 // There ought to be 1 parameter, an array of structs
277 if ( params.size() != 1 || params[0].getType() != XmlRpcValue::TypeArray )
278 throw XmlRpcException( SYSTEM_MULTICALL + ": Invalid argument (expected an array)" );
279
280 int nc = params[0].size();
281 result.setSize( nc );
282
283 for ( int i = 0; i < nc; ++i )
284 {
285
286 if ( !params[0][i].hasMember( METHODNAME ) || !params[0][i].hasMember( PARAMS ) )
287 {
288 result[i][FAULTCODE] = -1;
289 result[i][FAULTSTRING] =
291 ": Invalid argument (expected a struct with members methodName and params)";
292 continue;
293 }
294
295 const std::string& methodName = params[0][i][METHODNAME];
296 XmlRpcValue& methodParams = params[0][i][PARAMS];
297
298 XmlRpcValue resultValue;
299 resultValue.setSize( 1 );
300 try
301 {
302 if ( !executeMethod( methodName, methodParams, resultValue[0] ) &&
303 !executeMulticall( methodName, params, resultValue[0] ) )
304 {
305 result[i][FAULTCODE] = -1;
306 result[i][FAULTSTRING] = methodName + ": unknown method name";
307 }
308 else result[i] = resultValue;
309
310 } catch ( const XmlRpcException& fault )
311 {
312 result[i][FAULTCODE] = fault.getCode();
313 result[i][FAULTSTRING] = fault.getMessage();
314 }
315 }
316
317 return true;
318}
int getCode() const
Return the error code.
const std::string & getMessage() const
Return the error message.
bool executeMethod(const std::string &methodName, XmlRpcValue &params, XmlRpcValue &result)
static const std::string METHODNAME
static const std::string FAULTSTRING
bool executeMulticall(const std::string &methodName, XmlRpcValue &params, XmlRpcValue &result)
static const std::string SYSTEM_MULTICALL
int size() const
Return the size for string, base64, array, and struct values.
void setSize(int size)
Specify the size for array values. Array values will grow beyond this size if needed.

Referenced by executeMulticall(), and executeRequest().

◆ executeRequest()

void XmlRpcServerConnection::executeRequest ( )
protectedvirtual

Definition at line 213 of file XmlRpcServerConnection.cpp.

213 {
214 XmlRpcValue params, resultValue;
215 std::string methodName = parseRequest( params );
216 XmlRpcUtil::log( 2, "XmlRpcServerConnection::executeRequest: server calling method '%s'",
217 methodName.c_str() );
218
219 try
220 {
221
222 if ( !executeMethod( methodName, params, resultValue ) &&
223 !executeMulticall( methodName, params, resultValue ) )
224 generateFaultResponse( methodName + ": unknown method name" );
225 else generateResponse( resultValue.toXml() );
226
227 } catch ( const XmlRpcException& fault )
228 {
229 XmlRpcUtil::log( 2, "XmlRpcServerConnection::executeRequest: fault %s.",
230 fault.getMessage().c_str() );
231 generateFaultResponse( fault.getMessage(), fault.getCode() );
232 }
233}
std::string parseRequest(XmlRpcValue &params)
void generateFaultResponse(std::string const &msg, int errorCode=-1)
void generateResponse(std::string const &resultXml)
std::string toXml() const
Encode the Value in xml.

Referenced by writeResponse().

◆ generateFaultResponse()

void XmlRpcServerConnection::generateFaultResponse ( std::string const & msg,
int errorCode = -1 )
protected

Definition at line 348 of file XmlRpcServerConnection.cpp.

349 {
350 const char RESPONSE_1[] = "<?xml version=\"1.0\"?>\r\n"
351 "<methodResponse><fault>\r\n\t";
352 const char RESPONSE_2[] = "\r\n</fault></methodResponse>\r\n";
353
354 XmlRpcValue faultStruct;
355 faultStruct[FAULTCODE] = errorCode;
356 faultStruct[FAULTSTRING] = errorMsg;
357 std::string body = RESPONSE_1 + faultStruct.toXml() + RESPONSE_2;
358 std::string header = generateHeader( body );
359
360 _response = header + body;
361}
std::string generateHeader(std::string const &body)

Referenced by executeRequest().

◆ generateHeader()

std::string XmlRpcServerConnection::generateHeader ( std::string const & body)
protected

Definition at line 334 of file XmlRpcServerConnection.cpp.

334 {
335 std::string header = "HTTP/1.1 200 OK\r\n"
336 "Server: ";
337 header += XMLRPC_VERSION;
338 header += "\r\n"
339 "Content-Type: text/xml\r\n"
340 "Content-length: ";
341
342 char buffLen[40];
343 sprintf( buffLen, "%d\r\n\r\n", body.size() );
344
345 return header + buffLen;
346}
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 generateFaultResponse(), and generateResponse().

◆ generateResponse()

void XmlRpcServerConnection::generateResponse ( std::string const & resultXml)
protected

Definition at line 321 of file XmlRpcServerConnection.cpp.

321 {
322 const char RESPONSE_1[] = "<?xml version=\"1.0\"?>\r\n"
323 "<methodResponse><params><param>\r\n\t";
324 const char RESPONSE_2[] = "\r\n</param></params></methodResponse>\r\n";
325
326 std::string body = RESPONSE_1 + resultXml + RESPONSE_2;
327 std::string header = generateHeader( body );
328
329 _response = header + body;
330 XmlRpcUtil::log( 5, "XmlRpcServerConnection::generateResponse:\n%s\n", _response.c_str() );
331}

Referenced by executeRequest().

◆ handleEvent()

unsigned XmlRpcServerConnection::handleEvent ( unsigned eventType)
virtual

Handle IO on the client connection socket.

Parameters
eventTypeType of IO event that occurred.
See also
XmlRpcDispatch::EventType.

Implements XmlRpc::XmlRpcSource.

Definition at line 46 of file XmlRpcServerConnection.cpp.

46 {
48 if ( !readHeader() ) return 0;
49
51 if ( !readRequest() ) return 0;
52
54 if ( !writeResponse() ) return 0;
55
58}
@ ReadableEvent
data available to read
@ WritableEvent
connected/data can be written without blocking

◆ parseRequest()

std::string XmlRpcServerConnection::parseRequest ( XmlRpcValue & params)
protected

Definition at line 236 of file XmlRpcServerConnection.cpp.

236 {
237 int offset = 0; // Number of chars parsed from the request
238
239 std::string methodName = XmlRpcUtil::parseTag( METHODNAME_TAG, _request, &offset );
240
241 if ( methodName.size() > 0 && XmlRpcUtil::findTag( PARAMS_TAG, _request, &offset ) )
242 {
243 int nArgs = 0;
244 while ( XmlRpcUtil::nextTagIs( PARAM_TAG, _request, &offset ) )
245 {
246 params[nArgs++] = XmlRpcValue( _request, &offset );
247 (void)XmlRpcUtil::nextTagIs( PARAM_ETAG, _request, &offset );
248 }
249
250 (void)XmlRpcUtil::nextTagIs( PARAMS_ETAG, _request, &offset );
251 }
252
253 return methodName;
254}
static bool nextTagIs(const char *tag, std::string const &xml, int *offset)
static std::string parseTag(const char *tag, std::string const &xml, int *offset)
Returns contents between <tag> and </tag>, updates offset to char after </tag>.
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.

Referenced by executeRequest().

◆ readHeader()

bool XmlRpcServerConnection::readHeader ( )
protected

Definition at line 60 of file XmlRpcServerConnection.cpp.

60 {
61 // Read available data
62 bool eof;
63 if ( !XmlRpcSocket::nbRead( this->getfd(), _header, &eof ) )
64 {
65 // Its only an error if we already have read some data
66 if ( _header.length() > 0 )
68 "XmlRpcServerConnection::readHeader: error while reading header (%s).",
70 return false;
71 }
72
73 XmlRpcUtil::log( 4, "XmlRpcServerConnection::readHeader: read %d bytes.", _header.length() );
74 char* hp = (char*)_header.c_str(); // Start of header
75 char* ep = hp + _header.length(); // End of string
76 char* bp = 0; // Start of body
77 char* lp = 0; // Start of content-length value
78 char* kp = 0; // Start of connection value
79
80 for ( char* cp = hp; ( bp == 0 ) && ( cp < ep ); ++cp )
81 {
82 if ( ( ep - cp > 16 ) && ( strncasecmp( cp, "Content-length: ", 16 ) == 0 ) ) lp = cp + 16;
83 else if ( ( ep - cp > 12 ) && ( strncasecmp( cp, "Connection: ", 12 ) == 0 ) )
84 kp = cp + 12;
85 else if ( ( ep - cp > 4 ) && ( strncmp( cp, "\r\n\r\n", 4 ) == 0 ) ) bp = cp + 4;
86 else if ( ( ep - cp > 2 ) && ( strncmp( cp, "\n\n", 2 ) == 0 ) ) bp = cp + 2;
87 }
88
89 // If we haven't gotten the entire header yet, return (keep reading)
90 if ( bp == 0 )
91 {
92 // EOF in the middle of a request is an error, otherwise its ok
93 if ( eof )
94 {
95 XmlRpcUtil::log( 4, "XmlRpcServerConnection::readHeader: EOF" );
96 if ( _header.length() > 0 )
97 XmlRpcUtil::error( "XmlRpcServerConnection::readHeader: EOF while reading header" );
98 return false; // Either way we close the connection
99 }
100
101 return true; // Keep reading
102 }
103
104 // Decode content length
105 if ( lp == 0 )
106 {
107 XmlRpcUtil::error( "XmlRpcServerConnection::readHeader: No Content-length specified" );
108 return false; // We could try to figure it out by parsing as we read, but for now...
109 }
110
111 _contentLength = atoi( lp );
112 if ( _contentLength <= 0 )
113 {
115 "XmlRpcServerConnection::readHeader: Invalid Content-length specified (%d).",
117 return false;
118 }
119
120 XmlRpcUtil::log( 3, "XmlRpcServerConnection::readHeader: specified content length is %d.",
122
123 // Otherwise copy non-header data to request buffer and set state to read request.
124 _request = bp;
125
126 // Parse out any interesting bits from the header (HTTP version, connection)
127 _keepAlive = true;
128 if ( _header.find( "HTTP/1.0" ) != std::string::npos )
129 {
130 if ( kp == 0 || strncasecmp( kp, "keep-alive", 10 ) != 0 )
131 _keepAlive = false; // Default for HTTP 1.0 is to close the connection
132 }
133 else
134 {
135 if ( kp != 0 && strncasecmp( kp, "close", 5 ) == 0 ) _keepAlive = false;
136 }
137 XmlRpcUtil::log( 3, "KeepAlive: %d", _keepAlive );
138
139 _header = "";
141 return true; // Continue monitoring this source
142}
static bool nbRead(int socket, std::string &s, bool *eof)
Read text from the specified socket. Returns false on error.
static std::string getErrorMsg()
Returns message corresponding to last error.
int getfd() const
Return the file descriptor being monitored.
static void error(const char *fmt,...)
Dump error messages somewhere.
char * c_str(Index i)
double int * ep
Definition qcdloop1.h:82

Referenced by handleEvent().

◆ readRequest()

bool XmlRpcServerConnection::readRequest ( )
protected

Definition at line 144 of file XmlRpcServerConnection.cpp.

144 {
145 // If we dont have the entire request yet, read available data
146 if ( int( _request.length() ) < _contentLength )
147 {
148 bool eof;
149 if ( !XmlRpcSocket::nbRead( this->getfd(), _request, &eof ) )
150 {
151 XmlRpcUtil::error( "XmlRpcServerConnection::readRequest: read error (%s).",
153 return false;
154 }
155
156 // If we haven't gotten the entire request yet, return (keep reading)
157 if ( int( _request.length() ) < _contentLength )
158 {
159 if ( eof )
160 {
161 XmlRpcUtil::error( "XmlRpcServerConnection::readRequest: EOF while reading request" );
162 return false; // Either way we close the connection
163 }
164 return true;
165 }
166 }
167
168 // Otherwise, parse and dispatch the request
169 XmlRpcUtil::log( 3, "XmlRpcServerConnection::readRequest read %d bytes.",
170 _request.length() );
171 // XmlRpcUtil::log(5, "XmlRpcServerConnection::readRequest:\n%s\n", _request.c_str());
172
174
175 return true; // Continue monitoring this source
176}

Referenced by handleEvent().

◆ writeResponse()

bool XmlRpcServerConnection::writeResponse ( )
protected

Definition at line 178 of file XmlRpcServerConnection.cpp.

178 {
179 if ( _response.length() == 0 )
180 {
182 _bytesWritten = 0;
183 if ( _response.length() == 0 )
184 {
185 XmlRpcUtil::error( "XmlRpcServerConnection::writeResponse: empty response." );
186 return false;
187 }
188 }
189
190 // Try to write the response
192 {
193 XmlRpcUtil::error( "XmlRpcServerConnection::writeResponse: write error (%s).",
195 return false;
196 }
197 XmlRpcUtil::log( 3, "XmlRpcServerConnection::writeResponse: wrote %d of %d bytes.",
198 _bytesWritten, _response.length() );
199
200 // Prepare to read the next request
201 if ( _bytesWritten == int( _response.length() ) )
202 {
203 _header = "";
204 _request = "";
205 _response = "";
207 }
208
209 return _keepAlive; // Continue monitoring this source if true
210}
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::XmlRpcServerConnection::_bytesWritten
protected

Definition at line 94 of file XmlRpcServerConnection.h.

Referenced by writeResponse().

◆ _connectionState

ServerConnectionState XmlRpc::XmlRpcServerConnection::_connectionState
protected

◆ _contentLength

int XmlRpc::XmlRpcServerConnection::_contentLength
protected

Definition at line 85 of file XmlRpcServerConnection.h.

Referenced by readHeader(), and readRequest().

◆ _header

std::string XmlRpc::XmlRpcServerConnection::_header
protected

Definition at line 82 of file XmlRpcServerConnection.h.

Referenced by readHeader(), and writeResponse().

◆ _keepAlive

bool XmlRpc::XmlRpcServerConnection::_keepAlive
protected

Definition at line 97 of file XmlRpcServerConnection.h.

Referenced by readHeader(), writeResponse(), and XmlRpcServerConnection().

◆ _request

std::string XmlRpc::XmlRpcServerConnection::_request
protected

Definition at line 88 of file XmlRpcServerConnection.h.

Referenced by parseRequest(), readHeader(), readRequest(), and writeResponse().

◆ _response

std::string XmlRpc::XmlRpcServerConnection::_response
protected

Definition at line 91 of file XmlRpcServerConnection.h.

Referenced by generateFaultResponse(), generateResponse(), and writeResponse().

◆ _server

XmlRpcServer* XmlRpc::XmlRpcServerConnection::_server
protected

◆ FAULTCODE

const std::string XmlRpcServerConnection::FAULTCODE = "faultCode"
static

Definition at line 37 of file XmlRpcServerConnection.h.

Referenced by executeMulticall(), and generateFaultResponse().

◆ FAULTSTRING

const std::string XmlRpcServerConnection::FAULTSTRING = "faultString"
static

Definition at line 38 of file XmlRpcServerConnection.h.

Referenced by executeMulticall(), and generateFaultResponse().

◆ METHODNAME

const std::string XmlRpcServerConnection::METHODNAME = "methodName"
static

Definition at line 34 of file XmlRpcServerConnection.h.

Referenced by executeMulticall().

◆ METHODNAME_TAG

const char XmlRpcServerConnection::METHODNAME_TAG = "<methodName>"
static

Definition at line 27 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ PARAM_ETAG

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

Definition at line 31 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ PARAM_TAG

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

Definition at line 30 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ PARAMS

const std::string XmlRpcServerConnection::PARAMS = "params"
static

Definition at line 35 of file XmlRpcServerConnection.h.

Referenced by executeMulticall().

◆ PARAMS_ETAG

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

Definition at line 29 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ PARAMS_TAG

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

Definition at line 28 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ SYSTEM_MULTICALL

const std::string XmlRpcServerConnection::SYSTEM_MULTICALL = "system.multicall"
static

Definition at line 33 of file XmlRpcServerConnection.h.

Referenced by executeMulticall().


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