87 char *hp = (
char*)
_header.c_str();
88 char *ep = hp +
_header.length();
93 for (
char *cp = hp; (bp == 0) && (cp < ep); ++cp) {
94 if ((ep - cp > 16) && (strncasecmp(cp,
"Content-length: ", 16) == 0))
96 else if ((ep - cp > 12) && (strncasecmp(cp,
"Connection: ", 12) == 0))
98 else if ((ep - cp > 4) && (strncmp(cp,
"\r\n\r\n", 4) == 0))
100 else if ((ep - cp > 2) && (strncmp(cp,
"\n\n", 2) == 0))
110 XmlRpcUtil::error(
"XmlRpcServerConnection::readHeader: EOF while reading header");
119 XmlRpcUtil::error(
"XmlRpcServerConnection::readHeader: No Content-length specified");
124 long int clength = 0;
125 clength = strtol(lp,
nullptr, 10);
126 if ((clength < 0) || (clength > INT_MAX)) {
127 XmlRpcUtil::error(
"XmlRpcServerConnection::readHeader: Invalid Content-length specified.");
139 if (
_header.find(
"HTTP/1.0") != std::string::npos) {
140 if (kp == 0 || strncasecmp(kp,
"keep-alive", 10) != 0)
143 if (kp != 0 && strncasecmp(kp,
"close", 5) == 0)
165 if (
_request.length() > size_t(INT_MAX)) {
166 XmlRpcUtil::error(
"XmlRpcServerConnection::readRequest: request length (%u) exceeds the maximum allowed size (%u)",
175 XmlRpcUtil::error(
"XmlRpcServerConnection::readRequest: EOF while reading request");
228 XmlRpcUtil::log(2,
"XmlRpcServerConnection::executeRequest: server calling method '%s'",
240 XmlRpcUtil::log(2,
"XmlRpcServerConnection::executeRequest: fault %s.",
275 if ( ! method)
return false;
277 method->
execute(params, result);
280 if ( ! result.
valid())
281 result = std::string();
297 int nc = params[0].
size();
300 for (
int i=0; i<nc; ++i) {
303 ! params[0][i].hasMember(
PARAMS)) {
306 ": Invalid argument (expected a struct with members methodName and params)";
310 const std::string& methodName = params[0][i][
METHODNAME];
316 if ( !
executeMethod(methodName, methodParams, resultValue[0]) &&
320 result[i][
FAULTSTRING] = methodName +
": unknown method name";
323 result[i] = resultValue;
339 const char RESPONSE_1[] =
340 "<?xml version=\"1.0\"?>\r\n" 341 "<methodResponse><params><param>\r\n\t";
342 const char RESPONSE_2[] =
343 "\r\n</param></params></methodResponse>\r\n";
345 std::string body = RESPONSE_1 + resultXml + RESPONSE_2;
349 if ((header.length() + body.length()) >
size_t(INT_MAX)) {
350 XmlRpcUtil::error(
"XmlRpcServerConnection::generateResponse: response length (%u) exceeds the maximum allowed size (%u).",
365 "HTTP/1.1 200 OK\r\n" 369 "Content-Type: text/xml\r\n" 374 sprintf_s(buffLen,40,
"%d\r\n\r\n", (
int)body.size());
376 sprintf(buffLen,
"%d\r\n\r\n", (
int)body.size());
379 return header + buffLen;
386 const char RESPONSE_1[] =
387 "<?xml version=\"1.0\"?>\r\n" 388 "<methodResponse><fault>\r\n\t";
389 const char RESPONSE_2[] =
390 "\r\n</fault></methodResponse>\r\n";
395 std::string body = RESPONSE_1 + faultStruct.
toXml() + RESPONSE_2;
virtual void execute(XmlRpcValue ¶ms, XmlRpcValue &result)=0
Execute the method. Subclasses must provide a definition for this method.
virtual void executeRequest()
int getfd() const
Return the file descriptor being monitored.
int size() const
Return the size for string, base64, array, and struct values.
XmlRpcServerMethod * findMethod(const std::string &name) const
Look up a method by name.
RPC method arguments and results are represented by Values.
XMLRPCPP_DECL const char XMLRPC_VERSION[]
Version identifier.
connected/data can be written without blocking
ServerConnectionState _connectionState
static const std::string PARAMS
static const std::string SYSTEM_MULTICALL
static std::string parseTag(const char *tag, std::string const &xml, int *offset)
static const char PARAM_TAG[]
bool valid() const
Return true if the value has been set to something.
static void error(const char *fmt,...)
Dump error messages somewhere.
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.
const std::string & getMessage() const
Return the error message.
static bool nbRead(int socket, std::string &s, bool *eof)
Read text from the specified socket. Returns false on error.
std::string generateHeader(std::string const &body)
static const char PARAMS_TAG[]
bool executeMulticall(const std::string &methodName, XmlRpcValue ¶ms, XmlRpcValue &result)
bool executeMethod(const std::string &methodName, XmlRpcValue ¶ms, XmlRpcValue &result)
static std::string getErrorMsg()
Returns message corresponding to last error.
static bool nbWrite(int socket, const std::string &s, int *bytesSoFar)
Write text to the specified socket. Returns false on error.
virtual ~XmlRpcServerConnection()
Destructor.
static const char METHODNAME_TAG[]
Abstract class representing a single RPC method.
static const std::string FAULTCODE
Type const & getType() const
Return the type of the value stored.
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.
static const std::string FAULTSTRING
An RPC source represents a file descriptor to monitor.
static const char PARAM_ETAG[]
A class to handle XML RPC requests.
static const std::string METHODNAME
static const char PARAMS_ETAG[]
int getCode() const
Return the error code.
void generateFaultResponse(std::string const &msg, int errorCode=-1)
std::string toXml() const
Encode the Value in xml.
void generateResponse(std::string const &resultXml)
virtual unsigned handleEvent(unsigned eventType)
XmlRpcServerConnection(int fd, XmlRpcServer *server, bool deleteOnClose=false)
Constructor.
std::string parseRequest(XmlRpcValue ¶ms)
static void log(int level, const char *fmt,...)
Dump messages somewhere.
static bool nextTagIs(const char *tag, std::string const &xml, int *offset)