XmlRpcServer.cpp
Go to the documentation of this file.
1 // this file modified by Morgan Quigley on 22 Apr 2008.
2 // added features: server can be opened on port 0 and you can read back
3 // what port the OS gave you
4 
9 #include "xmlrpcpp/XmlRpcUtil.h"
11 
12 
13 using namespace XmlRpc;
14 
15 
17 {
18  _introspectionEnabled = false;
19  _listMethods = 0;
20  _methodHelp = 0;
21  _port = 0;
22 }
23 
24 
26 {
27  this->shutdown();
28  _methods.clear();
29  delete _listMethods;
30  delete _methodHelp;
31 }
32 
33 
34 // Add a command to the RPC server
35 void
37 {
38  _methods[method->name()] = method;
39 }
40 
41 // Remove a command from the RPC server
42 void
44 {
45  MethodMap::iterator i = _methods.find(method->name());
46  if (i != _methods.end())
47  _methods.erase(i);
48 }
49 
50 // Remove a command from the RPC server by name
51 void
52 XmlRpcServer::removeMethod(const std::string& methodName)
53 {
54  MethodMap::iterator i = _methods.find(methodName);
55  if (i != _methods.end())
56  _methods.erase(i);
57 }
58 
59 
60 // Look up a method by name
62 XmlRpcServer::findMethod(const std::string& name) const
63 {
64  MethodMap::const_iterator i = _methods.find(name);
65  if (i == _methods.end())
66  return 0;
67  return i->second;
68 }
69 
70 
71 // Create a socket, bind to the specified port, and
72 // set it in listen mode to make it available for clients.
73 bool
74 XmlRpcServer::bindAndListen(int port, int backlog /*= 5*/)
75 {
76  int fd = XmlRpcSocket::socket();
77  if (fd < 0)
78  {
79  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not create socket (%s).", XmlRpcSocket::getErrorMsg().c_str());
80  return false;
81  }
82 
83  this->setfd(fd);
84 
85  // Don't block on reads/writes
87  {
88  this->close();
89  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set socket to non-blocking input mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
90  return false;
91  }
92 
93  // Allow this port to be re-bound immediately so server re-starts are not delayed
94  if ( ! XmlRpcSocket::setReuseAddr(fd))
95  {
96  this->close();
97  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set SO_REUSEADDR socket option (%s).", XmlRpcSocket::getErrorMsg().c_str());
98  return false;
99  }
100 
101  // Bind to the specified port on the default interface
102  if ( ! XmlRpcSocket::bind(fd, port))
103  {
104  this->close();
105  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not bind to specified port (%s).", XmlRpcSocket::getErrorMsg().c_str());
106  return false;
107  }
108 
109  // Set in listening mode
110  if ( ! XmlRpcSocket::listen(fd, backlog))
111  {
112  this->close();
113  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set socket in listening mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
114  return false;
115  }
116 
118 
119  XmlRpcUtil::log(2, "XmlRpcServer::bindAndListen: server listening on port %d fd %d", _port, fd);
120 
121  // Notify the dispatcher to listen on this source when we are in work()
123 
124  return true;
125 }
126 
127 
128 // Process client requests for the specified time
129 void
130 XmlRpcServer::work(double msTime)
131 {
132  XmlRpcUtil::log(2, "XmlRpcServer::work: waiting for a connection");
133  _disp.work(msTime);
134 }
135 
136 
137 
138 // Handle input on the server socket by accepting the connection
139 // and reading the rpc request.
140 unsigned
142 {
144  return XmlRpcDispatch::ReadableEvent; // Continue to monitor this fd
145 }
146 
147 
148 // Accept a client connection request and create a connection to
149 // handle method calls from the client.
150 void
152 {
153  int s = XmlRpcSocket::accept(this->getfd());
154  XmlRpcUtil::log(2, "XmlRpcServer::acceptConnection: socket %d", s);
155  if (s < 0)
156  {
157  //this->close();
158  XmlRpcUtil::error("XmlRpcServer::acceptConnection: Could not accept connection (%s).", XmlRpcSocket::getErrorMsg().c_str());
159  }
160  else if ( ! XmlRpcSocket::setNonBlocking(s))
161  {
163  XmlRpcUtil::error("XmlRpcServer::acceptConnection: Could not set socket to non-blocking input mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
164  }
165  else // Notify the dispatcher to listen for input on this source when we are in work()
166  {
167  XmlRpcUtil::log(2, "XmlRpcServer::acceptConnection: creating a connection");
169  }
170 }
171 
172 
173 // Create a new connection object for processing requests from a specific client.
176 {
177  // Specify that the connection object be deleted when it is closed
178  return new XmlRpcServerConnection(s, this, true);
179 }
180 
181 
182 void
184 {
185  _disp.removeSource(sc);
186 }
187 
188 
189 // Stop processing client requests
190 void
192 {
193  _disp.exit();
194 }
195 
196 
197 // Close the server socket file descriptor and stop monitoring connections
198 void
200 {
201  // This closes and destroys all connections as well as closing this socket
202  _disp.clear();
203 }
204 
205 
206 // Introspection support
207 static const std::string LIST_METHODS("system.listMethods");
208 static const std::string METHOD_HELP("system.methodHelp");
209 static const std::string MULTICALL("system.multicall");
210 
211 
212 // List all methods available on a server
214 {
215 public:
217 
219  {
220  _server->listMethods(result);
221  }
222 
223  std::string help() { return std::string("List all methods available on a server as an array of strings"); }
224 };
225 
226 
227 // Retrieve the help string for a named method
229 {
230 public:
232 
233  void execute(XmlRpcValue& params, XmlRpcValue& result)
234  {
235  if (params[0].getType() != XmlRpcValue::TypeString)
236  throw XmlRpcException(METHOD_HELP + ": Invalid argument type");
237 
238  XmlRpcServerMethod* m = _server->findMethod(params[0]);
239  if ( ! m)
240  throw XmlRpcException(METHOD_HELP + ": Unknown method name");
241 
242  result = m->help();
243  }
244 
245  std::string help() { return std::string("Retrieve the help string for a named method"); }
246 };
247 
248 
249 // Specify whether introspection is enabled or not. Default is enabled.
250 void
252 {
253  if (_introspectionEnabled == enabled)
254  return;
255 
256  _introspectionEnabled = enabled;
257 
258  if (enabled)
259  {
260  if ( ! _listMethods)
261  {
262  _listMethods = new ListMethods(this);
263  _methodHelp = new MethodHelp(this);
264  } else {
267  }
268  }
269  else
270  {
273  }
274 }
275 
276 
277 void
279 {
280  int i = 0;
281  result.setSize(_methods.size()+1);
282  for (MethodMap::iterator it=_methods.begin(); it != _methods.end(); ++it)
283  result[i++] = it->first;
284 
285  // Multicall support is built into XmlRpcServerConnection
286  result[i] = MULTICALL;
287 }
288 
289 
290 
A class to handle XML RPC requests from a particular client.
virtual XmlRpcServerConnection * createConnection(int socket)
Create a new connection object for processing requests from a specific client.
Definition: XmlRpc.h:39
virtual void acceptConnection()
Accept a client connection request.
static bool setReuseAddr(int socket)
RPC method arguments and results are represented by Values.
Definition: XmlRpcValue.h:24
static const std::string METHOD_HELP("system.methodHelp")
static int get_port(int socket)
void execute(XmlRpcValue &, XmlRpcValue &result)
Execute the method. Subclasses must provide a definition for this method.
static int accept(int socket)
Accept a client connection request.
std::string help()
void shutdown()
Close all connections with clients and the socket file descriptor.
void work(double msTime)
Process client requests for the specified time.
bool bindAndListen(int port, int backlog=5)
XmlRpcServer()
Create a server object.
void addMethod(XmlRpcServerMethod *method)
Add a command to the RPC server.
XmlRpcServerMethod * findMethod(const std::string &name) const
Look up a method by name.
XmlRpcServer s
Definition: HelloServer.cpp:11
void removeMethod(XmlRpcServerMethod *method)
Remove a command from the RPC server.
void removeSource(XmlRpcSource *source)
static void error(const char *fmt,...)
Dump error messages somewhere.
Definition: XmlRpcUtil.cpp:95
virtual unsigned handleEvent(unsigned eventType)
Handle client connection requests.
void clear()
Clear all sources from the monitored sources list. Sources are closed.
virtual ~XmlRpcServer()
Destructor.
static std::string getErrorMsg()
Returns message corresponding to last error.
int getfd() const
Return the file descriptor being monitored.
Definition: XmlRpcSource.h:27
Abstract class representing a single RPC method.
XmlRpcServerMethod * _listMethods
Definition: XmlRpcServer.h:106
virtual void close()
Close the owned fd. If deleteOnClose was specified at construction, the object is deleted...
void setfd(int fd)
Specify the file descriptor to monitor.
Definition: XmlRpcSource.h:29
static bool bind(int socket, int port)
Bind to a specified port.
void work(double msTime)
XmlRpcDispatch _disp
Definition: XmlRpcServer.h:99
virtual void removeConnection(XmlRpcServerConnection *)
Remove a connection from the dispatcher.
void setSize(int size)
Specify the size for array values. Array values will grow beyond this size if needed.
Definition: XmlRpcValue.h:117
static const std::string MULTICALL("system.multicall")
void execute(XmlRpcValue &params, XmlRpcValue &result)
Execute the method. Subclasses must provide a definition for this method.
void enableIntrospection(bool enabled=true)
Specify whether introspection is enabled or not. Default is not enabled.
A class to handle XML RPC requests.
Definition: XmlRpcServer.h:37
static bool listen(int socket, int backlog)
Set socket in listen mode.
static int socket()
Creates a stream (TCP) socket. Returns -1 on failure.
std::string help()
static void close(int socket)
Closes a socket.
XmlRpcServerMethod * _methodHelp
Definition: XmlRpcServer.h:107
void addSource(XmlRpcSource *source, unsigned eventMask)
virtual std::string help()
static const std::string LIST_METHODS("system.listMethods")
void exit()
Exit from work routine.
static bool setNonBlocking(int socket)
Sets a stream (TCP) socket to perform non-blocking IO. Returns false on failure.
ListMethods(XmlRpcServer *s)
void exit()
Temporarily stop processing client requests and exit the work() method.
void listMethods(XmlRpcValue &result)
Introspection support.
MethodHelp(XmlRpcServer *s)
static void log(int level, const char *fmt,...)
Dump messages somewhere.
Definition: XmlRpcUtil.cpp:80
std::string & name()
Returns the name of the method.


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley
autogenerated on Sat Oct 5 2019 03:58:22