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 #include <errno.h>
13 #include <string.h>
14 #if !defined(_WINDOWS)
15 # include <sys/resource.h>
16 #else
17 # include <winsock2.h>
18 #endif
19 
20 using namespace XmlRpc;
21 
22 const int XmlRpcServer::FREE_FD_BUFFER = 32;
24 
26  : _introspectionEnabled(false),
27  _listMethods(0),
28  _methodHelp(0),
29  _port(0),
30  _accept_error(false),
31  _accept_retry_time_sec(0.0)
32 {
33  // Ask dispatch not to close this socket if it becomes unreadable.
34  setKeepOpen(true);
35 }
36 
37 
39 {
40  this->shutdown();
41  _methods.clear();
42  delete _listMethods;
43  delete _methodHelp;
44 }
45 
46 
47 // Add a command to the RPC server
48 void
50 {
51  _methods[method->name()] = method;
52 }
53 
54 // Remove a command from the RPC server
55 void
57 {
58  MethodMap::iterator i = _methods.find(method->name());
59  if (i != _methods.end())
60  _methods.erase(i);
61 }
62 
63 // Remove a command from the RPC server by name
64 void
65 XmlRpcServer::removeMethod(const std::string& methodName)
66 {
67  MethodMap::iterator i = _methods.find(methodName);
68  if (i != _methods.end())
69  _methods.erase(i);
70 }
71 
72 
73 // Look up a method by name
75 XmlRpcServer::findMethod(const std::string& name) const
76 {
77  MethodMap::const_iterator i = _methods.find(name);
78  if (i == _methods.end())
79  return 0;
80  return i->second;
81 }
82 
83 
84 // Create a socket, bind to the specified port, and
85 // set it in listen mode to make it available for clients.
86 bool
87 XmlRpcServer::bindAndListen(int port, int backlog /*= 5*/)
88 {
89  int fd = XmlRpcSocket::socket();
90  if (fd < 0)
91  {
92  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not create socket (%s).", XmlRpcSocket::getErrorMsg().c_str());
93  return false;
94  }
95 
96  this->setfd(fd);
97 
98  // Don't block on reads/writes
100  {
101  this->close();
102  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set socket to non-blocking input mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
103  return false;
104  }
105 
106  // Allow this port to be re-bound immediately so server re-starts are not delayed
107  if ( ! XmlRpcSocket::setReuseAddr(fd))
108  {
109  this->close();
110  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set SO_REUSEADDR socket option (%s).", XmlRpcSocket::getErrorMsg().c_str());
111  return false;
112  }
113 
114  // Bind to the specified port on the default interface
115  if ( ! XmlRpcSocket::bind(fd, port))
116  {
117  this->close();
118  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not bind to specified port (%s).", XmlRpcSocket::getErrorMsg().c_str());
119  return false;
120  }
121 
122  // Set in listening mode
123  if ( ! XmlRpcSocket::listen(fd, backlog))
124  {
125  this->close();
126  XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set socket in listening mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
127  return false;
128  }
129 
131 
132  XmlRpcUtil::log(2, "XmlRpcServer::bindAndListen: server listening on port %d fd %d", _port, fd);
133 
134  // Notify the dispatcher to listen on this source when we are in work()
136 
137  return true;
138 }
139 
140 
141 // Process client requests for the specified time
142 void
143 XmlRpcServer::work(double msTime)
144 {
145  XmlRpcUtil::log(2, "XmlRpcServer::work: waiting for a connection");
148  }
149  _disp.work(msTime);
150 }
151 
152 
153 
154 // Handle input on the server socket by accepting the connection
155 // and reading the rpc request.
156 unsigned
158 {
159  return acceptConnection();
160 }
161 
162 
163 // Accept a client connection request and create a connection to
164 // handle method calls from the client.
165 unsigned
167 {
168  int s = XmlRpcSocket::accept(this->getfd());
169  XmlRpcUtil::log(2, "XmlRpcServer::acceptConnection: socket %d", s);
170  if (s < 0)
171  {
172  //this->close();
173  XmlRpcUtil::error("XmlRpcServer::acceptConnection: Could not accept connection (%s).", XmlRpcSocket::getErrorMsg().c_str());
174 
175  // Note that there was an accept error; retry in 1 second
176  _accept_error = true;
178  return 0; // Stop monitoring this FD
179  }
180  else if ( !enoughFreeFDs() )
181  {
183  XmlRpcUtil::error("XmlRpcServer::acceptConnection: Rejecting client, not enough free file descriptors");
184  }
185  else if ( ! XmlRpcSocket::setNonBlocking(s))
186  {
188  XmlRpcUtil::error("XmlRpcServer::acceptConnection: Could not set socket to non-blocking input mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
189  }
190  else // Notify the dispatcher to listen for input on this source when we are in work()
191  {
192  _accept_error = false;
193  XmlRpcUtil::log(2, "XmlRpcServer::acceptConnection: creating a connection");
195  }
196  return XmlRpcDispatch::ReadableEvent; // Continue to monitor this fd
197 }
198 
200  // This function is just to check if enough FDs are there.
201  //
202  // If the underlying system calls here fail, this will print an error and
203  // return false
204 
205  return true;
206 }
207 
208 
209 // Create a new connection object for processing requests from a specific client.
212 {
213  // Specify that the connection object be deleted when it is closed
214  return new XmlRpcServerConnection(s, this, true);
215 }
216 
217 
218 void
220 {
221  _disp.removeSource(sc);
222 }
223 
224 
225 // Stop processing client requests
226 void
228 {
229  _disp.exit();
230 }
231 
232 
233 // Close the server socket file descriptor and stop monitoring connections
234 void
236 {
237  // This closes and destroys all connections as well as closing this socket
238  _disp.clear();
239 }
240 
241 
242 // Introspection support
243 static const std::string LIST_METHODS("system.listMethods");
244 static const std::string METHOD_HELP("system.methodHelp");
245 static const std::string MULTICALL("system.multicall");
246 
247 
248 // List all methods available on a server
250 {
251 public:
253 
255  {
256  _server->listMethods(result);
257  }
258 
259  std::string help() { return std::string("List all methods available on a server as an array of strings"); }
260 };
261 
262 
263 // Retrieve the help string for a named method
265 {
266 public:
268 
269  void execute(XmlRpcValue& params, XmlRpcValue& result)
270  {
271  if (params[0].getType() != XmlRpcValue::TypeString)
272  throw XmlRpcException(METHOD_HELP + ": Invalid argument type");
273 
274  XmlRpcServerMethod* m = _server->findMethod(params[0]);
275  if ( ! m)
276  throw XmlRpcException(METHOD_HELP + ": Unknown method name");
277 
278  result = m->help();
279  }
280 
281  std::string help() { return std::string("Retrieve the help string for a named method"); }
282 };
283 
284 
285 // Specify whether introspection is enabled or not. Default is enabled.
286 void
288 {
289  if (_introspectionEnabled == enabled)
290  return;
291 
292  _introspectionEnabled = enabled;
293 
294  if (enabled)
295  {
296  if ( ! _listMethods)
297  {
298  _listMethods = new ListMethods(this);
299  _methodHelp = new MethodHelp(this);
300  } else {
303  }
304  }
305  else
306  {
309  }
310 }
311 
312 
313 void
315 {
316  int i = 0;
317  result.setSize(_methods.size()+1);
318  for (MethodMap::iterator it=_methods.begin(); it != _methods.end(); ++it)
319  result[i++] = it->first;
320 
321  // Multicall support is built into XmlRpcServerConnection
322  result[i] = MULTICALL;
323 }
324 
325 
326 
XmlRpc::XmlRpcServer::enableIntrospection
void enableIntrospection(bool enabled=true)
Specify whether introspection is enabled or not. Default is not enabled.
Definition: XmlRpcServer.cpp:287
XmlRpc::XmlRpcServer::_disp
XmlRpcDispatch _disp
Definition: XmlRpcServer.h:106
XmlRpc::XmlRpcServer::removeConnection
virtual void removeConnection(XmlRpcServerConnection *)
Remove a connection from the dispatcher.
Definition: XmlRpcServer.cpp:219
XmlRpc::XmlRpcSocket::socket
static int socket()
Creates a stream (TCP) socket. Returns -1 on failure.
Definition: XmlRpcSocket.cpp:101
XmlRpc::XmlRpcServer
A class to handle XML RPC requests.
Definition: XmlRpcServer.h:41
XmlRpc::XmlRpcServerMethod::help
virtual std::string help()
Definition: XmlRpcServerMethod.h:41
s
XmlRpcServer s
Definition: HelloServer.cpp:11
XmlRpc::XmlRpcSource::setfd
void setfd(int fd)
Specify the file descriptor to monitor.
Definition: XmlRpcSource.h:29
XmlRpc::XmlRpcUtil::log
static void log(int level, const char *fmt,...)
Dump messages somewhere.
Definition: XmlRpcUtil.cpp:82
XmlRpc::XmlRpcServer::FREE_FD_BUFFER
static const int FREE_FD_BUFFER
Definition: XmlRpcServer.h:127
XmlRpc::XmlRpcSocket::close
static void close(int socket)
Closes a socket.
Definition: XmlRpcSocket.cpp:109
XmlRpc::XmlRpcSource::setKeepOpen
void setKeepOpen(bool b=true)
Specify whether the file descriptor should be kept open if it is no longer monitored.
Definition: XmlRpcSource.h:34
XmlRpcServer.h
XmlRpc
Definition: XmlRpcClient.h:20
XmlRpc::XmlRpcServer::enoughFreeFDs
bool enoughFreeFDs()
Check if enough number of free file descriptors.
Definition: XmlRpcServer.cpp:199
XmlRpc::XmlRpcServer::_accept_retry_time_sec
double _accept_retry_time_sec
Definition: XmlRpcServer.h:124
XmlRpc::XmlRpcServer::_methodHelp
XmlRpcServerMethod * _methodHelp
Definition: XmlRpcServer.h:114
XmlRpc::XmlRpcDispatch::exit
void exit()
Exit from work routine.
Definition: XmlRpcDispatch.cpp:259
XmlRpc::XmlRpcDispatch::ReadableEvent
@ ReadableEvent
data available to read
Definition: XmlRpcDispatch.h:33
XmlRpc::XmlRpcSource::close
virtual void close()
Close the owned fd. If deleteOnClose was specified at construction, the object is deleted.
Definition: XmlRpcSource.cpp:20
XmlRpc::XmlRpcServer::_accept_error
bool _accept_error
Definition: XmlRpcServer.h:119
XmlRpc::XmlRpcServer::acceptConnection
virtual unsigned acceptConnection()
Accept a client connection request.
Definition: XmlRpcServer.cpp:166
XmlRpc::XmlRpcDispatch::addSource
void addSource(XmlRpcSource *source, unsigned eventMask)
Definition: XmlRpcDispatch.cpp:96
XmlRpc::XmlRpcServer::_introspectionEnabled
bool _introspectionEnabled
Definition: XmlRpcServer.h:103
XmlRpc::XmlRpcSocket::setNonBlocking
static bool setNonBlocking(int socket)
Sets a stream (TCP) socket to perform non-blocking IO. Returns false on failure.
Definition: XmlRpcSocket.cpp:123
XmlRpc::XmlRpcServer::_methods
MethodMap _methods
Definition: XmlRpcServer.h:110
MULTICALL
static const std::string MULTICALL("system.multicall")
XmlRpc::XmlRpcServer::exit
void exit()
Temporarily stop processing client requests and exit the work() method.
Definition: XmlRpcServer.cpp:227
XmlRpc::XmlRpcServer::listMethods
void listMethods(XmlRpcValue &result)
Introspection support.
Definition: XmlRpcServer.cpp:314
XmlRpc::XmlRpcServer::createConnection
virtual XmlRpcServerConnection * createConnection(int socket)
Create a new connection object for processing requests from a specific client.
Definition: XmlRpcServer.cpp:211
XmlRpc::XmlRpcSocket::get_port
static int get_port(int socket)
Definition: XmlRpcSocket.cpp:397
XmlRpc::XmlRpcValue::TypeString
@ TypeString
Definition: XmlRpcValue.h:33
MethodHelp::MethodHelp
MethodHelp(XmlRpcServer *s)
Definition: XmlRpcServer.cpp:267
XmlRpc::XmlRpcServerMethod
Abstract class representing a single RPC method.
Definition: XmlRpcServerMethod.h:26
XmlRpc::XmlRpcServer::_port
int _port
Definition: XmlRpcServer.h:116
XmlRpc::XmlRpcServer::ACCEPT_RETRY_INTERVAL_SEC
static const double ACCEPT_RETRY_INTERVAL_SEC
Definition: XmlRpcServer.h:122
XmlRpc::XmlRpcServer::findMethod
XmlRpcServerMethod * findMethod(const std::string &name) const
Look up a method by name.
Definition: XmlRpcServer.cpp:75
XmlRpc::XmlRpcDispatch::getTime
double getTime()
Definition: XmlRpcDispatch.cpp:281
XmlRpc::XmlRpcUtil::error
static void error(const char *fmt,...)
Dump error messages somewhere.
Definition: XmlRpcUtil.cpp:97
XmlRpcSocket.h
XmlRpc::XmlRpcDispatch::removeSource
void removeSource(XmlRpcSource *source)
Definition: XmlRpcDispatch.cpp:103
XmlRpc::XmlRpcSocket::accept
static int accept(int socket)
Accept a client connection request.
Definition: XmlRpcSocket.cpp:183
XmlRpc::XmlRpcSource::getfd
int getfd() const
Return the file descriptor being monitored.
Definition: XmlRpcSource.h:27
ListMethods::ListMethods
ListMethods(XmlRpcServer *s)
Definition: XmlRpcServer.cpp:252
MethodHelp::help
std::string help()
Definition: XmlRpcServer.cpp:281
XmlRpc::XmlRpcServer::bindAndListen
bool bindAndListen(int port, int backlog=5)
Definition: XmlRpcServer.cpp:87
XmlRpc::XmlRpcException
Definition: XmlRpcException.h:23
XmlRpc::XmlRpcDispatch::work
void work(double msTime)
Definition: XmlRpcDispatch.cpp:130
LIST_METHODS
static const std::string LIST_METHODS("system.listMethods")
XmlRpc::XmlRpcDispatch::clear
void clear()
Clear all sources from the monitored sources list. Sources are closed.
Definition: XmlRpcDispatch.cpp:266
XmlRpc::XmlRpcServer::shutdown
void shutdown()
Close all connections with clients and the socket file descriptor.
Definition: XmlRpcServer.cpp:235
XmlRpc::XmlRpcServer::handleEvent
virtual unsigned handleEvent(unsigned eventType)
Handle client connection requests.
Definition: XmlRpcServer.cpp:157
XmlRpc::XmlRpcServer::work
void work(double msTime)
Process client requests for the specified time.
Definition: XmlRpcServer.cpp:143
XmlRpc::XmlRpcServerMethod::name
std::string & name()
Returns the name of the method.
Definition: XmlRpcServerMethod.h:34
XmlRpc::XmlRpcSocket::setReuseAddr
static bool setReuseAddr(int socket)
Definition: XmlRpcSocket.cpp:135
XmlRpc::XmlRpcServer::XmlRpcServer
XmlRpcServer()
Create a server object.
Definition: XmlRpcServer.cpp:25
XmlRpcServerMethod.h
XmlRpc::XmlRpcServer::removeMethod
void removeMethod(XmlRpcServerMethod *method)
Remove a command from the RPC server.
Definition: XmlRpcServer.cpp:56
ListMethods
Definition: XmlRpcServer.cpp:249
XmlRpc::XmlRpcServer::addMethod
void addMethod(XmlRpcServerMethod *method)
Add a command to the RPC server.
Definition: XmlRpcServer.cpp:49
XmlRpc::XmlRpcServer::~XmlRpcServer
virtual ~XmlRpcServer()
Destructor.
Definition: XmlRpcServer.cpp:38
XmlRpc::XmlRpcSocket::getErrorMsg
static std::string getErrorMsg()
Returns message corresponding to last error.
Definition: XmlRpcSocket.cpp:383
XmlRpcException.h
XmlRpc::XmlRpcValue::setSize
void setSize(int size)
Specify the size for array values. Array values will grow beyond this size if needed.
Definition: XmlRpcValue.h:130
XmlRpc::XmlRpcSocket::bind
static bool bind(int socket, int port)
Bind to a specified port.
Definition: XmlRpcSocket.cpp:145
ListMethods::help
std::string help()
Definition: XmlRpcServer.cpp:259
METHOD_HELP
static const std::string METHOD_HELP("system.methodHelp")
XmlRpc::XmlRpcServer::_listMethods
XmlRpcServerMethod * _listMethods
Definition: XmlRpcServer.h:113
XmlRpc::XmlRpcServerConnection
A class to handle XML RPC requests from a particular client.
Definition: XmlRpcServerConnection.h:26
ListMethods::execute
void execute(XmlRpcValue &, XmlRpcValue &result)
Execute the method. Subclasses must provide a definition for this method.
Definition: XmlRpcServer.cpp:254
MethodHelp::execute
void execute(XmlRpcValue &params, XmlRpcValue &result)
Execute the method. Subclasses must provide a definition for this method.
Definition: XmlRpcServer.cpp:269
XmlRpcUtil.h
XmlRpc::XmlRpcValue
RPC method arguments and results are represented by Values.
Definition: XmlRpcValue.h:24
XmlRpcServerConnection.h
MethodHelp
Definition: XmlRpcServer.cpp:264
XmlRpc::XmlRpcSocket::listen
static bool listen(int socket, int backlog)
Set socket in listen mode.
Definition: XmlRpcSocket.cpp:176


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix, Dirk Thomas , Jacob Perron
autogenerated on Tue May 20 2025 03:00:08