📄 xmlrpc.c
字号:
if (response->fault != NULL) { error(0, "XMLRPC: Fault Response may not contain any param."); return -1; } response->param = value; return 0;}static int xmlrpc_response_is_fault(XMLRPCMethodResponse *response){ if (response == NULL || response->fault == NULL) return 0; return 1;}static long xmlrpc_response_get_faultcode(XMLRPCMethodResponse *faultresponse){ if (! xmlrpc_response_is_fault(faultresponse)) { error(0, "XMLRPC response is not fault response."); return -1; } return xmlrpc_fault_get_code(faultresponse->fault);}static Octstr *xmlrpc_response_get_faultstring(XMLRPCMethodResponse *faultresponse){ if (! xmlrpc_response_is_fault(faultresponse)) { error(0, "XMLRPC response is not fault response."); return NULL; } return xmlrpc_fault_get_string(faultresponse->fault);}static Octstr *xmlrpc_response_print(XMLRPCMethodResponse *response, int level){ Octstr *body = NULL, *os_value = NULL; if (response->fault == NULL && response->param != NULL) { os_value = xmlrpc_value_print(response->param, level + 6); body = octstr_format("%*s<methodResponse>\n" "%*s<params>\n%*s<param>\n" "%S" "%*s</param>\n%*s</params>\n" "%*s</methodResponse>\n", level, "", level+2, "", level+4, "", os_value, level+4, "", level+2, "", level, ""); } else if (response->fault != NULL && response->param == NULL) { os_value = xmlrpc_fault_print(response->fault, level + 2); body = octstr_format("%*s<methodResponse>\n" "%S" "%*s</methodResponse>\n", level, "", os_value, level, ""); } octstr_destroy(os_value); return body;}/*------------------------------------- * Document */XMLRPCDocument *xmlrpc_doc_create(void){ XMLRPCDocument *xrdoc = gw_malloc(sizeof(XMLRPCDocument)); xrdoc->d_type = xr_undefined; xrdoc->parse_status = XMLRPC_COMPILE_OK; xrdoc->parse_error = NULL; xrdoc->methodcall = NULL; xrdoc->methodresponse = NULL; return xrdoc;}XMLRPCDocument *xmlrpc_doc_create_call(Octstr *name){ XMLRPCDocument *xrdoc; xrdoc = xmlrpc_doc_create(); xrdoc->d_type = xr_methodcall; xrdoc->methodcall = xmlrpc_call_create(name); return xrdoc;}XMLRPCDocument *xmlrpc_doc_create_response(void){ XMLRPCDocument *xrdoc; xrdoc = xmlrpc_doc_create(); xrdoc->d_type = xr_methodresponse; xrdoc->methodresponse = xmlrpc_response_create(); return xrdoc;}XMLRPCDocument *xmlrpc_doc_create_faultresponse(long faultcode, Octstr *faultstring){ XMLRPCDocument *xrdoc; XMLRPCMethodResponse *response; xrdoc = xmlrpc_doc_create_response(); response = xrdoc->methodresponse; response->fault = xmlrpc_fault_create(faultcode, faultstring); return xrdoc;}XMLRPCDocument *xmlrpc_doc_parse(Octstr *post_body, int d_type){ XMLRPCDocument *xrdoc = xmlrpc_doc_create(); xmlDocPtr pDoc; size_t size; char *body; if (post_body == NULL) { xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED; xrdoc->parse_error = octstr_create("XMLRPC: (null) XML document given."); return xrdoc; } xrdoc->d_type = d_type; octstr_strip_blanks(post_body); octstr_shrink_blanks(post_body); size = octstr_len(post_body); body = octstr_get_cstr(post_body); /* parse XML document to a XML tree */ pDoc = xmlParseMemory(body, size); if (!pDoc) { xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED; xrdoc->parse_error = octstr_create("XMLRPC: not valid XML document given."); return xrdoc; } parse_document(pDoc, xrdoc); xmlFreeDoc(pDoc); return xrdoc;}/* Destroy XMLRPCDocument object */void xmlrpc_doc_destroy(XMLRPCDocument *xrdoc, int d_type){ if (xrdoc == NULL) return; if (xrdoc->d_type != d_type) warning(0, "Destroying document with different type then given."); xmlrpc_call_destroy(xrdoc->methodcall); xmlrpc_response_destroy(xrdoc->methodresponse); octstr_destroy(xrdoc->parse_error); gw_free(xrdoc);}/* Add given <value> param to XMLRPCDocument object. * Return 0 if ok or -1 if something wrong (e.g. xrdoc is null or faultresponse) */int xmlrpc_doc_add_value(XMLRPCDocument *xrdoc, int d_type, XMLRPCValue *value){ if (xrdoc == NULL) return -1; if (xrdoc->d_type != d_type && d_type != xr_undefined) { error(0, "Wrong xmlrpc document type. Param not added."); return -1; } if (xrdoc->d_type == xr_methodresponse) { if (xmlrpc_response_add_param(xrdoc->methodresponse, value) < 0) return -1; } else if (xrdoc->d_type == xr_methodcall) { if (xmlrpc_call_add_param(xrdoc->methodcall, value) < 0) return -1; } else { error(0, "Unknown xmlrpc document type. Param not added."); return -1; } return 0;}/* Add a scalar param to MethodCall/MethodResponse. * Return 0 if ok or -1 if something wrong (e.g. xrdoc is null or faultresponse) */int xmlrpc_doc_add_scalar(XMLRPCDocument *xrdoc, int d_type, int type, void *arg){ XMLRPCValue *param; param = xmlrpc_create_scalar_value(type, arg); if (xmlrpc_doc_add_value(xrdoc, d_type, param) < 0) { xmlrpc_value_destroy(param); return -1; } return 0;}/* Create Octstr (text/xml string) out of given XMLRPCDocument. Caller * must free returned Octstr */Octstr *xmlrpc_doc_print(XMLRPCDocument *xrdoc, int d_type, int level){ Octstr *body = NULL, *pref = NULL; if (xrdoc == NULL) return NULL; if (xrdoc->d_type != d_type) { error(0, "Wrong xmlrpc document type."); return NULL; } if (xrdoc->d_type == xr_methodresponse) { body = xmlrpc_response_print(xrdoc->methodresponse, level); } else if (xrdoc->d_type == xr_methodcall) { body = xmlrpc_call_print(xrdoc->methodcall, level); } else { error(0, "Unknown xmlrpc document type."); } if (body != NULL) { pref = octstr_format("%*s<?xml version=\"1.0\"?>\n", level, ""); octstr_insert(body, pref, 0); octstr_destroy(pref); } return body;}/* Send XMLRPCDocument to given URL with given Headers. * Return 0 if all went fine, -1 if failure. As user reference, uses *void */int xmlrpc_doc_send(XMLRPCDocument *xrdoc, int d_type, HTTPCaller *http_ref, Octstr *url, List *headers, void *ref){ Octstr *body; if (http_ref == NULL || xrdoc == NULL) return -1; if (xrdoc->d_type != d_type) { error(0, "Wrong xmlrpc document type."); return -1; } if (headers == NULL) headers = list_create(); http_header_remove_all(headers, "Content-Type"); http_header_add(headers, "Content-Type", "text/xml"); /* * XML-RPC specs say we at least need Host and User-Agent * HTTP headers to be defined. * These are set anyway within gwlib/http.c:build_request() */ body = xmlrpc_doc_print(xrdoc, d_type, 0); http_start_request(http_ref, HTTP_METHOD_POST, url, headers, body, 0, ref, NULL); octstr_destroy(body); /* XXX: should headers be destroyed here? */ /*http_destroy_headers(headers); */ return 0;}/*------------------------------------- * XMLRPCValue *//* Create new value. Set type of it to xr_undefined, so it must be * set laterwards to correct one */XMLRPCValue *xmlrpc_value_create(void){ XMLRPCValue *val = gw_malloc(sizeof(XMLRPCValue)); val->v_type = xr_undefined; val->v_scalar = NULL; val->v_array = NULL; val->v_struct = NULL; return val;}/* Destroy value with its information, recursively if need to */void xmlrpc_value_destroy(XMLRPCValue *val){ if (val == NULL) return; switch(val->v_type) { case xr_scalar: xmlrpc_scalar_destroy(val->v_scalar); break; case xr_array: list_destroy(val->v_array, xmlrpc_value_destroy_item); break; case xr_struct: dict_destroy(val->v_struct); break; } gw_free(val);}/* wrapper to destroy to be used with list */void xmlrpc_value_destroy_item(void *val){ xmlrpc_value_destroy(val);}int xmlrpc_value_set_type(XMLRPCValue *val, int v_type){ if (val == NULL) return -1; switch(v_type) { case xr_scalar: case xr_array: case xr_struct: val->v_type = v_type; break; default: error(0, "XMLRPC: value type not supported."); return -1; } return 0;}int xmlrpc_value_set_content(XMLRPCValue *val, void *content){ if (val == NULL) return -1; switch(val->v_type) { case xr_scalar: val->v_scalar = (XMLRPCScalar *)content; break; case xr_array: val->v_array = (List *)content; break; case xr_struct: val->v_struct = (Dict *)content; break; default: error(0, "XMLRPC: value type not supported."); return -1; } return 0;}int xmlrpc_value_get_type(XMLRPCValue *val){ if (val == NULL) return -1; return val->v_type;}int xmlrpc_value_get_type_smart(XMLRPCValue *val){ int type = xmlrpc_value_get_type(val); if (type == xr_scalar) return xmlrpc_get_scalar_value_type(val); return type;}void *xmlrpc_value_get_content(XMLRPCValue *val){ if (val == NULL) return NULL; switch(val->v_type) { case xr_scalar: return val->v_scalar; case xr_array: return val->v_array; case xr_struct: return val->v_struct; default: error(0, "XMLRPC: value type not supported."); return NULL; }}Octstr *xmlrpc_value_print(XMLRPCValue *val, int level){ Octstr *body = NULL, *os = NULL; if (val == NULL) return NULL; switch(val->v_type) { case xr_scalar: os = xmlrpc_scalar_print(val->v_scalar, level+2); break; case xr_struct: os = xmlrpc_print_struct(val->v_struct, level+2); break; case xr_array: os = xmlrpc_print_array(val->v_array, level+2); break; default: return NULL; } if (os != NULL) { body = octstr_format("%*s<value>\n%S%*s</value>\n", level, "", os, level, ""); octstr_destroy(os); } return body;}/*------------------------------------- * XMLRPCScalar *//* Create new scalar of given type with given argument */XMLRPCScalar *xmlrpc_scalar_create(int type, void *arg){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -