#include "XmlRpc.h" #define LLOG(x) // LOG(x) namespace Upp { static bool sLogRpcCalls; void LogXmlRpcCalls(bool b) { sLogRpcCalls = b; } XmlRpcCall& XmlRpcCall::URL(const char *url) { shorted = true; if(url && *url) { server.URL(url); shorted = false; } shouldExecute = true; return *this; } XmlRpcCall& XmlRpcCall::Method(const char *name) { shouldExecute = true; method = name; data.Reset(); error.Clear(); return *this; } XmlRpcCall::XmlRpcCall(const char *url) { URL(url); server.ContentType("text/xml"); timeout = 30000; } XmlRpcCall::XmlRpcCall() { URL(NULL); server.ContentType("text/xml"); timeout = 30000; } String XmlRpcExecute(const String& request, const char *group, const char *peeraddr); Value XmlRpcCall::Retry() { ClearError(); shouldExecute = true; return Execute(); } Value XmlRpcCall::Execute() { if(!shouldExecute) return Value(); shouldExecute = false; String request = XmlHeader(); request << XmlTag("methodCall")(XmlTag("methodName")(method) + FormatXmlRpcParams(data.out)); if(sLogRpcCalls) RLOG("XmlRpc call request:\n" << request); String response; if(shorted) response = XmlRpcExecute(request, "", "127.0.0.1"); else response = server.Post(request).TimeoutMsecs(timeout).ExecuteRedirect(); if(sLogRpcCalls) RLOG("XmlRpc call response:\n" << response); if(IsNull(response)) { faultCode = XMLRPC_CLIENT_HTTP_ERROR; faultString = server.GetError(); error = "Http request failed: " + faultString; LLOG(error); return ErrorValue(error); } XmlParser p(response); try { p.ReadPI(); p.PassTag("methodResponse"); if(p.Tag("fault")) { Value m = ParseXmlRpcValue(p); if(IsValueMap(m)) { ValueMap mm = m; faultString = mm["faultString"]; faultCode = mm["faultCode"]; error.Clear(); error << "Failed '" << faultString << "' (" << faultCode << ')'; LLOG(s); return ErrorValue(error); } } else { data.in = ParseXmlRpcParams(p); data.ii = 0; p.PassEnd(); } } catch(XmlError e) { String s; faultString = e; faultCode = XMLRPC_CLIENT_XML_ERROR; error.Clear(); error << "XML Error: " << faultString; LLOG(error << ": " << p.GetPtr()); return ErrorValue(error); } return data.in.GetCount() ? data.in[0] : Null; } void XmlRpcCall::ClearError() { faultCode = 0; faultString.Clear(); error.Clear(); } }