A class to handle XML RPC requests. More...
#include <XmlRpcServer.h>
Public Member Functions | |
XmlRpcServer () | |
Create a server object. | |
virtual | ~XmlRpcServer () |
Destructor. | |
void | enableIntrospection (bool enabled=true) |
Specify whether introspection is enabled or not. Default is not enabled. | |
void | addMethod (XmlRpcServerMethod *method) |
Add a command to the RPC server. | |
void | removeMethod (XmlRpcServerMethod *method) |
Remove a command from the RPC server. | |
void | removeMethod (const std::string &methodName) |
Remove a command from the RPC server by name. | |
XmlRpcServerMethod * | findMethod (const std::string &name) const |
Look up a method by name. | |
bool | bindAndListen (int port, int backlog=5) |
Create a socket, bind to the specified port, and set it in listen mode to make it available for clients. | |
int | getPort (void) const |
Get the port number this server is listening on. | |
void | work (double msTime) |
Process client requests for the specified time. | |
void | exit () |
Temporarily stop processing client requests and exit the work() method. | |
void | shutdown () |
Close all connections with clients and the socket file descriptor. | |
void | listMethods (XmlRpcValue &result) |
Introspection support. | |
virtual std::string | executeRequest (std::string const &request) |
Parses the request xml, runs the method, generates the response (header+xml). | |
virtual unsigned | handleEvent (unsigned eventType) |
Handle client connection requests. | |
virtual void | removeConnection (XmlRpcServerConnection *) |
Remove a connection from the dispatcher. | |
Protected Types | |
typedef std::map< std::string, XmlRpcServerMethod * > | MethodMap |
Collection of methods. This could be a set keyed on method name if we wanted... | |
Protected Member Functions | |
virtual void | acceptConnection () |
Accept a client connection request. | |
virtual XmlRpcServerConnection * | createConnection (int socket) |
Create a new connection object for processing requests from a specific client. | |
virtual void | dispatchConnection (XmlRpcServerConnection *sc) |
Hand off a new connection object to a dispatcher. | |
std::string | parseRequest (std::string const &request, XmlRpcValue ¶ms) |
Parse the methodName and parameters from the request. | |
bool | executeMethod (const std::string &methodName, XmlRpcValue ¶ms, XmlRpcValue &result) |
Execute a named method with the specified params. | |
bool | executeMulticall (const std::string &methodName, XmlRpcValue ¶ms, XmlRpcValue &result) |
Execute multiple calls and return the results in an array. | |
std::string | generateResponse (std::string const &resultXml) |
Construct a response from the result XML. | |
std::string | generateFaultResponse (std::string const &msg, int errorCode=-1) |
Construct a fault response. | |
std::string | generateHeader (std::string const &body) |
Return the appropriate headers for the response. | |
Protected Attributes | |
bool | _introspectionEnabled |
Whether the introspection API is supported by this server. | |
XmlRpcDispatch | _disp |
Event dispatcher. | |
MethodMap | _methods |
Registered RPC methods. | |
XmlRpcServerMethod * | _listMethods |
List all registered RPC methods (only available if introspection is enabled). | |
XmlRpcServerMethod * | _methodHelp |
Return help string for a specified method (only available if introspection is enabled). | |
Static Protected 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 |
static const std::string | METHODNAME = "methodName" |
static const std::string | PARAMS = "params" |
static const std::string | FAULTCODE = "faultCode" |
static const std::string | FAULTSTRING = "faultString" |
A class to handle XML RPC requests.
Definition at line 40 of file XmlRpcServer.h.
typedef std::map< std::string, XmlRpcServerMethod* > XmlRpc::XmlRpcServer::MethodMap [protected] |
Collection of methods. This could be a set keyed on method name if we wanted...
Definition at line 154 of file XmlRpcServer.h.
XmlRpcServer::XmlRpcServer | ( | ) |
Create a server object.
Definition at line 34 of file XmlRpcServer.cc.
00035 { 00036 _introspectionEnabled = false; 00037 _listMethods = 0; 00038 _methodHelp = 0; 00039 }
XmlRpcServer::~XmlRpcServer | ( | ) | [virtual] |
Destructor.
Definition at line 42 of file XmlRpcServer.cc.
00043 { 00044 this->shutdown(); 00045 _methods.clear(); 00046 delete _listMethods; 00047 delete _methodHelp; 00048 }
void XmlRpcServer::acceptConnection | ( | ) | [protected, virtual] |
Accept a client connection request.
Definition at line 175 of file XmlRpcServer.cc.
Referenced by handleEvent().
00176 { 00177 int s = XmlRpcSocket::accept(this->getfd()); 00178 XmlRpcUtil::log(2, "XmlRpcServer::acceptConnection: socket %d", s); 00179 if (s < 0) 00180 { 00181 //this->close(); 00182 XmlRpcUtil::error("XmlRpcServer::acceptConnection: Could not accept connection (%s).", XmlRpcSocket::getErrorMsg().c_str()); 00183 } 00184 else if ( ! XmlRpcSocket::setNonBlocking(s)) 00185 { 00186 XmlRpcSocket::close(s); 00187 XmlRpcUtil::error("XmlRpcServer::acceptConnection: Could not set socket to non-blocking input mode (%s).", XmlRpcSocket::getErrorMsg().c_str()); 00188 } 00189 else // Notify the dispatcher to listen for input on this source when we are in work() 00190 { 00191 XmlRpcUtil::log(2, "XmlRpcServer::acceptConnection: creating a connection"); 00192 XmlRpcServerConnection* c = this->createConnection(s); 00193 if (c) this->dispatchConnection(c); 00194 } 00195 }
void XmlRpcServer::addMethod | ( | XmlRpcServerMethod * | method | ) |
Add a command to the RPC server.
Definition at line 53 of file XmlRpcServer.cc.
Referenced by enableIntrospection(), and XmlRpc::XmlRpcServerMethod::XmlRpcServerMethod().
bool XmlRpcServer::bindAndListen | ( | int | port, | |
int | backlog = 5 | |||
) |
Create a socket, bind to the specified port, and set it in listen mode to make it available for clients.
port | The port to bind and listen on (zero to choose an arbitrary port) | |
backlog |
Definition at line 91 of file XmlRpcServer.cc.
00092 { 00093 int fd = XmlRpcSocket::getSocket(); 00094 if (fd < 0) 00095 { 00096 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not create socket (%s).", XmlRpcSocket::getErrorMsg().c_str()); 00097 return false; 00098 } 00099 00100 this->setfd(fd); 00101 00102 // Don't block on reads/writes 00103 if ( ! XmlRpcSocket::setNonBlocking(fd)) 00104 { 00105 this->close(); 00106 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set socket to non-blocking input mode (%s).", XmlRpcSocket::getErrorMsg().c_str()); 00107 return false; 00108 } 00109 00110 // Allow this port to be re-bound immediately so server re-starts are not delayed 00111 if ( ! XmlRpcSocket::setReuseAddr(fd)) 00112 { 00113 this->close(); 00114 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set SO_REUSEADDR socket option (%s).", XmlRpcSocket::getErrorMsg().c_str()); 00115 return false; 00116 } 00117 00118 // Bind to the specified port on the default interface 00119 if ( ! XmlRpcSocket::bind(fd, port)) 00120 { 00121 this->close(); 00122 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not bind to specified port (%s).", XmlRpcSocket::getErrorMsg().c_str()); 00123 return false; 00124 } 00125 00126 // Set in listening mode 00127 if ( ! XmlRpcSocket::listen(fd, backlog)) 00128 { 00129 this->close(); 00130 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set socket in listening mode (%s).", XmlRpcSocket::getErrorMsg().c_str()); 00131 return false; 00132 } 00133 00134 XmlRpcUtil::log(2, "XmlRpcServer::bindAndListen: server listening on port %d fd %d", port, fd); 00135 00136 // Notify the dispatcher to listen on this source when we are in work() 00137 _disp.addSource(this, XmlRpcDispatch::ReadableEvent); 00138 00139 return true; 00140 }
XmlRpcServerConnection * XmlRpcServer::createConnection | ( | int | socket | ) | [protected, virtual] |
Create a new connection object for processing requests from a specific client.
If the client is not authorized to connect, close the socket and return 0.
Definition at line 200 of file XmlRpcServer.cc.
Referenced by acceptConnection().
00201 { 00202 // Specify that the connection object be deleted when it is closed 00203 return new XmlRpcServerConnection(s, this, true); 00204 }
void XmlRpcServer::dispatchConnection | ( | XmlRpcServerConnection * | sc | ) | [protected, virtual] |
Hand off a new connection object to a dispatcher.
Definition at line 209 of file XmlRpcServer.cc.
Referenced by acceptConnection().
00210 { 00211 _disp.addSource(sc, XmlRpcDispatch::ReadableEvent); 00212 }
void XmlRpcServer::enableIntrospection | ( | bool | enabled = true |
) |
Specify whether introspection is enabled or not. Default is not enabled.
Definition at line 285 of file XmlRpcServer.cc.
Referenced by XmlRpcInterface::initializeApp().
00286 { 00287 if (_introspectionEnabled == enabled) 00288 return; 00289 00290 _introspectionEnabled = enabled; 00291 00292 if (enabled) 00293 { 00294 if ( ! _listMethods) 00295 { 00296 _listMethods = new ListMethods(this); 00297 _methodHelp = new MethodHelp(this); 00298 } else { 00299 addMethod(_listMethods); 00300 addMethod(_methodHelp); 00301 } 00302 } 00303 else 00304 { 00305 removeMethod(LIST_METHODS); 00306 removeMethod(METHOD_HELP); 00307 } 00308 }
bool XmlRpcServer::executeMethod | ( | const std::string & | methodName, | |
XmlRpcValue & | params, | |||
XmlRpcValue & | result | |||
) | [protected] |
Execute a named method with the specified params.
Definition at line 376 of file XmlRpcServer.cc.
Referenced by executeMulticall(), and executeRequest().
00379 { 00380 XmlRpcServerMethod* method = findMethod(methodName); 00381 00382 if ( ! method) return false; 00383 00384 method->execute(params, result); 00385 00386 // Ensure a valid result value 00387 if ( ! result.isValid()) 00388 result = std::string(); 00389 00390 return true; 00391 }
bool XmlRpcServer::executeMulticall | ( | const std::string & | methodName, | |
XmlRpcValue & | params, | |||
XmlRpcValue & | result | |||
) | [protected] |
Execute multiple calls and return the results in an array.
System.multicall implementation
Definition at line 395 of file XmlRpcServer.cc.
Referenced by executeRequest().
00398 { 00399 if (methodName != MULTICALL) return false; 00400 00401 // There ought to be 1 parameter, an array of structs 00402 if (params.size() != 1 || params[0].getType() != XmlRpcValue::TypeArray) 00403 throw XmlRpcException(MULTICALL + ": Invalid argument (expected an array)"); 00404 00405 int nc = params[0].size(); 00406 result.setSize(nc); 00407 00408 for (int i=0; i<nc; ++i) { 00409 00410 if ( ! params[0][i].hasMember(METHODNAME) || 00411 ! params[0][i].hasMember(PARAMS)) { 00412 result[i][FAULTCODE] = -1; 00413 result[i][FAULTSTRING] = MULTICALL + 00414 ": Invalid argument (expected a struct with members methodName and params)"; 00415 continue; 00416 } 00417 00418 const std::string& methodName = params[0][i][METHODNAME]; 00419 XmlRpcValue& methodParams = params[0][i][PARAMS]; 00420 00421 XmlRpcValue resultValue; 00422 resultValue.setSize(1); 00423 try { 00424 if ( ! executeMethod(methodName, methodParams, resultValue[0]) && 00425 ! executeMulticall(methodName, params, resultValue[0])) 00426 { 00427 result[i][FAULTCODE] = -1; 00428 result[i][FAULTSTRING] = methodName + ": unknown method name"; 00429 } 00430 else 00431 result[i] = resultValue; 00432 00433 } catch (const XmlRpcException& fault) { 00434 result[i][FAULTCODE] = fault.getCode(); 00435 result[i][FAULTSTRING] = fault.getMessage(); 00436 } 00437 } 00438 00439 return true; 00440 }
std::string XmlRpcServer::executeRequest | ( | std::string const & | request | ) | [virtual] |
Parses the request xml, runs the method, generates the response (header+xml).
Returns a fault response if an error occurs during method execution.
Definition at line 327 of file XmlRpcServer.cc.
Referenced by XmlRpc::XmlRpcServerConnection::executeRequest(), and XmlRpcInterface::writeResponse().
00328 { 00329 XmlRpcValue params, resultValue; 00330 std::string methodName = parseRequest(request, params); 00331 XmlRpcUtil::log(2, "XmlRpcServer::executeRequest: server calling method '%s'", 00332 methodName.c_str()); 00333 00334 std::string response; 00335 try { 00336 00337 if ( ! executeMethod(methodName, params, resultValue) && 00338 ! executeMulticall(methodName, params, resultValue)) 00339 response = generateFaultResponse(methodName + ": unknown method name"); 00340 else 00341 response = generateResponse(resultValue.toXml()); 00342 00343 } catch (const XmlRpcException& fault) { 00344 XmlRpcUtil::log(2, "XmlRpcServer::executeRequest: fault %s.", 00345 fault.getMessage().c_str()); 00346 response = generateFaultResponse(fault.getMessage(), fault.getCode()); 00347 } 00348 00349 return response; 00350 }
void XmlRpcServer::exit | ( | ) |
Temporarily stop processing client requests and exit the work() method.
Definition at line 225 of file XmlRpcServer.cc.
XmlRpcServerMethod * XmlRpcServer::findMethod | ( | const std::string & | name | ) | const |
Look up a method by name.
Definition at line 79 of file XmlRpcServer.cc.
Referenced by executeMethod().
std::string XmlRpcServer::generateFaultResponse | ( | std::string const & | msg, | |
int | errorCode = -1 | |||
) | [protected] |
Construct a fault response.
Definition at line 482 of file XmlRpcServer.cc.
Referenced by executeRequest(), XmlRpcInterface::handleRpcResponse(), and XmlRpcInterface::handleRpcTimeout().
00483 { 00484 const char RESPONSE_1[] = 00485 "<?xml version=\"1.0\"?>\r\n" 00486 "<methodResponse><fault>\r\n\t"; 00487 const char RESPONSE_2[] = 00488 "\r\n</fault></methodResponse>\r\n"; 00489 00490 XmlRpcValue faultStruct; 00491 faultStruct[FAULTCODE] = errorCode; 00492 faultStruct[FAULTSTRING] = errorMsg; 00493 std::string body = RESPONSE_1 + faultStruct.toXml() + RESPONSE_2; 00494 std::string header = generateHeader(body); 00495 00496 return header + body; 00497 }
std::string XmlRpcServer::generateHeader | ( | std::string const & | body | ) | [protected] |
Return the appropriate headers for the response.
Definition at line 464 of file XmlRpcServer.cc.
Referenced by generateFaultResponse(), and generateResponse().
00465 { 00466 std::string header = 00467 "HTTP/1.1 200 OK\r\n" 00468 "Server: "; 00469 header += XMLRPC_VERSION; 00470 header += "\r\n" 00471 "Content-Type: text/xml\r\n" 00472 "Content-length: "; 00473 00474 char buffLen[40]; 00475 sprintf(buffLen,"%d\r\n\r\n", body.size()); 00476 00477 return header + buffLen; 00478 }
std::string XmlRpcServer::generateResponse | ( | std::string const & | resultXml | ) | [protected] |
Construct a response from the result XML.
Definition at line 445 of file XmlRpcServer.cc.
Referenced by executeRequest(), and XmlRpcInterface::handleRpcResponse().
00446 { 00447 const char RESPONSE_1[] = 00448 "<?xml version=\"1.0\"?>\r\n" 00449 "<methodResponse><params><param>\r\n\t"; 00450 const char RESPONSE_2[] = 00451 "\r\n</param></params></methodResponse>\r\n"; 00452 00453 std::string body = RESPONSE_1 + resultXml + RESPONSE_2; 00454 std::string header = generateHeader(body); 00455 std::string response = header + body; 00456 00457 XmlRpcUtil::log(5, "XmlRpcServer::generateResponse:\n%s\n", response.c_str()); 00458 return response; 00459 }
int XmlRpcServer::getPort | ( | void | ) | const |
Get the port number this server is listening on.
Definition at line 145 of file XmlRpcServer.cc.
00146 { 00147 return XmlRpcSocket::getPort(getfd()); 00148 }
unsigned XmlRpcServer::handleEvent | ( | unsigned | eventType | ) | [virtual] |
Handle client connection requests.
Implements XmlRpc::XmlRpcSource.
Definition at line 165 of file XmlRpcServer.cc.
00166 { 00167 acceptConnection(); 00168 return XmlRpcDispatch::ReadableEvent; // Continue to monitor this fd 00169 }
void XmlRpcServer::listMethods | ( | XmlRpcValue & | result | ) |
Introspection support.
Definition at line 312 of file XmlRpcServer.cc.
std::string XmlRpcServer::parseRequest | ( | std::string const & | request, | |
XmlRpcValue & | params | |||
) | [protected] |
Parse the methodName and parameters from the request.
Definition at line 354 of file XmlRpcServer.cc.
Referenced by executeRequest().
00355 { 00356 int offset = 0; // Number of chars parsed from the request 00357 00358 std::string methodName = XmlRpcUtil::parseTag(METHODNAME_TAG, request, &offset); 00359 00360 if (methodName.size() > 0 && XmlRpcUtil::findTag(PARAMS_TAG, request, &offset)) 00361 { 00362 int nArgs = 0; 00363 while (XmlRpcUtil::nextTagIs(PARAM_TAG, request, &offset)) { 00364 params[nArgs++] = XmlRpcValue(request, &offset); 00365 (void) XmlRpcUtil::nextTagIs(PARAM_ETAG, request, &offset); 00366 } 00367 00368 (void) XmlRpcUtil::nextTagIs(PARAMS_ETAG, request, &offset); 00369 } 00370 00371 return methodName; 00372 }
void XmlRpcServer::removeConnection | ( | XmlRpcServerConnection * | sc | ) | [virtual] |
Remove a connection from the dispatcher.
Definition at line 217 of file XmlRpcServer.cc.
Referenced by XmlRpc::XmlRpcServerConnection::~XmlRpcServerConnection().
00218 { 00219 _disp.removeSource(sc); 00220 }
void XmlRpcServer::removeMethod | ( | const std::string & | methodName | ) |
Remove a command from the RPC server by name.
Definition at line 69 of file XmlRpcServer.cc.
void XmlRpcServer::removeMethod | ( | XmlRpcServerMethod * | method | ) |
Remove a command from the RPC server.
Definition at line 60 of file XmlRpcServer.cc.
Referenced by enableIntrospection(), and XmlRpc::XmlRpcServerMethod::~XmlRpcServerMethod().
void XmlRpcServer::shutdown | ( | ) |
Close all connections with clients and the socket file descriptor.
Definition at line 233 of file XmlRpcServer.cc.
Referenced by ~XmlRpcServer().
void XmlRpcServer::work | ( | double | msTime | ) |
Process client requests for the specified time.
Definition at line 154 of file XmlRpcServer.cc.
00155 { 00156 XmlRpcUtil::log(2, "XmlRpcServer::work: waiting for a connection"); 00157 _disp.work(msTime); 00158 }
XmlRpcDispatch XmlRpc::XmlRpcServer::_disp [protected] |
Event dispatcher.
Definition at line 151 of file XmlRpcServer.h.
Referenced by bindAndListen(), dispatchConnection(), exit(), removeConnection(), shutdown(), and work().
bool XmlRpc::XmlRpcServer::_introspectionEnabled [protected] |
Whether the introspection API is supported by this server.
Definition at line 148 of file XmlRpcServer.h.
Referenced by enableIntrospection(), and XmlRpcServer().
XmlRpcServerMethod* XmlRpc::XmlRpcServer::_listMethods [protected] |
List all registered RPC methods (only available if introspection is enabled).
Definition at line 160 of file XmlRpcServer.h.
Referenced by enableIntrospection(), XmlRpcServer(), and ~XmlRpcServer().
XmlRpcServerMethod* XmlRpc::XmlRpcServer::_methodHelp [protected] |
Return help string for a specified method (only available if introspection is enabled).
Definition at line 163 of file XmlRpcServer.h.
Referenced by enableIntrospection(), XmlRpcServer(), and ~XmlRpcServer().
MethodMap XmlRpc::XmlRpcServer::_methods [protected] |
Registered RPC methods.
Definition at line 157 of file XmlRpcServer.h.
Referenced by addMethod(), findMethod(), listMethods(), removeMethod(), and ~XmlRpcServer().
const std::string XmlRpcServer::FAULTCODE = "faultCode" [static, protected] |
Definition at line 110 of file XmlRpcServer.h.
Referenced by executeMulticall(), and generateFaultResponse().
const std::string XmlRpcServer::FAULTSTRING = "faultString" [static, protected] |
Definition at line 111 of file XmlRpcServer.h.
Referenced by executeMulticall(), and generateFaultResponse().
const std::string XmlRpcServer::METHODNAME = "methodName" [static, protected] |
Definition at line 107 of file XmlRpcServer.h.
Referenced by executeMulticall().
const char XmlRpcServer::METHODNAME_TAG = "<methodName>" [static, protected] |
Definition at line 100 of file XmlRpcServer.h.
Referenced by parseRequest().
const char XmlRpcServer::PARAM_ETAG = "</param>" [static, protected] |
Definition at line 104 of file XmlRpcServer.h.
Referenced by parseRequest().
const char XmlRpcServer::PARAM_TAG = "<param>" [static, protected] |
Definition at line 103 of file XmlRpcServer.h.
Referenced by parseRequest().
const std::string XmlRpcServer::PARAMS = "params" [static, protected] |
Definition at line 108 of file XmlRpcServer.h.
Referenced by executeMulticall().
const char XmlRpcServer::PARAMS_ETAG = "</params>" [static, protected] |
Definition at line 102 of file XmlRpcServer.h.
Referenced by parseRequest().
const char XmlRpcServer::PARAMS_TAG = "<params>" [static, protected] |
Definition at line 101 of file XmlRpcServer.h.
Referenced by parseRequest().
const std::string XmlRpc::XmlRpcServer::SYSTEM_MULTICALL [static, protected] |
Definition at line 106 of file XmlRpcServer.h.