1 #ifndef DISABLE_NETWORK
3 #include <lib/network/xmlrpc.h>
4 #include <lib/base/estring.h>
7 static std::map<std::string, int (*)(std::vector<eXMLRPCVariant>&, ePtrList<eXMLRPCVariant>&)> rpcproc;
9 void eXMLRPCVariant::zero()
21 eXMLRPCVariant::eXMLRPCVariant(std::map<std::string,eXMLRPCVariant*> *__struct)
27 eXMLRPCVariant::eXMLRPCVariant(std::vector<eXMLRPCVariant> *__array)
33 eXMLRPCVariant::eXMLRPCVariant(__s32 *__i4)
39 eXMLRPCVariant::eXMLRPCVariant(bool *__boolean)
45 eXMLRPCVariant::eXMLRPCVariant(std::string *__string)
51 eXMLRPCVariant::eXMLRPCVariant(double *__double)
57 /*eXMLRPCVariant::eXMLRPCVariant(QDateTime *__datetime)
63 /*eXMLRPCVariant::eXMLRPCVariant(QByteArray *__base64)
69 eXMLRPCVariant::eXMLRPCVariant(const eXMLRPCVariant &c)
75 _boolean=new bool(*c._boolean);
77 _string=new std::string(*c._string);
79 _double=new double(*c._double);
83 _struct=new std::map<std::string,eXMLRPCVariant*>;
84 for (std::map<std::string,eXMLRPCVariant*>::iterator b(c._struct->begin()); b != c._struct->end(); ++b)
85 _struct->insert(std::pair<std::string,eXMLRPCVariant*>(b->first, new eXMLRPCVariant(*b->second)));
88 _array = new std::vector<eXMLRPCVariant>(*c._array);
91 eXMLRPCVariant::~eXMLRPCVariant()
95 for (std::map<std::string,eXMLRPCVariant*>::iterator i(_struct->begin()); i != _struct->end(); ++i)
116 std::map<std::string,eXMLRPCVariant*> *eXMLRPCVariant::getStruct()
121 std::vector<eXMLRPCVariant> *eXMLRPCVariant::getArray()
126 __s32 *eXMLRPCVariant::getI4()
131 bool *eXMLRPCVariant::getBoolean()
136 std::string *eXMLRPCVariant::getString()
141 double *eXMLRPCVariant::getDouble()
146 /*QDateTime *eXMLRPCVariant::getDatetime()
151 /*QByteArray *eXMLRPCVariant::getBase64()
156 void eXMLRPCVariant::toXML(std::string &result)
160 static std::string s1("<value><array><data>");
162 for (unsigned int i=0; i<getArray()->size(); i++)
164 static std::string s(" ");
166 (*getArray())[i].toXML(result);
167 static std::string s1("\n");
170 static std::string s2("</data></array></value>\n");
172 } else if (getStruct())
174 static std::string s1("<value><struct>");
176 for (std::map<std::string,eXMLRPCVariant*>::iterator i(_struct->begin()); i != _struct->end(); ++i)
178 static std::string s1(" <member><name>");
181 static std::string s2("</name>");
183 i->second->toXML(result);
184 static std::string s3("</member>\n");
187 static std::string s2("</struct></value>\n");
191 static std::string s1("<value><i4>");
193 result+=getNum(*getI4());
194 static std::string s2("</i4></value>");
196 } else if (getBoolean())
198 static std::string s0("<value><boolean>0</boolean></value>");
199 static std::string s1("<value><boolean>1</boolean></value>");
200 result+=(*getBoolean())?s1:s0;
201 } else if (getString())
203 static std::string s1("<value><string>");
204 static std::string s2("</string></value>");
206 result+=*getString();
208 } else if (getDouble())
210 // result+=std::string().sprintf("<value><double>%lf</double></value>", *getDouble());
211 #warning double support removed
213 eFatal("couldn't append");
216 static eXMLRPCVariant *fromXML(XMLTreeNode *n)
218 if (strcmp(n->GetType(), "value"))
221 const char *data=n->GetData();
224 if ((!strcmp(n->GetType(), "i4")) || (!strcmp(n->GetType(), "int")))
225 return new eXMLRPCVariant(new int(atoi(data)));
226 else if (!strcmp(n->GetType(), "boolean"))
227 return new eXMLRPCVariant(new bool(atoi(data)));
228 else if (!strcmp(n->GetType(), "string"))
229 return new eXMLRPCVariant(new std::string(data));
230 else if (!strcmp(n->GetType(), "double"))
231 return new eXMLRPCVariant(new double(atof(data)));
232 else if (!strcmp(n->GetType(), "struct")) {
233 std::map<std::string,eXMLRPCVariant*> *s=new std::map<std::string,eXMLRPCVariant*>;
234 for (n=n->GetChild(); n; n=n->GetNext())
236 if (strcmp(data, "member"))
242 eXMLRPCVariant *value;
243 for (XMLTreeNode *v=n->GetChild(); v; v=v->GetNext())
245 if (!strcmp(v->GetType(), "name"))
246 name=std::string(v->GetData());
247 else if (!strcmp(v->GetType(), "value"))
250 if ((!value) || (!name))
255 s->INSERT(name,value);
257 return new eXMLRPCVariant(s);
258 } else if (!strcmp(n->GetType(), "array"))
260 ePtrList<eXMLRPCVariant> l;
261 #warning autodelete removed
262 // l.setAutoDelete(true);
264 if (strcmp(data, "data"))
266 for (n=n->GetChild(); n; n=n->GetNext())
267 if (!strcmp(n->GetType(), "value"))
269 eXMLRPCVariant *value=fromXML(n);
275 return new eXMLRPCVariant( l.getVector() );
277 eDebug("couldn't convert %s", n->GetType());
281 eXMLRPCResponse::eXMLRPCResponse(eHTTPConnection *c):
282 eHTTPDataSource(c), parser("ISO-8859-1")
284 // size etc. setzen aber erst NACH data-phase
285 connection->localstate=eHTTPConnection::stateWait;
288 eXMLRPCResponse::~eXMLRPCResponse()
292 int eXMLRPCResponse::doCall()
294 eDebug("doing call");
297 std::string methodName=0;
299 if (connection->remote_header["Content-Type"]!="text/xml")
301 eDebug("remote header failure (%s != text/xml)", (connection->remote_header["Content-Type"]).c_str());
305 XMLTreeNode *methodCall=parser.RootNode();
311 if (strcmp(methodCall->GetType(), "methodCall"))
313 eDebug("no methodCall found");
317 ePtrList<eXMLRPCVariant> params;
318 // params.setAutoDelete(true);
319 #warning params autodelete remove
321 for (XMLTreeNode *c=methodCall->GetChild(); c; c=c->GetNext())
323 if (!strcmp(c->GetType(), "methodName"))
324 methodName=std::string(c->GetData());
325 else if (!strcmp(c->GetType(), "params"))
327 for (XMLTreeNode *p=c->GetChild(); p; p=p->GetNext())
328 if (!strcmp(p->GetType(), "param"))
329 params.push_back(fromXML(p->GetChild()));
332 eDebug("unknown stuff found");
339 eDebug("no methodName found!");
343 eDebug("methodName: %s", methodName.c_str() );
345 result="<?xml version=\"1.0\"?>\n"
348 ePtrList<eXMLRPCVariant> ret;
349 // ret.setAutoDelete(true);
350 #warning autodelete removed
352 int (*proc)(std::vector<eXMLRPCVariant>&, ePtrList<eXMLRPCVariant> &)=rpcproc[methodName];
355 std::vector<eXMLRPCVariant>* v = params.getVector();
360 xmlrpc_fault(ret, -1, "called method not present");
362 fault=proc( *v , ret);
366 eDebug("converting to text...");
371 ret.current()->toXML(result);
372 result+="</fault>\n";
375 result+="<params>\n";
376 for (ePtrList<eXMLRPCVariant>::iterator i(ret); i != ret.end(); ++i)
384 result+="</methodResponse>";
386 snprintf(buffer, 10, "%d", size=result.length());
388 connection->local_header["Content-Type"]="text/xml";
389 connection->local_header["Content-Length"]=buffer;
390 connection->code=200;
391 connection->code_descr="OK";
392 connection->localstate=eHTTPConnection::stateResponse;
396 int eXMLRPCResponse::doWrite(int hm)
403 connection->writeBlock(result.c_str()+wptr, tw);
405 return size > wptr ? 1 : -1;
408 void eXMLRPCResponse::haveData(void *data, int len)
414 if (!parser.Parse((char*)data, len, !len))
418 memcpy(temp, data, len);
419 eDebug("%s: %s", temp, parser.ErrorString(parser.GetErrorCode()));
423 if ((!err) && (!len))
428 eDebug("schade: %d", err);
429 connection->code=400;
430 connection->code_descr="Bad request";
432 snprintf(buffer, 10, "%d", size=result.length());
434 connection->local_header["Content-Type"]="text/html";
435 connection->local_header["Content-Length"]=buffer;
436 result.sprintf("XMLRPC error %d\n", err);
437 connection->localstate=eHTTPConnection::stateResponse;
441 void xmlrpc_initialize(eHTTPD *httpd)
443 httpd->addResolver(new eHTTPXMLRPCResolver);
446 void xmlrpc_addMethod(std::string methodName, int (*proc)(std::vector<eXMLRPCVariant>&, ePtrList<eXMLRPCVariant>&))
448 rpcproc[methodName]=proc;
451 void xmlrpc_fault(ePtrList<eXMLRPCVariant> &res, int faultCode, std::string faultString)
453 std::map<std::string,eXMLRPCVariant*> *s=new std::map<std::string,eXMLRPCVariant*>;
454 s->INSERT("faultCode", new eXMLRPCVariant(new __s32(faultCode)));
455 s->INSERT("faultString", new eXMLRPCVariant(new std::string(faultString)));
456 res.push_back(new eXMLRPCVariant(s));
459 int xmlrpc_checkArgs(std::string args, std::vector<eXMLRPCVariant> &parm, ePtrList<eXMLRPCVariant> &res)
461 if (parm.size() != args.length())
463 xmlrpc_fault(res, -500, std::string().sprintf("parameter count mismatch (found %d, expected %d)", parm.size(), args.length()));
467 for (unsigned int i=0; i<args.length(); i++)
476 if (parm[i].getBoolean())
480 if (parm[i].getString())
484 if (parm[i].getDouble())
488 if (parm[i].getDatetime())
492 if (parm[i].getBase64())
496 if (parm[i].getStruct())
500 if (parm[i].getArray())
504 xmlrpc_fault(res, -501, std::string().sprintf("parameter type mismatch, expected %c as #%d", args[i], i));
510 eHTTPXMLRPCResolver::eHTTPXMLRPCResolver()
514 eHTTPDataSource *eHTTPXMLRPCResolver::getDataSource(std::string request, std::string path, eHTTPConnection *conn)
516 if ((path=="/RPC2") && (request=="POST"))
517 return new eXMLRPCResponse(conn);
518 if ((path=="/SID2") && (request=="POST"))
519 return new eXMLRPCResponse(conn);
523 #endif //DISABLE_NETWORK