20 #include <libxml/parser.h>
21 #include <libxml/tree.h>
23 static const char *
soap_v1_1 =
"http://schemas.xmlsoap.org/soap/envelope/";
24 static const char *
soap_v1_2 =
"http://www.w3.org/2001/06/soap-envelope";
27 char **content_buf,
int *content_len,
30 const char *stylesheet)
39 if (!content_buf || !*content_buf || !content_len)
45 doc = xmlParseMemory(*content_buf, *content_len);
48 "Bad XML Document", 0);
50 ptr = xmlDocGetRootElement(doc);
51 if (!ptr || ptr->type != XML_ELEMENT_NODE || !ptr->ns)
55 "No Envelope element", 0);
58 for (i = 0; handlers[i].
ns; i++)
60 const char *hns = handlers[i].
ns;
74 void *handler_data = 0;
77 p_top_tmp.children = ptr;
78 ret = (*handlers[i].
f)(o, &p_top_tmp, &handler_data,
79 handlers[i].client_data,
80 (
const char *)ptr->
ns->href);
82 if (ret || !handler_data)
84 "SOAP Handler returned error", 0);
98 if (xmlStrcmp(ptr->name, BAD_CAST
"Envelope"))
102 "No Envelope element", 0);
107 const char * ns_envelope = (
const char *) ptr->ns->href;
110 else if (!strcmp(ns_envelope,
soap_v1_2))
116 "Bad SOAP version", 0);
120 while(ptr && ptr->type == XML_TEXT_NODE)
122 if (ptr && ptr->type == XML_ELEMENT_NODE &&
123 !xmlStrcmp(ptr->ns->href, BAD_CAST p->ns) &&
124 !xmlStrcmp(ptr->name, BAD_CAST
"Header"))
127 while(ptr && ptr->type == XML_TEXT_NODE)
131 if (!ptr || ptr->type != XML_ELEMENT_NODE ||
132 xmlStrcmp(ptr->name, BAD_CAST
"Body"))
136 "SOAP Body element not found", 0);
138 if (xmlStrcmp(ptr->ns->href, BAD_CAST p->ns))
142 "SOAP bad NS for Body element", 0);
146 while (ptr && ptr->type == XML_TEXT_NODE)
148 if (!ptr || ptr->type != XML_ELEMENT_NODE)
152 "SOAP No content for Body", 0);
158 "SOAP No namespace for content", 0);
161 if (!xmlStrcmp(ptr->ns->href, BAD_CAST p->ns)
162 && !xmlStrcmp(ptr->name, BAD_CAST
"Fault") && ptr->children)
168 p->u.fault->fault_code = 0;
169 p->u.fault->fault_string = 0;
170 p->u.fault->details = 0;
173 if (ptr->children && ptr->children->type == XML_TEXT_NODE)
175 if (!xmlStrcmp(ptr->name, BAD_CAST
"faultcode"))
176 p->u.fault->fault_code =
178 ptr->children->content);
179 if (!xmlStrcmp(ptr->name, BAD_CAST
"faultstring"))
180 p->u.fault->fault_string =
182 ptr->children->content);
183 if (!xmlStrcmp(ptr->name, BAD_CAST
"details"))
184 p->u.fault->details =
186 ptr->children->content);
194 const char *ns = (
const char *) ptr->ns->href;
195 for (i = 0; handlers[i].
ns; i++)
197 if (strchr(handlers[i].ns,
':') &&
203 void *handler_data = 0;
204 ret = (*handlers[i].
f)(o, pptr, &handler_data,
205 handlers[i].client_data, ns);
206 if (ret || !handler_data)
208 "SOAP Handler returned error", 0);
214 p->u.generic->no = i;
215 p->u.generic->ns = handlers[i].
ns;
216 p->u.generic->p = handler_data;
222 "No handler for NS", ns);
232 xmlNodePtr envelope_ptr, body_ptr;
234 xmlDocPtr doc = xmlNewDoc(BAD_CAST
"1.0");
236 envelope_ptr = xmlNewNode(0, BAD_CAST
"Envelope");
237 ns_env = xmlNewNs(envelope_ptr, BAD_CAST p->
ns,
238 BAD_CAST
"SOAP-ENV");
239 xmlSetNs(envelope_ptr, ns_env);
241 body_ptr = xmlNewChild(envelope_ptr, ns_env, BAD_CAST
"Body",
243 xmlDocSetRootElement(doc, envelope_ptr);
248 xmlNodePtr fault_ptr = xmlNewChild(body_ptr, ns_env,
249 BAD_CAST
"Fault", 0);
250 xmlNewChild(fault_ptr, ns_env, BAD_CAST
"faultcode",
252 xmlNewChild(fault_ptr, ns_env, BAD_CAST
"faultstring",
255 xmlNewChild(fault_ptr, ns_env, BAD_CAST
"details",
262 ret = (*handlers[no].f)(o, body_ptr, &p->
u.
generic->
p,
263 handlers[no].client_data,
273 xmlDocSetRootElement(doc, body_ptr->children);
274 body_ptr->children = 0;
275 xmlFreeNode(envelope_ptr);
279 char *content = (
char *)
odr_malloc(o, strlen(stylesheet) + 40);
281 xmlNodePtr pi, ptr = xmlDocGetRootElement(doc);
282 sprintf(content,
"type=\"text/xsl\" href=\"%s\"", stylesheet);
283 pi = xmlNewPI(BAD_CAST
"xml-stylesheet",
285 xmlAddPrevSibling(ptr, pi);
292 xmlDocDumpMemoryEnc(doc, &buf_out, &len_out, encoding);
294 xmlDocDumpMemory(doc, &buf_out, &len_out);
295 *content_buf = (
char *)
odr_malloc(o, len_out);
296 *content_len = len_out;
297 memcpy(*content_buf, buf_out, len_out);
307 char **content_buf,
int *content_len,
309 const char *stylesheet)
311 static char *err_xml =
312 "<?xml version=\"1.0\"?>\n"
314 " xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
315 "\t<SOAP-ENV:Body>\n"
316 "\t\t<SOAP-ENV:Fault>\n"
317 "\t\t\t<faultcode>SOAP-ENV:Server</faultcode>\n"
318 "\t\t\t<faultstring>HTTP error</faultstring>\n"
319 "\t\t\t<detail>SOAP not supported in this YAZ configuration</detail>\n"
320 "\t\t</SOAP-ENV:Fault>\n"
321 "\t</SOAP-ENV:Body>\n"
322 "</SOAP-ENV:Envelope>\n";
325 *content_buf = err_xml;
326 *content_len = strlen(err_xml);
332 char **content_buf,
int *content_len,
334 const char *encoding)
341 char **content_buf,
int *content_len,
348 const char *fault_code,
const char *fault_string,
int yaz_match_glob(const char *glob, const char *text)
matches a glob expression against text
char * odr_strdup(ODR o, const char *str)
void * odr_malloc(ODR o, size_t size)
static const char * soap_v1_1
int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, char **content_buf, int *content_len, Z_SOAP_Handler *handlers, const char *encoding, const char *stylesheet)
static const char * soap_v1_2
int z_soap_codec(ODR o, Z_SOAP **pp, char **content_buf, int *content_len, Z_SOAP_Handler *handlers)
int z_soap_codec_enc(ODR o, Z_SOAP **pp, char **content_buf, int *content_len, Z_SOAP_Handler *handlers, const char *encoding)
int z_soap_error(ODR o, Z_SOAP *p, const char *fault_code, const char *fault_string, const char *details)
Z_SOAP_Fault * soap_error