CGEM BOSS 6.6.5.i
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 ()
 Close the owned fd. If deleteOnClose was specified at construction, the object is deleted.
 

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 25 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 31 of file XmlRpcServerConnection.cpp.

31 :
32 XmlRpcSource(fd, deleteOnClose)
33{
34 XmlRpcUtil::log(2,"XmlRpcServerConnection: new socket %d.", fd);
35 _server = server;
37 _keepAlive = true;
38}
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 41 of file XmlRpcServerConnection.cpp.

42{
43 XmlRpcUtil::log(4,"XmlRpcServerConnection dtor.");
45}
virtual void removeConnection(XmlRpcServerConnection *)
Remove a connection from the dispatcher.

Member Function Documentation

◆ executeMethod()

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

Definition at line 254 of file XmlRpcServerConnection.cpp.

256{
257 XmlRpcServerMethod* method = _server->findMethod(methodName);
258
259 if ( ! method) return false;
260
261 method->execute(params, result);
262
263 // Ensure a valid result value
264 if ( ! result.valid())
265 result = std::string();
266
267 return true;
268}
Abstract class representing a single RPC method.
virtual void execute(XmlRpcValue &params, XmlRpcValue &result)=0
Execute the method. Subclasses must provide a definition for this method.
XmlRpcServerMethod * findMethod(const std::string &name) const
Look up a method by name.
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.

274{
275 if (methodName != SYSTEM_MULTICALL) return false;
276
277 // There ought to be 1 parameter, an array of structs
278 if (params.size() != 1 || params[0].getType() != XmlRpcValue::TypeArray)
279 throw XmlRpcException(SYSTEM_MULTICALL + ": Invalid argument (expected an array)");
280
281 int nc = params[0].size();
282 result.setSize(nc);
283
284 for (int i=0; i<nc; ++i) {
285
286 if ( ! params[0][i].hasMember(METHODNAME) ||
287 ! params[0][i].hasMember(PARAMS)) {
288 result[i][FAULTCODE] = -1;
289 result[i][FAULTSTRING] = SYSTEM_MULTICALL +
290 ": Invalid argument (expected a struct with members methodName and params)";
291 continue;
292 }
293
294 const std::string& methodName = params[0][i][METHODNAME];
295 XmlRpcValue& methodParams = params[0][i][PARAMS];
296
297 XmlRpcValue resultValue;
298 resultValue.setSize(1);
299 try {
300 if ( ! executeMethod(methodName, methodParams, resultValue[0]) &&
301 ! executeMulticall(methodName, params, resultValue[0]))
302 {
303 result[i][FAULTCODE] = -1;
304 result[i][FAULTSTRING] = methodName + ": unknown method name";
305 }
306 else
307 result[i] = resultValue;
308
309 } catch (const XmlRpcException& fault) {
310 result[i][FAULTCODE] = fault.getCode();
311 result[i][FAULTSTRING] = fault.getMessage();
312 }
313 }
314
315 return true;
316}
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
RPC method arguments and results are represented by Values.
Definition XmlRpcValue.h:22
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 208 of file XmlRpcServerConnection.cpp.

209{
210 XmlRpcValue params, resultValue;
211 std::string methodName = parseRequest(params);
212 XmlRpcUtil::log(2, "XmlRpcServerConnection::executeRequest: server calling method '%s'",
213 methodName.c_str());
214
215 try {
216
217 if ( ! executeMethod(methodName, params, resultValue) &&
218 ! executeMulticall(methodName, params, resultValue))
219 generateFaultResponse(methodName + ": unknown method name");
220 else
221 generateResponse(resultValue.toXml());
222
223 } catch (const XmlRpcException& fault) {
224 XmlRpcUtil::log(2, "XmlRpcServerConnection::executeRequest: fault %s.",
225 fault.getMessage().c_str());
226 generateFaultResponse(fault.getMessage(), fault.getCode());
227 }
228}
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 356 of file XmlRpcServerConnection.cpp.

357{
358 const char RESPONSE_1[] =
359 "<?xml version=\"1.0\"?>\r\n"
360 "<methodResponse><fault>\r\n\t";
361 const char RESPONSE_2[] =
362 "\r\n</fault></methodResponse>\r\n";
363
364 XmlRpcValue faultStruct;
365 faultStruct[FAULTCODE] = errorCode;
366 faultStruct[FAULTSTRING] = errorMsg;
367 std::string body = RESPONSE_1 + faultStruct.toXml() + RESPONSE_2;
368 std::string header = generateHeader(body);
369
370 _response = header + body;
371}
std::string generateHeader(std::string const &body)

