XmlRpc::XmlRpcServer Class Reference

A class to handle XML RPC requests. More...

#include <XmlRpcServer.h>

Inheritance diagram for XmlRpc::XmlRpcServer:
XmlRpc::XmlRpcSource XmlRpc::XmlRpcThreadedServer XmlRpcInterface

List of all members.

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.
XmlRpcServerMethodfindMethod (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 XmlRpcServerConnectioncreateConnection (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 &params)
 Parse the methodName and parameters from the request.
bool executeMethod (const std::string &methodName, XmlRpcValue &params, XmlRpcValue &result)
 Execute a named method with the specified params.
bool executeMulticall (const std::string &methodName, XmlRpcValue &params, 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"

Detailed Description

A class to handle XML RPC requests.

Definition at line 40 of file XmlRpcServer.h.


Member Typedef Documentation

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.


Constructor & Destructor Documentation

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 }


Member Function Documentation

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().

00054 {
00055   _methods[method->getName()] = method;
00056 }

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.

Parameters:
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.

00226 {
00227   _disp.exit();
00228 }

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().

00080 {
00081   MethodMap::const_iterator i = _methods.find(name);
00082   if (i == _methods.end())
00083     return 0;
00084   return i->second;
00085 }

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.

00313 {
00314   int i = 0;
00315   result.setSize(_methods.size()+1);
00316   for (MethodMap::iterator it=_methods.begin(); it != _methods.end(); ++it)
00317     result[i++] = it->first;
00318 
00319   // Multicall support is built into XmlRpcServer::executeRequest
00320   result[i] = MULTICALL;
00321 }

std::string XmlRpcServer::parseRequest ( std::string const &  request,
XmlRpcValue params 
) [protected]

Parse the methodName and parameters from the request.

Returns:
the methodName

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.

00070 {
00071   MethodMap::iterator i = _methods.find(methodName);
00072   if (i != _methods.end())
00073     _methods.erase(i);
00074 }

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().

00061 {
00062   MethodMap::iterator i = _methods.find(method->getName());
00063   if (i != _methods.end())
00064     _methods.erase(i);
00065 }

void XmlRpcServer::shutdown (  ) 

Close all connections with clients and the socket file descriptor.

Definition at line 233 of file XmlRpcServer.cc.

Referenced by ~XmlRpcServer().

00234 {
00235   // This closes and destroys all connections as well as closing this socket
00236   _disp.clear();
00237 }

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 }


Member Data Documentation

Event dispatcher.

Definition at line 151 of file XmlRpcServer.h.

Referenced by bindAndListen(), dispatchConnection(), exit(), removeConnection(), shutdown(), and work().

Whether the introspection API is supported by this server.

Definition at line 148 of file XmlRpcServer.h.

Referenced by enableIntrospection(), and XmlRpcServer().

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().

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().

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.


The documentation for this class was generated from the following files:
Generated on Wed May 26 16:21:20 2010 for OverSim by  doxygen 1.6.3