3
static void _xr_value_serialize_xmlrpc(xmlNode* node, xr_value* val)
9
if (xr_value_get_type(val) != XRV_MEMBER)
10
node = xmlNewChild(node, NULL, BAD_CAST "value", NULL);
12
switch (xr_value_get_type(val))
16
value = xmlNewChild(node, NULL, BAD_CAST "array", NULL);
17
value = xmlNewChild(value, NULL, BAD_CAST "data", NULL);
18
for (i = xr_value_get_items(val); i; i = i->next)
19
_xr_value_serialize_xmlrpc(value, i->data);
24
value = xmlNewChild(node, NULL, BAD_CAST "struct", NULL);
25
for (i = xr_value_get_members(val); i; i = i->next)
26
_xr_value_serialize_xmlrpc(value, i->data);
31
value = xmlNewChild(node, NULL, BAD_CAST "member", NULL);
32
xmlNewChild(value, NULL, BAD_CAST "name", BAD_CAST xr_value_get_member_name(val));
33
_xr_value_serialize_xmlrpc(value, xr_value_get_member_value(val));
39
xr_value_to_int(val, &int_val);
40
snprintf(buf, sizeof(buf), "%d", int_val);
41
xmlNewChild(node, NULL, BAD_CAST "int", BAD_CAST buf);
47
xr_value_to_string(val, &str_val);
48
xmlAddChild(node, xmlNewText(BAD_CAST str_val));
55
xr_value_to_bool(val, &bool_val);
56
xmlNewChild(node, NULL, BAD_CAST "boolean", BAD_CAST (bool_val ? "1" : "0"));
62
xr_value_to_double(val, &dbl_val);
63
snprintf(buf, sizeof(buf), "%g", dbl_val);
64
xmlNewChild(node, NULL, BAD_CAST "double", BAD_CAST buf);
70
xr_value_to_time(val, &str_val);
71
xmlNewChild(node, NULL, BAD_CAST "dateTime.iso8601", BAD_CAST str_val);
79
xr_value_to_blob(val, &b);
80
data = g_base64_encode(b->buf, b->len);
82
xmlNewChild(node, NULL, BAD_CAST "base64", BAD_CAST data);
89
static xr_value* _xr_value_unserialize_xmlrpc(xmlNode* node)
91
gboolean is_string_without_element = TRUE;
92
for_each_node(node, tn)
93
/* check if node contains only text and entity reference nodes */
94
if (tn->type != XML_TEXT_NODE && tn->type != XML_ENTITY_REF_NODE)
95
is_string_without_element = FALSE;
97
if (match_node(tn, "int") || match_node(tn, "i4"))
98
return xr_value_int_new(xml_get_cont_int(tn));
99
else if (match_node(tn, "string"))
101
char* str = xml_get_cont_str(tn);
102
xr_value* val = xr_value_string_new(str);
106
else if (match_node(tn, "boolean"))
107
return xr_value_bool_new(xml_get_cont_bool(tn));
108
else if (match_node(tn, "double"))
109
return xr_value_double_new(xml_get_cont_double(tn));
110
else if (match_node(tn, "dateTime.iso8601"))
112
char* str = xml_get_cont_str(tn);
113
xr_value* val = xr_value_time_new(str);
117
else if (match_node(tn, "base64"))
121
char* base64 = xml_get_cont_str(tn);
123
char* buf = g_base64_decode(base64, &len);
125
b = xr_blob_new(buf, len);
126
bv = xr_value_blob_new(b);
130
else if (match_node(tn, "array"))
132
xr_value* arr = xr_value_array_new();
134
if (match_node(d, "data"))
137
if (match_node(v, "value"))
139
xr_value* elem = _xr_value_unserialize_xmlrpc(v);
145
xr_value_array_append(arr, elem);
153
else if (match_node(tn, "struct"))
155
xr_value* str = xr_value_struct_new();
157
if (match_node(m, "member"))
160
xr_value* val = NULL;
161
int names = 0, values = 0;
164
if (match_node(me, "name"))
167
name = xml_get_cont_str(me);
169
else if (match_node(me, "value"))
172
val = _xr_value_unserialize_xmlrpc(me);
176
if (values != 1 || names != 1)
183
xr_value_struct_set_member(str, name, val);
191
if (is_string_without_element)
193
xmlChar* str = xmlNodeGetContent(node);
194
xr_value* val = xr_value_string_new(str);
202
static void xr_call_serialize_request_xmlrpc(xr_call* call, char** buf, int* len)
204
xmlDoc* doc = xmlNewDoc(BAD_CAST "1.0");
205
xmlNode* root = xmlNewNode(NULL, BAD_CAST "methodCall");
206
xmlDocSetRootElement(doc, root);
207
xmlNewChild(root, NULL, BAD_CAST "methodName", call->method);
208
xmlNode* params = xmlNewChild(root, NULL, BAD_CAST "params", NULL);
211
for (i = call->params; i; i = i->next)
213
xmlNode* param = xmlNewChild(params, NULL, BAD_CAST "param", NULL);
214
_xr_value_serialize_xmlrpc(param, i->data);
217
if (xr_debug_enabled & XR_DEBUG_HTTP)
218
xmlDocDumpFormatMemoryEnc(doc, (xmlChar**)buf, len, "UTF-8", 1);
220
xmlDocDumpMemoryEnc(doc, (xmlChar**)buf, len, "UTF-8");
225
static void xr_call_serialize_response_xmlrpc(xr_call* call, char** buf, int* len)
227
xmlDoc* doc = xmlNewDoc(BAD_CAST "1.0");
228
xmlNode* root = xmlNewNode(NULL, BAD_CAST "methodResponse");
229
xmlDocSetRootElement(doc, root);
233
xmlNode* fault = xmlNewChild(root, NULL, BAD_CAST "fault", NULL);
234
xr_value* v = xr_value_struct_new();
235
xr_value_struct_set_member(v, "faultCode", xr_value_int_new(call->errcode));
236
xr_value_struct_set_member(v, "faultString", xr_value_string_new(call->errmsg));
237
_xr_value_serialize_xmlrpc(fault, v);
240
else if (call->retval)
242
xmlNode* params = xmlNewChild(root, NULL, BAD_CAST "params", NULL);
243
xmlNode* param = xmlNewChild(params, NULL, BAD_CAST "param", NULL);
244
_xr_value_serialize_xmlrpc(param, call->retval);
247
if (xr_debug_enabled & XR_DEBUG_HTTP)
248
xmlDocDumpFormatMemoryEnc(doc, (xmlChar**)buf, len, "UTF-8", 1);
250
xmlDocDumpMemoryEnc(doc, (xmlChar**)buf, len, "UTF-8");
255
static gboolean xr_call_unserialize_request_xmlrpc(xr_call* call, const char* buf, int len)
257
xmlDoc* doc = xmlReadMemory(buf, len, 0, 0, XML_PARSE_NOWARNING|XML_PARSE_NOERROR|XML_PARSE_NONET);
260
xr_call_set_error(call, -1, "Can't parse XML-RPC XML request. Invalid XML document.");
264
xmlNode* root = xmlDocGetRootElement(doc);
267
xr_call_set_error(call, -1, "Can't parse XML-RPC XML request. Root element is missing.");
271
xmlXPathContext* ctx = xmlXPathNewContext(doc);
273
call->method = xp_eval_cont_str(ctx, "/methodCall/methodName");
274
if (call->method == NULL)
276
xr_call_set_error(call, -1, "Can't parse XML-RPC XML request. Missing methodName.");
281
struct nodeset* ns = xp_eval_nodes(ctx, "/methodCall/params/param/value");
282
for (i = 0; i < ns->count; i++)
284
xr_value* v = _xr_value_unserialize_xmlrpc(ns->nodes[i]);
287
xr_call_set_error(call, -1, "Can't parse XML-RPC XML request. Failed to unserialize parameter %d.", i);
290
xr_call_add_param(call, v);
294
xmlXPathFreeContext(ctx);
301
xmlXPathFreeContext(ctx);
308
static gboolean xr_call_unserialize_response_xmlrpc(xr_call* call, const char* buf, int len)
310
xmlDoc* doc = xmlReadMemory(buf, len, 0, 0, XML_PARSE_NOWARNING|XML_PARSE_NOERROR|XML_PARSE_NONET);
313
xr_call_set_error(call, -1, "Can't parse XML-RPC XML response. Invalid XML document.");
317
xmlNode* root = xmlDocGetRootElement(doc);
320
xr_call_set_error(call, -1, "Can't parse XML-RPC XML response. Root element is missing.");
324
xmlXPathContext* ctx = xmlXPathNewContext(doc);
326
struct nodeset* ns = xp_eval_nodes(ctx, "/methodResponse/params/param/value");
329
call->retval = _xr_value_unserialize_xmlrpc(ns->nodes[0]);
330
if (call->retval == NULL)
332
xr_call_set_error(call, -1, "Can't parse XML-RPC XML response. Failed to unserialize retval.");
337
else if (ns->count > 1) // more than one param is bad
339
xr_call_set_error(call, -1, "Can't parse XML-RPC XML response. Too many return values.");
344
// ok no params/param, check for fault
345
ns = xp_eval_nodes(ctx, "/methodResponse/fault/value");
348
call->retval = _xr_value_unserialize_xmlrpc(ns->nodes[0]);
349
if (call->retval == NULL)
351
xr_call_set_error(call, -1, "Can't parse XML-RPC XML response. Failed to unserialize fault response.");
354
// check if client returned standard XML-RPC error message, we want to process
355
// it differently than normal retval
358
if (xr_value_is_error_retval(call->retval, &errcode, &errmsg))
360
xr_call_set_error(call, errcode, "%s", errmsg);
366
xr_call_set_error(call, -1, "Can't parse XML-RPC XML response. Invalid fault response.");
370
else // no fault either
372
xr_call_set_error(call, -1, "Can't parse XML-RPC XML response. Failed to unserialize retval.");
378
xmlXPathFreeContext(ctx);
383
xr_value_unref(call->retval);
387
xmlXPathFreeContext(ctx);
394
static void xr_call_free_buffer_xmlrpc(xr_call* call, char* buf)