1 #ifndef DISABLE_NETWORK
3 #include <lib/network/xmlrpc.h>
6 static std::map<eString, int (*)(std::vector<eXMLRPCVariant>&, ePtrList<eXMLRPCVariant>&)> rpcproc;
8 void eXMLRPCVariant::zero()
20 eXMLRPCVariant::eXMLRPCVariant(std::map<eString,eXMLRPCVariant*> *__struct)
26 eXMLRPCVariant::eXMLRPCVariant(std::vector<eXMLRPCVariant> *__array)
32 eXMLRPCVariant::eXMLRPCVariant(__s32 *__i4)
38 eXMLRPCVariant::eXMLRPCVariant(bool *__boolean)
44 eXMLRPCVariant::eXMLRPCVariant(eString *__string)
50 eXMLRPCVariant::eXMLRPCVariant(double *__double)
56 /*eXMLRPCVariant::eXMLRPCVariant(QDateTime *__datetime)
62 /*eXMLRPCVariant::eXMLRPCVariant(QByteArray *__base64)
68 eXMLRPCVariant::eXMLRPCVariant(const eXMLRPCVariant &c)
74 _boolean=new bool(*c._boolean);
76 _string=new eString(*c._string);
78 _double=new double(*c._double);
82 _struct=new std::map<eString,eXMLRPCVariant*>;
83 for (std::map<eString,eXMLRPCVariant*>::iterator b(c._struct->begin()); b != c._struct->end(); ++b)
84 _struct->insert(std::pair<eString,eXMLRPCVariant*>(b->first, new eXMLRPCVariant(*b->second)));
87 _array = new std::vector<eXMLRPCVariant>(*c._array);
90 eXMLRPCVariant::~eXMLRPCVariant()
94 for (std::map<eString,eXMLRPCVariant*>::iterator i(_struct->begin()); i != _struct->end(); ++i)
115 std::map<eString,eXMLRPCVariant*> *eXMLRPCVariant::getStruct()
120 std::vector<eXMLRPCVariant> *eXMLRPCVariant::getArray()
125 __s32 *eXMLRPCVariant::getI4()
130 bool *eXMLRPCVariant::getBoolean()
135 eString *eXMLRPCVariant::getString()
140 double *eXMLRPCVariant::getDouble()
145 /*QDateTime *eXMLRPCVariant::getDatetime()
150 /*QByteArray *eXMLRPCVariant::getBase64()
155 void eXMLRPCVariant::toXML(eString &result)
159 static eString s1("<value><array><data>");
161 for (unsigned int i=0; i<getArray()->size(); i++)
163 static eString s(" ");
165 (*getArray())[i].toXML(result);
166 static eString s1("\n");
169 static eString s2("</data></array></value>\n");
171 } else if (getStruct())
173 static eString s1("<value><struct>");
175 for (std::map<eString,eXMLRPCVariant*>::iterator i(_struct->begin()); i != _struct->end(); ++i)
177 static eString s1(" <member><name>");
180 static eString s2("</name>");
182 i->second->toXML(result);
183 static eString s3("</member>\n");
186 static eString s2("</struct></value>\n");
190 static eString s1("<value><i4>");
192 result+=eString().setNum(*getI4());
193 static eString s2("</i4></value>");
195 } else if (getBoolean())
197 static eString s0("<value><boolean>0</boolean></value>");
198 static eString s1("<value><boolean>1</boolean></value>");
199 result+=(*getBoolean())?s1:s0;
200 } else if (getString())
202 static eString s1("<value><string>");
203 static eString s2("</string></value>");
205 result+=*getString();
207 } else if (getDouble())
209 result+=eString().sprintf("<value><double>%lf</double></value>", *getDouble());
211 eFatal("couldn't append");
214 static eXMLRPCVariant *fromXML(XMLTreeNode *n)
216 if (strcmp(n->GetType(), "value"))
219 const char *data=n->GetData();
222 if ((!strcmp(n->GetType(), "i4")) || (!strcmp(n->GetType(), "int")))
223 return new eXMLRPCVariant(new int(atoi(data)));
224 else if (!strcmp(n->GetType(), "boolean"))
225 return new eXMLRPCVariant(new bool(atoi(data)));
226 else if (!strcmp(n->GetType(), "string"))
227 return new eXMLRPCVariant(new eString(data));
228 else if (!strcmp(n->GetType(), "double"))
229 return new eXMLRPCVariant(new double(atof(data)));
230 else if (!strcmp(n->GetType(), "struct")) {
231 std::map<eString,eXMLRPCVariant*> *s=new std::map<eString,eXMLRPCVariant*>;
232 for (n=n->GetChild(); n; n=n->GetNext())
234 if (strcmp(data, "member"))
240 eXMLRPCVariant *value;
241 for (XMLTreeNode *v=n->GetChild(); v; v=v->GetNext())
243 if (!strcmp(v->GetType(), "name"))
244 name=eString(v->GetData());
245 else if (!strcmp(v->GetType(), "value"))
248 if ((!value) || (!name))
253 s->INSERT(name,value);
255 return new eXMLRPCVariant(s);
256 } else if (!strcmp(n->GetType(), "array"))
258 ePtrList<eXMLRPCVariant> l;
259 #warning autodelete removed
260 // l.setAutoDelete(true);
262 if (strcmp(data, "data"))
264 for (n=n->GetChild(); n; n=n->GetNext())
265 if (!strcmp(n->GetType(), "value"))
267 eXMLRPCVariant *value=fromXML(n);
273 return new eXMLRPCVariant( l.getVector() );
275 eDebug("couldn't convert %s", n->GetType());
279 eXMLRPCResponse::eXMLRPCResponse(eHTTPConnection *c):
280 eHTTPDataSource(c), parser("ISO-8859-1")
282 // size etc. setzen aber erst NACH data-phase
283 connection->localstate=eHTTPConnection::stateWait;
286 eXMLRPCResponse::~eXMLRPCResponse()
290 int eXMLRPCResponse::doCall()
292 eDebug("doing call");
295 eString methodName=0;
297 if (connection->remote_header["Content-Type"]!="text/xml")
299 eDebug("remote header failure (%s != text/xml)", (connection->remote_header["Content-Type"]).c_str());
303 XMLTreeNode *methodCall=parser.RootNode();
309 if (strcmp(methodCall->GetType(), "methodCall"))
311 eDebug("no methodCall found");
315 ePtrList<eXMLRPCVariant> params;
316 // params.setAutoDelete(true);
317 #warning params autodelete remove
319 for (XMLTreeNode *c=methodCall->GetChild(); c; c=c->GetNext())
321 if (!strcmp(c->GetType(), "methodName"))
322 methodName=eString(c->GetData());
323 else if (!strcmp(c->GetType(), "params"))
325 for (XMLTreeNode *p=c->GetChild(); p; p=p->GetNext())
326 if (!strcmp(p->GetType(), "param"))
327 params.push_back(fromXML(p->GetChild()));
330 eDebug("unknown stuff found");
337 eDebug("no methodName found!");
341 eDebug("methodName: %s", methodName.c_str() );
343 result="<?xml version=\"1.0\"?>\n"
346 ePtrList<eXMLRPCVariant> ret;
347 // ret.setAutoDelete(true);
348 #warning autodelete removed
350 int (*proc)(std::vector<eXMLRPCVariant>&, ePtrList<eXMLRPCVariant> &)=rpcproc[methodName];
353 std::vector<eXMLRPCVariant>* v = params.getVector();
358 xmlrpc_fault(ret, -1, "called method not present");
360 fault=proc( *v , ret);
364 eDebug("converting to text...");
369 ret.current()->toXML(result);
370 result+="</fault>\n";
373 result+="<params>\n";
374 for (ePtrList<eXMLRPCVariant>::iterator i(ret); i != ret.end(); ++i)
382 result+="</methodResponse>";
384 snprintf(buffer, 10, "%d", size=result.length());
386 connection->local_header["Content-Type"]="text/xml";
387 connection->local_header["Content-Length"]=buffer;
388 connection->code=200;
389 connection->code_descr="OK";
390 connection->localstate=eHTTPConnection::stateResponse;
394 int eXMLRPCResponse::doWrite(int hm)
401 connection->writeBlock(result.c_str()+wptr, tw);
403 return size > wptr ? 1 : -1;
406 void eXMLRPCResponse::haveData(void *data, int len)
412 if (!parser.Parse((char*)data, len, !len))
416 memcpy(temp, data, len);
417 eDebug("%s: %s", temp, parser.ErrorString(parser.GetErrorCode()));
421 if ((!err) && (!len))
426 eDebug("schade: %d", err);
427 connection->code=400;
428 connection->code_descr="Bad request";
430 snprintf(buffer, 10, "%d", size=result.length());
432 connection->local_header["Content-Type"]="text/html";
433 connection->local_header["Content-Length"]=buffer;
434 result.sprintf("XMLRPC error %d\n", err);
435 connection->localstate=eHTTPConnection::stateResponse;
439 void xmlrpc_initialize(eHTTPD *httpd)
441 httpd->addResolver(new eHTTPXMLRPCResolver);
444 void xmlrpc_addMethod(eString methodName, int (*proc)(std::vector<eXMLRPCVariant>&, ePtrList<eXMLRPCVariant>&))
446 rpcproc[methodName]=proc;
449 void xmlrpc_fault(ePtrList<eXMLRPCVariant> &res, int faultCode, eString faultString)
451 std::map<eString,eXMLRPCVariant*> *s=new std::map<eString,eXMLRPCVariant*>;
452 s->INSERT("faultCode", new eXMLRPCVariant(new __s32(faultCode)));
453 s->INSERT("faultString", new eXMLRPCVariant(new eString(faultString)));
454 res.push_back(new eXMLRPCVariant(s));
457 int xmlrpc_checkArgs(eString args, std::vector<eXMLRPCVariant> &parm, ePtrList<eXMLRPCVariant> &res)
459 if (parm.size() != args.length())
461 xmlrpc_fault(res, -500, eString().sprintf("parameter count mismatch (found %d, expected %d)", parm.size(), args.length()));
465 for (unsigned int i=0; i<args.length(); i++)
474 if (parm[i].getBoolean())
478 if (parm[i].getString())
482 if (parm[i].getDouble())
486 if (parm[i].getDatetime())
490 if (parm[i].getBase64())
494 if (parm[i].getStruct())
498 if (parm[i].getArray())
502 xmlrpc_fault(res, -501, eString().sprintf("parameter type mismatch, expected %c as #%d", args[i], i));
508 eHTTPXMLRPCResolver::eHTTPXMLRPCResolver()
512 eHTTPDataSource *eHTTPXMLRPCResolver::getDataSource(eString request, eString path, eHTTPConnection *conn)
514 if ((path=="/RPC2") && (request=="POST"))
515 return new eXMLRPCResponse(conn);
516 if ((path=="/SID2") && (request=="POST"))
517 return new eXMLRPCResponse(conn);
521 #endif //DISABLE_NETWORK