Referenced by executeRequest().

◆ generateHeader()

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

Definition at line 338 of file XmlRpcServerConnection.cpp.

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

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

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 52 of file XmlRpcServerConnection.cpp.

53{
55 if ( ! readHeader()) return 0;
56
58 if ( ! readRequest()) return 0;
59
61 if ( ! writeResponse()) return 0;
62
65}
@ ReadableEvent
data available to read
@ WritableEvent
connected/data can be written without blocking

◆ parseRequest()

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

Definition at line 232 of file XmlRpcServerConnection.cpp.

233{
234 int offset = 0; // Number of chars parsed from the request
235
236 std::string methodName = XmlRpcUtil::parseTag(METHODNAME_TAG, _request, &offset);
237
238 if (methodName.size() > 0 && XmlRpcUtil::findTag(PARAMS_TAG, _request, &offset))
239 {
240 int nArgs = 0;
241 while (XmlRpcUtil::nextTagIs(PARAM_TAG, _request, &offset)) {
242 params[nArgs++] = XmlRpcValue(_request, &offset);
243 (void) XmlRpcUtil::nextTagIs(PARAM_ETAG, _request, &offset);
244 }
245
247 }
248
249 return methodName;
250}
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 69 of file XmlRpcServerConnection.cpp.

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

Referenced by handleEvent().

◆ readRequest()

bool XmlRpcServerConnection::readRequest ( )
protected

Definition at line 146 of file XmlRpcServerConnection.cpp.

147{
148 // If we dont have the entire request yet, read available data
149 if (int(_request.length()) < _contentLength) {
150 bool eof;
151 if ( ! XmlRpcSocket::nbRead(this->getfd(), _request, &eof)) {
152 XmlRpcUtil::error("XmlRpcServerConnection::readRequest: read error (%s).",XmlRpcSocket::getErrorMsg().c_str());
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 if (eof) {
159 XmlRpcUtil::error("XmlRpcServerConnection::readRequest: EOF while reading request");
160 return false; // Either way we close the connection
161 }
162 return true;
163 }
164 }
165
166 // Otherwise, parse and dispatch the request
167 XmlRpcUtil::log(3, "XmlRpcServerConnection::readRequest read %d bytes.", _request.length());
168 //XmlRpcUtil::log(5, "XmlRpcServerConnection::readRequest:\n%s\n", _request.c_str());
169
171
172 return true; // Continue monitoring this source
173}

Referenced by handleEvent().

◆ writeResponse()

bool XmlRpcServerConnection::writeResponse ( )
protected

Definition at line 177 of file XmlRpcServerConnection.cpp.

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

Referenced by writeResponse().

◆ _connectionState

ServerConnectionState XmlRpc::XmlRpcServerConnection::_connectionState
protected

◆ _contentLength

int XmlRpc::XmlRpcServerConnection::_contentLength
protected

Definition at line 86 of file XmlRpcServerConnection.h.

Referenced by readHeader(), and readRequest().

◆ _header

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

Definition at line 83 of file XmlRpcServerConnection.h.

Referenced by readHeader(), and writeResponse().

◆ _keepAlive

bool XmlRpc::XmlRpcServerConnection::_keepAlive
protected

Definition at line 98 of file XmlRpcServerConnection.h.

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

◆ _request

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

Definition at line 89 of file XmlRpcServerConnection.h.

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

◆ _response

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

Definition at line 92 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 38 of file XmlRpcServerConnection.h.

Referenced by executeMulticall(), and generateFaultResponse().

◆ FAULTSTRING

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

Definition at line 39 of file XmlRpcServerConnection.h.

Referenced by executeMulticall(), and generateFaultResponse().

◆ METHODNAME

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

Definition at line 35 of file XmlRpcServerConnection.h.

Referenced by executeMulticall().

◆ METHODNAME_TAG

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

Definition at line 28 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ PARAM_ETAG

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

Definition at line 32 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ PARAM_TAG

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

Definition at line 31 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ PARAMS

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

Definition at line 36 of file XmlRpcServerConnection.h.

Referenced by executeMulticall().

◆ PARAMS_ETAG

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

Definition at line 30 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ PARAMS_TAG

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

Definition at line 29 of file XmlRpcServerConnection.h.

Referenced by parseRequest().

◆ SYSTEM_MULTICALL

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

Definition at line 34 of file XmlRpcServerConnection.h.

Referenced by executeMulticall().


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