X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fsoap.c;h=94e0f1942e6dac8f191302300332cf14bb94c568;hp=d2f38f8eb4c303ed51297055c2ac61288718fd9b;hb=f0df1959fda559c0d952810c338a9fde667b5a63;hpb=dd7de5f04a0de631f98ad9c4774f2111a85388e5 diff --git a/src/soap.c b/src/soap.c index d2f38f8..94e0f19 100644 --- a/src/soap.c +++ b/src/soap.c @@ -1,24 +1,33 @@ -/* - * Copyright (c) 2002-2004, Index Data. +/* This file is part of the YAZ toolkit. + * Copyright (C) Index Data * See the file LICENSE for details. + */ +/** + * \file soap.c + * \brief Implements SOAP * - * $Id: soap.c,v 1.8 2004-10-02 13:28:26 adam Exp $ + * This implements encoding and decoding of SOAP packages using + * Libxml2. */ +#if HAVE_CONFIG_H +#include +#endif #include +#include -#if HAVE_XML2 +#if YAZ_HAVE_XML2 #include #include static const char *soap_v1_1 = "http://schemas.xmlsoap.org/soap/envelope/"; static const char *soap_v1_2 = "http://www.w3.org/2001/06/soap-envelope"; -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) +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) { if (o->direction == ODR_DECODE) { @@ -37,10 +46,56 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, if (!doc) return z_soap_error(o, p, "SOAP-ENV:Client", "Bad XML Document", 0); - /* check that root node is Envelope */ + ptr = xmlDocGetRootElement(doc); - if (!ptr || ptr->type != XML_ELEMENT_NODE || - strcmp(ptr->name, "Envelope") || !ptr->ns) + if (!ptr || ptr->type != XML_ELEMENT_NODE || !ptr->ns) + { + xmlFreeDoc(doc); + return z_soap_error(o, p, "SOAP-ENV:Client", + "No Envelope element", 0); + } + /* check for SRU root node match */ + for (i = 0; handlers[i].ns; i++) + { + const char *hns = handlers[i].ns; + if (strchr(hns, ':')) + { + if (yaz_match_glob(hns, (const char *) ptr->ns->href)) + break; + } + else + { + if (yaz_match_glob(hns, (const char *) ptr->name)) + break; + } + } + if (handlers[i].ns) + { + void *handler_data = 0; + xmlNode p_top_tmp; /* pseudo parent node needed */ + + p_top_tmp.children = ptr; + ret = (*handlers[i].f)(o, &p_top_tmp, &handler_data, + handlers[i].client_data, + (const char *)ptr->ns->href); + + if (ret || !handler_data) + z_soap_error(o, p, "SOAP-ENV:Client", + "SOAP Handler returned error", 0); + else + { + p->which = Z_SOAP_generic; + p->u.generic = (Z_SOAP_Generic *) + odr_malloc(o, sizeof(*p->u.generic)); + p->u.generic->no = i; + p->u.generic->ns = handlers[i].ns; + p->u.generic->p = handler_data; + } + xmlFreeDoc(doc); + return ret; + } + /* OK: assume SOAP */ + if (xmlStrcmp(ptr->name, BAD_CAST "Envelope")) { xmlFreeDoc(doc); return z_soap_error(o, p, "SOAP-ENV:Client", @@ -49,7 +104,7 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, else { /* determine SOAP version */ - const char * ns_envelope = ptr->ns->href; + const char * ns_envelope = (const char *) ptr->ns->href; if (!strcmp(ns_envelope, soap_v1_1)) p->ns = soap_v1_1; else if (!strcmp(ns_envelope, soap_v1_2)) @@ -65,22 +120,22 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, while(ptr && ptr->type == XML_TEXT_NODE) ptr = ptr->next; if (ptr && ptr->type == XML_ELEMENT_NODE && - !strcmp(ptr->ns->href, p->ns) && - !strcmp(ptr->name, "Header")) + !xmlStrcmp(ptr->ns->href, BAD_CAST p->ns) && + !xmlStrcmp(ptr->name, BAD_CAST "Header")) { ptr = ptr->next; while(ptr && ptr->type == XML_TEXT_NODE) ptr = ptr->next; } /* check that Body is present */ - if (!ptr || ptr->type != XML_ELEMENT_NODE || - strcmp(ptr->name, "Body")) + if (!ptr || ptr->type != XML_ELEMENT_NODE || + xmlStrcmp(ptr->name, BAD_CAST "Body")) { xmlFreeDoc(doc); return z_soap_error(o, p, "SOAP-ENV:Client", "SOAP Body element not found", 0); } - if (strcmp(ptr->ns->href, p->ns)) + if (xmlStrcmp(ptr->ns->href, BAD_CAST p->ns)) { xmlFreeDoc(doc); return z_soap_error(o, p, "SOAP-ENV:Client", @@ -103,8 +158,8 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, "SOAP No namespace for content", 0); } /* check for fault package */ - if (!strcmp(ptr->ns->href, p->ns) - && !strcmp(ptr->name, "Fault") && ptr->children) + if (!xmlStrcmp(ptr->ns->href, BAD_CAST p->ns) + && !xmlStrcmp(ptr->name, BAD_CAST "Fault") && ptr->children) { ptr = ptr->children; @@ -117,15 +172,18 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, { if (ptr->children && ptr->children->type == XML_TEXT_NODE) { - if (!strcmp(ptr->name, "faultcode")) + if (!xmlStrcmp(ptr->name, BAD_CAST "faultcode")) p->u.fault->fault_code = - odr_strdup(o, ptr->children->content); - if (!strcmp(ptr->name, "faultstring")) + odr_strdup(o, (const char *) + ptr->children->content); + if (!xmlStrcmp(ptr->name, BAD_CAST "faultstring")) p->u.fault->fault_string = - odr_strdup(o, ptr->children->content); - if (!strcmp(ptr->name, "details")) + odr_strdup(o, (const char *) + ptr->children->content); + if (!xmlStrcmp(ptr->name, BAD_CAST "details")) p->u.fault->details = - odr_strdup(o, ptr->children->content); + odr_strdup(o, (const char *) + ptr->children->content); } ptr = ptr->next; } @@ -133,15 +191,18 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, } else { + const char *ns = (const char *) ptr->ns->href; for (i = 0; handlers[i].ns; i++) - if (!strcmp(ptr->ns->href, handlers[i].ns)) + { + if (strchr(handlers[i].ns, ':') && + yaz_match_glob(handlers[i].ns, ns)) break; + } if (handlers[i].ns) { void *handler_data = 0; ret = (*handlers[i].f)(o, pptr, &handler_data, - handlers[i].client_data, - handlers[i].ns); + handlers[i].client_data, ns); if (ret || !handler_data) z_soap_error(o, p, "SOAP-ENV:Client", "SOAP Handler returned error", 0); @@ -149,7 +210,7 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, { p->which = Z_SOAP_generic; p->u.generic = (Z_SOAP_Generic *) - odr_malloc(o, sizeof(*p->u.generic)); + odr_malloc(o, sizeof(*p->u.generic)); p->u.generic->no = i; p->u.generic->ns = handlers[i].ns; p->u.generic->p = handler_data; @@ -157,8 +218,8 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, } else { - ret = z_soap_error(o, p, "SOAP-ENV:Client", - "No handler for NS", ptr->ns->href); + ret = z_soap_error(o, p, "SOAP-ENV:Client", + "No handler for NS", ns); } } xmlFreeDoc(doc); @@ -170,52 +231,59 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, xmlNsPtr ns_env; xmlNodePtr envelope_ptr, body_ptr; - xmlDocPtr doc = xmlNewDoc("1.0"); + xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); - envelope_ptr = xmlNewNode(0, "Envelope"); - ns_env = xmlNewNs(envelope_ptr, p->ns, "SOAP-ENV"); + envelope_ptr = xmlNewNode(0, BAD_CAST "Envelope"); + ns_env = xmlNewNs(envelope_ptr, BAD_CAST p->ns, + BAD_CAST "SOAP-ENV"); xmlSetNs(envelope_ptr, ns_env); - body_ptr = xmlNewChild(envelope_ptr, ns_env, "Body", 0); + body_ptr = xmlNewChild(envelope_ptr, ns_env, BAD_CAST "Body", + 0); xmlDocSetRootElement(doc, envelope_ptr); if (p->which == Z_SOAP_fault || p->which == Z_SOAP_error) { Z_SOAP_Fault *f = p->u.fault; - xmlNodePtr fault_ptr = xmlNewChild(body_ptr, ns_env, "Fault", 0); - xmlNewChild(fault_ptr, ns_env, "faultcode", f->fault_code); - xmlNewChild(fault_ptr, ns_env, "faultstring", f->fault_string); + xmlNodePtr fault_ptr = xmlNewChild(body_ptr, ns_env, + BAD_CAST "Fault", 0); + xmlNewChild(fault_ptr, ns_env, BAD_CAST "faultcode", + BAD_CAST f->fault_code); + xmlNewChild(fault_ptr, ns_env, BAD_CAST "faultstring", + BAD_CAST f->fault_string); if (f->details) - xmlNewChild(fault_ptr, ns_env, "details", f->details); + xmlNewChild(fault_ptr, ns_env, BAD_CAST "details", + BAD_CAST f->details); } else if (p->which == Z_SOAP_generic) { int ret, no = p->u.generic->no; - + ret = (*handlers[no].f)(o, body_ptr, &p->u.generic->p, handlers[no].client_data, handlers[no].ns); if (ret) - { - xmlFreeDoc(doc); + { + xmlFreeDoc(doc); return ret; - } + } } if (p->which == Z_SOAP_generic && !strcmp(p->ns, "SRU")) { xmlDocSetRootElement(doc, body_ptr->children); - body_ptr->children = 0; - xmlFreeNode(envelope_ptr); + body_ptr->children = 0; + xmlFreeNode(envelope_ptr); + } + if (stylesheet) + { + char *content = (char *) odr_malloc(o, strlen(stylesheet) + 40); + + xmlNodePtr pi, ptr = xmlDocGetRootElement(doc); + sprintf(content, "type=\"text/xsl\" href=\"%s\"", stylesheet); + pi = xmlNewPI(BAD_CAST "xml-stylesheet", + BAD_CAST content); + xmlAddPrevSibling(ptr, pi); } - if (stylesheet) - { - char *content = odr_malloc(o, strlen(stylesheet) + 40); - - xmlNodePtr pi, ptr = xmlDocGetRootElement(doc); - sprintf(content, "type=\"text/xsl\" href=\"%s\"", stylesheet); - pi = xmlNewPI("xml-stylesheet", content); - xmlAddPrevSibling(ptr, pi); - } if (1) { xmlChar *buf_out; @@ -235,10 +303,10 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, return 0; } #else -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) +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 char *err_xml = "\n" @@ -260,16 +328,16 @@ int z_soap_codec_enc_xsl(ODR o, Z_SOAP **pp, return -1; } #endif -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_codec_enc(ODR o, Z_SOAP **pp, + char **content_buf, int *content_len, + Z_SOAP_Handler *handlers, + const char *encoding) { return z_soap_codec_enc_xsl(o, pp, content_buf, content_len, handlers, - encoding, 0); + encoding, 0); } -int z_soap_codec(ODR o, Z_SOAP **pp, +int z_soap_codec(ODR o, Z_SOAP **pp, char **content_buf, int *content_len, Z_SOAP_Handler *handlers) { @@ -281,7 +349,7 @@ int z_soap_error(ODR o, Z_SOAP *p, const char *details) { p->which = Z_SOAP_error; - p->u.soap_error = (Z_SOAP_Fault *) + p->u.soap_error = (Z_SOAP_Fault *) odr_malloc(o, sizeof(*p->u.soap_error)); p->u.soap_error->fault_code = odr_strdup(o, fault_code); p->u.soap_error->fault_string = odr_strdup(o, fault_string); @@ -292,3 +360,12 @@ int z_soap_error(ODR o, Z_SOAP *p, return -1; } +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +