1 #ifndef DISABLE_NETWORK
3 #include <lib/system/xmlrpc.h>
5 #include <lib/dvb/dvb.h>
6 #include <lib/dvb/edvb.h>
8 static std::map
<eString
, int (*)(std::vector
<eXMLRPCVariant
>&, ePtrList
<eXMLRPCVariant
>&)> rpcproc
;
10 eXMLRPCVariant::eXMLRPCVariant(const eXMLRPCVariant
&c
)
17 _struct
=new std::map
<eString
,eXMLRPCVariant
*>;
18 for (std::map
<eString
,eXMLRPCVariant
*>::iterator
b(c
._struct
->begin()); b
!= c
._struct
->end(); ++b
)
19 _struct
->insert(std::pair
<eString
,eXMLRPCVariant
*>(b
->first
, new eXMLRPCVariant(*b
->second
)));
23 _array
= new std::vector
<eXMLRPCVariant
>(*c
._array
);
31 _boolean
=new bool(*c
._boolean
);
35 _string
=new eString(*c
._string
);
39 _double
=new double(*c
._double
);
44 eXMLRPCVariant::~eXMLRPCVariant()
49 for (std::map
<eString
,eXMLRPCVariant
*>::iterator
i(_struct
->begin()); i
!= _struct
->end(); ++i
)
71 void eXMLRPCVariant::toXML(eString
&result
)
77 static eString
s1("<value><array><data>");
79 for (unsigned int i
=0; i
<getArray()->size(); i
++)
81 static eString
s(" ");
83 (*getArray())[i
].toXML(result
);
84 static eString
s1("\n");
87 static eString
s2("</data></array></value>\n");
93 static eString
s1("<value><struct>");
95 for (std::map
<eString
,eXMLRPCVariant
*>::iterator
i(_struct
->begin()); i
!= _struct
->end(); ++i
)
97 static eString
s1(" <member><name>");
100 static eString
s2("</name>");
102 i
->second
->toXML(result
);
103 static eString
s3("</member>\n");
106 static eString
s2("</struct></value>\n");
112 static eString
s1("<value><i4>");
114 result
+=eString().setNum(*getI4());
115 static eString
s2("</i4></value>");
121 static eString
s0("<value><boolean>0</boolean></value>");
122 static eString
s1("<value><boolean>1</boolean></value>");
123 result
+=(*getBoolean())?s1
:s0
;
128 static eString
s1("<value><string>");
129 static eString
s2("</string></value>");
131 result
+=*getString();
137 result
+=eString().sprintf("<value><double>%lf</double></value>", *getDouble());
142 static eXMLRPCVariant
*fromXML(XMLTreeNode
*n
)
144 if (strcmp(n
->GetType(), "value"))
147 const char *data
=n
->GetData();
150 if ((!strcmp(n
->GetType(), "i4")) || (!strcmp(n
->GetType(), "int")))
151 return new eXMLRPCVariant(new int(atoi(data
)));
152 else if (!strcmp(n
->GetType(), "boolean"))
153 return new eXMLRPCVariant(new bool(atoi(data
)));
154 else if (!strcmp(n
->GetType(), "string"))
155 return new eXMLRPCVariant(new eString(data
));
156 else if (!strcmp(n
->GetType(), "double"))
157 return new eXMLRPCVariant(new double(atof(data
)));
158 else if (!strcmp(n
->GetType(), "struct")) {
159 std::map
<eString
,eXMLRPCVariant
*> *s
=new std::map
<eString
,eXMLRPCVariant
*>;
160 for (n
=n
->GetChild(); n
; n
=n
->GetNext())
162 if (strcmp(data
, "member"))
168 eXMLRPCVariant
*value
;
169 for (XMLTreeNode
*v
=n
->GetChild(); v
; v
=v
->GetNext())
171 if (!strcmp(v
->GetType(), "name"))
172 name
=eString(v
->GetData());
173 else if (!strcmp(v
->GetType(), "value"))
176 if ((!value
) || (!name
))
181 s
->INSERT(name
,value
);
183 return new eXMLRPCVariant(s
);
184 } else if (!strcmp(n
->GetType(), "array"))
186 ePtrList
<eXMLRPCVariant
> l
;
187 l
.setAutoDelete(true);
189 if (strcmp(data
, "data"))
191 for (n
=n
->GetChild(); n
; n
=n
->GetNext())
192 if (!strcmp(n
->GetType(), "value"))
194 eXMLRPCVariant
*value
=fromXML(n
);
200 return new eXMLRPCVariant( l
.getVector() );
202 eDebug("couldn't convert %s", n
->GetType());
206 eXMLRPCResponse::eXMLRPCResponse(eHTTPConnection
*c
):
207 eHTTPDataSource(c
), parser("ISO-8859-1")
209 // size etc. setzen aber erst NACH data-phase
210 connection
->localstate
=eHTTPConnection::stateWait
;
213 eXMLRPCResponse::~eXMLRPCResponse()
217 int eXMLRPCResponse::doCall()
219 eDebug("doing call");
222 eString methodName
=0;
224 if (connection
->remote_header
["Content-Type"]!="text/xml")
226 eDebug("remote header failure (%s != text/xml)", (connection
->remote_header
["Content-Type"]).c_str());
230 XMLTreeNode
*methodCall
=parser
.RootNode();
236 if (strcmp(methodCall
->GetType(), "methodCall"))
238 eDebug("no methodCall found");
242 ePtrList
<eXMLRPCVariant
> params
;
243 params
.setAutoDelete(true);
245 for (XMLTreeNode
*c
=methodCall
->GetChild(); c
; c
=c
->GetNext())
247 if (!strcmp(c
->GetType(), "methodName"))
248 methodName
=eString(c
->GetData());
249 else if (!strcmp(c
->GetType(), "params"))
251 for (XMLTreeNode
*p
=c
->GetChild(); p
; p
=p
->GetNext())
252 if (!strcmp(p
->GetType(), "param"))
253 params
.push_back(fromXML(p
->GetChild()));
256 eDebug("unknown stuff found");
263 eDebug("no methodName found!");
267 eDebug("methodName: %s", methodName
.c_str() );
269 result
="<?xml version=\"1.0\"?>\n"
272 ePtrList
<eXMLRPCVariant
> ret
;
273 ret
.setAutoDelete(true);
275 int (*proc
)(std::vector
<eXMLRPCVariant
>&, ePtrList
<eXMLRPCVariant
> &)=rpcproc
[methodName
];
278 std::vector
<eXMLRPCVariant
>* v
= params
.getVector();
283 xmlrpc_fault(ret
, -1, "called method not present");
285 fault
=proc( *v
, ret
);
289 eDebug("converting to text...");
294 ret
.current()->toXML(result
);
295 result
+="</fault>\n";
298 result
+="<params>\n";
299 for (ePtrList
<eXMLRPCVariant
>::iterator
i(ret
); i
!= ret
.end(); ++i
)
307 result
+="</methodResponse>";
309 snprintf(buffer
, 10, "%d", size
=result
.length());
311 connection
->local_header
["Content-Type"]="text/xml";
312 connection
->local_header
["Content-Length"]=buffer
;
313 connection
->code
=200;
314 connection
->code_descr
="OK";
315 connection
->localstate
=eHTTPConnection::stateResponse
;
319 int eXMLRPCResponse::doWrite(int hm
)
326 connection
->writeBlock(result
.c_str()+wptr
, tw
);
328 return size
> wptr
? 1 : -1;
331 void eXMLRPCResponse::haveData(void *data
, int len
)
337 if (!parser
.Parse((char*)data
, len
, !len
))
341 memcpy(temp
, data
, len
);
342 eDebug("%s: %s", temp
, parser
.ErrorString(parser
.GetErrorCode()));
346 if ((!err
) && (!len
))
351 eDebug("schade: %d", err
);
352 connection
->code
=400;
353 connection
->code_descr
="Bad request";
355 snprintf(buffer
, 10, "%d", size
=result
.length());
357 connection
->local_header
["Content-Type"]="text/html";
358 connection
->local_header
["Content-Length"]=buffer
;
359 result
.sprintf("XMLRPC error %d\n", err
);
360 connection
->localstate
=eHTTPConnection::stateResponse
;
364 void xmlrpc_addMethod(eString methodName
, int (*proc
)(std::vector
<eXMLRPCVariant
>&, ePtrList
<eXMLRPCVariant
>&))
366 rpcproc
[methodName
]=proc
;
369 void xmlrpc_fault(ePtrList
<eXMLRPCVariant
> &res
, int faultCode
, eString faultString
)
371 std::map
<eString
,eXMLRPCVariant
*> *s
=new std::map
<eString
,eXMLRPCVariant
*>;
372 s
->INSERT("faultCode", new eXMLRPCVariant(new __s32(faultCode
)));
373 s
->INSERT("faultString", new eXMLRPCVariant(new eString(faultString
)));
374 res
.push_back(new eXMLRPCVariant(s
));
377 int xmlrpc_checkArgs(eString args
, std::vector
<eXMLRPCVariant
> &parm
, ePtrList
<eXMLRPCVariant
> &res
)
379 if (parm
.size() != args
.length())
381 xmlrpc_fault(res
, -500, eString().sprintf("parameter count mismatch (found %d, expected %d)", parm
.size(), args
.length()));
385 for (unsigned int i
=0; i
<args
.length(); i
++)
394 if (parm
[i
].getBoolean())
398 if (parm
[i
].getString())
402 if (parm
[i
].getDouble())
406 if (parm[i].getDatetime())
410 if (parm[i].getBase64())
414 if (parm
[i
].getStruct())
418 if (parm
[i
].getArray())
422 xmlrpc_fault(res
, -501, eString().sprintf("parameter type mismatch, expected %c as #%d", args
[i
], i
));
428 eHTTPXMLRPCResolver::eHTTPXMLRPCResolver()
432 eHTTPDataSource
*eHTTPXMLRPCResolver::getDataSource(eString request
, eString path
, eHTTPConnection
*conn
)
434 if ((path
=="/RPC2") && (request
=="POST"))
435 return new eXMLRPCResponse(conn
);
436 if ((path
=="/SID2") && (request
=="POST"))
437 return new eXMLRPCResponse(conn
);
441 #endif //DISABLE_NETWORK