From: Adam Dickmeiss Date: Tue, 18 Mar 2003 13:34:35 +0000 (+0000) Subject: SRU support for frontend server X-Git-Tag: YAZ.2.0.1~38 X-Git-Url: http://sru.miketaylor.org.uk/?a=commitdiff_plain;h=6a9f385c94281b3dbddd612f388837c01661c5c5;p=yaz-moved-to-github.git SRU support for frontend server --- diff --git a/CHANGELOG b/CHANGELOG index eb3f90c..f5312b3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ Possible compatibility problems with earlier versions marked with '*'. +SRU protocol support for frontend server. + Fix compile bug for systems that have nl_langinfo but CODESET undefined. Added missing PQF transform rules for <= and >= . Thanks to Peter Popovics. diff --git a/include/yaz/nmem.h b/include/yaz/nmem.h index 2a11b2b..bf29b6a 100644 --- a/include/yaz/nmem.h +++ b/include/yaz/nmem.h @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: nmem.h,v 1.10 2003-01-06 08:20:27 adam Exp $ + * $Id: nmem.h,v 1.11 2003-03-18 13:34:35 adam Exp $ */ #ifndef NMEM_H @@ -64,6 +64,7 @@ typedef struct nmem_control *NMEM; YAZ_EXPORT void nmem_reset(NMEM n); YAZ_EXPORT int nmem_total(NMEM n); YAZ_EXPORT char *nmem_strdup (NMEM mem, const char *src); +YAZ_EXPORT char *nmem_strdupn (NMEM mem, const char *src, size_t n); YAZ_EXPORT int *nmem_intdup (NMEM mem, int v); YAZ_EXPORT void nmem_transfer (NMEM dst, NMEM src); diff --git a/include/yaz/odr.h b/include/yaz/odr.h index b9bd91f..bfd4d35 100644 --- a/include/yaz/odr.h +++ b/include/yaz/odr.h @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: odr.h,v 1.9 2003-03-11 11:03:30 adam Exp $ + * $Id: odr.h,v 1.10 2003-03-18 13:34:35 adam Exp $ */ #ifndef ODR_H @@ -194,6 +194,7 @@ YAZ_EXPORT void odr_setbuf(ODR o, char *buf, int len, int can_grow); YAZ_EXPORT char *odr_getbuf(ODR o, int *len, int *size); YAZ_EXPORT void *odr_malloc(ODR o, int size); YAZ_EXPORT char *odr_strdup(ODR o, const char *str); +YAZ_EXPORT char *odr_strdupn(ODR o, const char *str, size_t n); YAZ_EXPORT int *odr_intdup(ODR o, int v); YAZ_EXPORT NMEM odr_extract_mem(ODR o); YAZ_EXPORT Odr_null *odr_nullval(void); diff --git a/odr/odr_mem.c b/odr/odr_mem.c index 43f3c54..2ec348a 100644 --- a/odr/odr_mem.c +++ b/odr/odr_mem.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: odr_mem.c,v 1.22 2003-03-11 11:03:31 adam Exp $ + * $Id: odr_mem.c,v 1.23 2003-03-18 13:34:35 adam Exp $ */ #if HAVE_CONFIG_H #include @@ -37,6 +37,11 @@ char *odr_strdup(ODR o, const char *str) return nmem_strdup(o->mem, str); } +char *odr_strdupn(ODR o, const char *str, size_t n) +{ + return nmem_strdupn(o->mem, str, n); +} + int *odr_intdup(ODR o, int v) { return nmem_intdup(o->mem, v); diff --git a/server/seshigh.c b/server/seshigh.c index e8c6439..5f8a5c2 100644 --- a/server/seshigh.c +++ b/server/seshigh.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: seshigh.c,v 1.148 2003-03-11 11:09:17 adam Exp $ + * $Id: seshigh.c,v 1.149 2003-03-18 13:34:36 adam Exp $ */ /* @@ -539,8 +539,10 @@ static void srw_bend_search(association *assoc, request *req, Z_External *ext; yaz_log(LOG_LOG, "Got SRW SearchRetrieveRequest"); + yaz_log(LOG_DEBUG, "srw_bend_search"); if (!assoc->init) { + yaz_log(LOG_DEBUG, "srw_bend_init"); if (!srw_bend_init(assoc)) { srw_error = 3; /* assume Authentication error */ @@ -612,6 +614,7 @@ static void srw_bend_search(association *assoc, request *req, if (srw_error) { + yaz_log(LOG_DEBUG, "srw_bend_search returned SRW error %d", srw_error); srw_res->num_diagnostics = 1; srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics)); @@ -636,6 +639,7 @@ static void srw_bend_search(association *assoc, request *req, srw_res->numberOfRecords = odr_intdup(assoc->encode, rr.hits); if (rr.errcode) { + yaz_log(LOG_DEBUG, "bend_search returned Bib-1 code %d", rr.errcode); srw_res->num_diagnostics = 1; srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics)); @@ -643,6 +647,9 @@ static void srw_bend_search(association *assoc, request *req, odr_intdup(assoc->encode, yaz_diag_bib1_to_srw (rr.errcode)); srw_res->diagnostics[0].details = rr.errstring; + yaz_log(LOG_DEBUG, "srw_bend_search returned SRW error %d", + srw_res->diagnostics[0].code); + } else { @@ -652,8 +659,13 @@ static void srw_bend_search(association *assoc, request *req, int number = *srw_req->maximumRecords; int start = 1; int i; + if (srw_req->startRecord) start = *srw_req->startRecord; + + yaz_log(LOG_DEBUG, "srw_bend_search. start=%d max=%d", + start, *srw_req->maximumRecords); + if (start <= rr.hits) { int j = 0; @@ -666,6 +678,7 @@ static void srw_bend_search(association *assoc, request *req, { int errcode; srw_res->records[j].recordData_buf = 0; + yaz_log(LOG_DEBUG, "srw_bend_fetch %d", i+start); errcode = srw_bend_fetch(assoc, i+start, srw_req, srw_res->records + j); if (errcode) @@ -691,6 +704,70 @@ static void srw_bend_search(association *assoc, request *req, } } +static int hex_digit (int ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a'+10; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A'+10; + return 0; +} + +static char *uri_val(const char *path, const char *name, ODR o) +{ + size_t nlen = strlen(name); + if (*path != '?') + return 0; + path++; + while (path && *path) + { + const char *p1 = strchr(path, '='); + if (!p1) + break; + if (p1 - path == nlen && !memcmp(path, name, nlen)) + { + size_t i = 0; + char *ret; + + path = p1 + 1; + p1 = strchr(path, '&'); + if (!p1) + p1 = strlen(path) + path; + ret = odr_malloc(o, p1 - path + 1); + while (*path && *path != '&') + { + if (*path == '+') + { + ret[i++] = ' '; + path++; + } + else if (*path == '%' && path[1] && path[2]) + { + ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]); + path = path + 3; + } + else + ret[i++] = *path++; + } + ret[i] = '\0'; + return ret; + } + path = strchr(p1, '&'); + if (path) + path++; + } + return 0; +} + +void uri_val_int(const char *path, const char *name, ODR o, int **intp) +{ + const char *v = uri_val(path, name, o); + if (v) + *intp = odr_intdup(o, atoi(v)); +} + static void process_http_request(association *assoc, request *req) { Z_HTTP_Request *hreq = req->gdu_request->u.HTTP_Request; @@ -701,6 +778,94 @@ static void process_http_request(association *assoc, request *req) if (!strcmp(hreq->method, "GET")) { + char *charset = 0; + int ret = -1; + Z_SOAP *soap_package = 0; + char *db = "Default"; + const char *p0 = hreq->path, *p1; + static Z_SOAP_Handler soap_handlers[2] = { +#if HAVE_XML2 + {"http://www.loc.gov/zing/srw/v1.0/", 0, + (Z_SOAP_fun) yaz_srw_codec}, +#endif + {0, 0, 0} + }; + + if (*p0 == '/') + p0++; + p1 = strchr(p0, '?'); + if (!p1) + p1 = p0 + strlen(p0); + if (p1 != p0) + { + db = odr_malloc(assoc->decode, p1 - p0 + 1); + memcpy (db, p0, p1 - p0); + db[p1 - p0] = '\0'; + } + + if (p1 && *p1 == '?' && p1[1]) + { + Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_searchRetrieve_response); + Z_SRW_PDU *sr = yaz_srw_get(o, Z_SRW_searchRetrieve_request); + char *query = uri_val(p1, "query", o); + char *pQuery = uri_val(p1, "pQuery", o); + char *sortKeys = uri_val(p1, "sortKeys", o); + + if (query) + { + sr->u.request->query_type = Z_SRW_query_type_cql; + sr->u.request->query.cql = query; + } + if (pQuery) + { + sr->u.request->query_type = Z_SRW_query_type_pqf; + sr->u.request->query.pqf = pQuery; + } + if (sortKeys) + { + sr->u.request->sort_type = Z_SRW_sort_type_sort; + sr->u.request->sort.sortKeys = sortKeys; + } + sr->u.request->recordSchema = uri_val(p1, "recordSchema", o); + uri_val_int(p1, "maximumRecords", o, + &sr->u.request->maximumRecords); + uri_val_int(p1, "startRecord", o, + &sr->u.request->startRecord); + if (sr->u.request->startRecord) + yaz_log(LOG_LOG, "startRecord=%d", *sr->u.request->startRecord); + sr->u.request->database = db; + srw_bend_search(assoc, req, sr->u.request, + res->u.response); + + soap_package = odr_malloc(o, sizeof(*soap_package)); + soap_package->which = Z_SOAP_generic; + + soap_package->u.generic = + odr_malloc(o, sizeof(*soap_package->u.generic)); + + soap_package->u.generic->p = res; + soap_package->u.generic->ns = soap_handlers[0].ns; + soap_package->u.generic->no = 0; + + soap_package->ns = "SRU"; + + p = z_get_HTTP_Response(o, 200); + hres = p->u.HTTP_Response; + + ret = z_soap_codec_enc(assoc->encode, &soap_package, + &hres->content_buf, &hres->content_len, + soap_handlers, charset); + if (!charset) + z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml"); + else + { + char ctype[60]; + strcpy(ctype, "text/xml; charset="); + strcat(ctype, charset); + z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); + } + + } #ifdef DOCDIR if (strlen(hreq->path) >= 5 && strlen(hreq->path) < 80 && !memcmp(hreq->path, "/doc/", 5)) diff --git a/util/nmemsdup.c b/util/nmemsdup.c index 0c32d71..33a643e 100644 --- a/util/nmemsdup.c +++ b/util/nmemsdup.c @@ -1,23 +1,8 @@ /* - * Copyright (c) 1997-2001, Index Data. + * Copyright (c) 1997-2003, Index Data. * See the file LICENSE for details. * - * $Log: nmemsdup.c,v $ - * Revision 1.5 2001-03-25 21:55:13 adam - * Added odr_intdup. Ztest server returns TaskPackage for ItemUpdate. - * - * Revision 1.4 2000/02/29 13:44:55 adam - * Check for config.h (currently not generated). - * - * Revision 1.3 1999/11/30 13:47:12 adam - * Improved installation. Moved header files to include/yaz. - * - * Revision 1.2 1998/02/11 11:53:36 adam - * Changed code so that it compiles as C++. - * - * Revision 1.1 1997/09/17 12:10:42 adam - * YAZ version 1.4. - * + * $Id: nmemsdup.c,v 1.6 2003-03-18 13:34:37 adam Exp $ */ #if HAVE_CONFIG_H #include @@ -33,6 +18,14 @@ char *nmem_strdup (NMEM mem, const char *src) return dst; } +char *nmem_strdupn (NMEM mem, const char *src, size_t n) +{ + char *dst = (char *)nmem_malloc (mem, n+1); + memcpy (dst, src, n); + dst[n] = '\0'; + return dst; +} + int *nmem_intdup(NMEM mem, int v) { int *dst = (int*) nmem_malloc (mem, sizeof(int)); diff --git a/zutil/soap.c b/zutil/soap.c index d848cf9..0b34cdb 100644 --- a/zutil/soap.c +++ b/zutil/soap.c @@ -2,7 +2,7 @@ * Copyright (c) 2002-2003, Index Data. * See the file LICENSE for details. * - * $Id: soap.c,v 1.6 2003-03-11 11:09:17 adam Exp $ + * $Id: soap.c,v 1.7 2003-03-18 13:34:37 adam Exp $ */ #include @@ -184,8 +184,6 @@ int z_soap_codec_enc(ODR o, Z_SOAP **pp, Z_SOAP *p = *pp; xmlNsPtr ns_env; xmlNodePtr envelope_ptr, body_ptr; - xmlChar *buf_out; - int len_out; xmlDocPtr doc = xmlNewDoc("1.0"); @@ -215,14 +213,23 @@ int z_soap_codec_enc(ODR o, Z_SOAP **pp, if (ret) return ret; } - if (encoding) - xmlDocDumpMemoryEnc(doc, &buf_out, &len_out, encoding); - else - xmlDocDumpMemory(doc, &buf_out, &len_out); - *content_buf = (char *) odr_malloc(o, len_out); - *content_len = len_out; - memcpy(*content_buf, buf_out, len_out); - xmlFree(buf_out); + if (p->which == Z_SOAP_generic && !strcmp(p->ns, "SRU")) + { + xmlDocSetRootElement(doc, body_ptr->children); + } + if (1) + { + xmlChar *buf_out; + int len_out; + if (encoding) + xmlDocDumpMemoryEnc(doc, &buf_out, &len_out, encoding); + else + xmlDocDumpMemory(doc, &buf_out, &len_out); + *content_buf = (char *) odr_malloc(o, len_out); + *content_len = len_out; + memcpy(*content_buf, buf_out, len_out); + xmlFree(buf_out); + } xmlFreeDoc(doc); return 0; } diff --git a/zutil/srw.c b/zutil/srw.c index 813908d..2078563 100644 --- a/zutil/srw.c +++ b/zutil/srw.c @@ -2,7 +2,7 @@ * Copyright (c) 2002-2003, Index Data. * See the file LICENSE for details. * - * $Id: srw.c,v 1.8 2003-03-03 19:57:37 adam Exp $ + * $Id: srw.c,v 1.9 2003-03-18 13:34:37 adam Exp $ */ #include @@ -333,7 +333,6 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, &res->nextRecordPosition)) ; } - } else return -1; @@ -345,9 +344,12 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if ((*p)->which == Z_SRW_searchRetrieve_request) { Z_SRW_searchRetrieveRequest *req = (*p)->u.request; - xmlNsPtr ns_srw = xmlNewNs(pptr, ns, "zs"); - xmlNodePtr ptr = xmlNewChild(pptr, ns_srw, + xmlNodePtr ptr = xmlNewChild(pptr, 0, "searchRetrieveRequest", 0); + xmlNsPtr ns_srw = xmlNewNs(ptr, ns, "zs"); + + xmlSetNs(ptr, ns_srw); + switch(req->query_type) { case Z_SRW_query_type_cql: @@ -380,10 +382,11 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if ((*p)->which == Z_SRW_searchRetrieve_response) { Z_SRW_searchRetrieveResponse *res = (*p)->u.response; - xmlNsPtr ns_srw = xmlNewNs(pptr, ns, "zs"); - xmlNodePtr ptr = xmlNewChild(pptr, ns_srw, + xmlNodePtr ptr = xmlNewChild(pptr, 0, "searchRetrieveResponse", 0); + xmlNsPtr ns_srw = xmlNewNs(ptr, ns, "zs"); + xmlSetNs(ptr, ns_srw); add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords); add_xsd_string(ptr, "resultSetId", res->resultSetId); add_xsd_integer(ptr, "resultSetIdleTime", res->resultSetIdleTime);