86 char *hp = (
char*)
_header.c_str();
87 char *ep = hp +
_header.length();
92 for (
char *cp = hp; (bp == 0) && (cp < ep); ++cp) {
93 if ((ep - cp > 16) && (strncasecmp(cp,
"Content-length: ", 16) == 0))
95 else if ((ep - cp > 12) && (strncasecmp(cp,
"Connection: ", 12) == 0))
97 else if ((ep - cp > 4) && (strncmp(cp,
"\r\n\r\n", 4) == 0))
99 else if ((ep - cp > 2) && (strncmp(cp,
"\n\n", 2) == 0))
109 XmlRpcUtil::error(
"XmlRpcServerConnection::readHeader: EOF while reading header");
118 XmlRpcUtil::error(
"XmlRpcServerConnection::readHeader: No Content-length specified");
123 long int clength = 0;
124 clength = strtol(lp, NULL, 10);
125 if ((clength < 0) || (clength > __INT_MAX__)) {
126 XmlRpcUtil::error(
"XmlRpcServerConnection::readHeader: Invalid Content-length specified.");
138 if (
_header.find(
"HTTP/1.0") != std::string::npos) {
139 if (kp == 0 || strncasecmp(kp,
"keep-alive", 10) != 0)
142 if (kp != 0 && strncasecmp(kp,
"close", 5) == 0)
164 if (
_request.length() > size_t(__INT_MAX__)) {
165 XmlRpcUtil::error(
"XmlRpcServerConnection::readRequest: request length (%u) exceeds the maximum allowed size (%u)",
174 XmlRpcUtil::error(
"XmlRpcServerConnection::readRequest: EOF while reading request");
227 XmlRpcUtil::log(2,
"XmlRpcServerConnection::executeRequest: server calling method '%s'",
239 XmlRpcUtil::log(2,
"XmlRpcServerConnection::executeRequest: fault %s.",
274 if ( ! method)
return false;
276 method->
execute(params, result);
279 if ( ! result.
valid())
280 result = std::string();
296 int nc = params[0].
size();
299 for (
int i=0; i<nc; ++i) {
302 ! params[0][i].hasMember(
PARAMS)) {
305 ": Invalid argument (expected a struct with members methodName and params)";
309 const std::string& methodName = params[0][i][
METHODNAME];
315 if ( !
executeMethod(methodName, methodParams, resultValue[0]) &&
319 result[i][
FAULTSTRING] = methodName +
": unknown method name";
322 result[i] = resultValue;
338 const char RESPONSE_1[] =
339 "<?xml version=\"1.0\"?>\r\n" 340 "<methodResponse><params><param>\r\n\t";
341 const char RESPONSE_2[] =
342 "\r\n</param></params></methodResponse>\r\n";
344 std::string body = RESPONSE_1 + resultXml + RESPONSE_2;
348 if ((header.length() + body.length()) >
size_t(__INT_MAX__)) {
349 XmlRpcUtil::error(
"XmlRpcServerConnection::generateResponse: response length (%u) exceeds the maximum allowed size (%u).",
364 "HTTP/1.1 200 OK\r\n" 368 "Content-Type: text/xml\r\n" 373 sprintf_s(buffLen,40,
"%d\r\n\r\n", (
int)body.size());
375 sprintf(buffLen,
"%d\r\n\r\n", (
int)body.size());
378 return header + buffLen;
385 const char RESPONSE_1[] =
386 "<?xml version=\"1.0\"?>\r\n" 387 "<methodResponse><fault>\r\n\t";
388 const char RESPONSE_2[] =
389 "\r\n</fault></methodResponse>\r\n";
394 std::string body = RESPONSE_1 + faultStruct.
toXml() + RESPONSE_2;
const std::string & getMessage() const
Return the error message.
virtual void execute(XmlRpcValue ¶ms, XmlRpcValue &result)=0
Execute the method. Subclasses must provide a definition for this method.
virtual void executeRequest()
RPC method arguments and results are represented by Values.
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
int size() const
Return the size for string, base64, array, and struct values.
static std::string parseTag(const char *tag, std::string const &xml, int *offset)
Returns contents between <tag> and </tag>, updates offset to char after </tag>
XmlRpcServerMethod * findMethod(const std::string &name) const
Look up a method by name.
bool valid() const
Return true if the value has been set to something.
static const char PARAM_TAG[]
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.
int getCode() const
Return the error code.
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)
Type const & getType() const
Return the type of the value stored.
bool executeMethod(const std::string &methodName, XmlRpcValue ¶ms, XmlRpcValue &result)
static std::string getErrorMsg()
Returns message corresponding to last error.
int getfd() const
Return the file descriptor being monitored.
virtual ~XmlRpcServerConnection()
Destructor.
static const char METHODNAME_TAG[]
Abstract class representing a single RPC method.
static const std::string FAULTCODE
std::string toXml() const
Encode the Value in xml.
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[]
void generateFaultResponse(std::string const &msg, int errorCode=-1)
static bool nbWrite(int socket, std::string &s, int *bytesSoFar)
Write text to the specified socket. Returns false on error.
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)