From 6e3d70edfadd110351b71466c51632e288e31773 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 27 Oct 2009 14:27:58 +0100 Subject: [PATCH] Better support for extra data for SRU codecs and GFS The Z_SRW_PDU structure has two new members extraResponseData_{buf,len} for extra data response buffer and length. For the GFS, both request and response data (XML) is carried in extra_args and extra_response_data for the search handler. Patch by Ko van der Sloot. --- NEWS | 6 ++++++ include/yaz/backend.h | 2 ++ include/yaz/srw.h | 4 +++- src/seshigh.c | 15 ++++++++++++--- src/srw.c | 42 ++++++++++++++++++++++++++++++++---------- src/srwutil.c | 2 ++ src/zoom-c.c | 2 ++ ztest/ztest.c | 23 +++++++++++++++++++++++ 8 files changed, 82 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index 632972a..b574e27 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +Add support for extra request / response data for SRU codecs and GFS. +The Z_SRW_PDU structure has two new members extraResponseData_{buf,len} +for extra data response buffer and length. For the GFS, both request +and response data (XML) is carried in extra_args and extra_response_data +for the search handler. Patch by Ko van der Sloot. + --- 3.0.49 2009/10/01 Make a number of functions defined in xmlquery.c static. These have diff --git a/include/yaz/backend.h b/include/yaz/backend.h index a7a4874..5667e5c 100644 --- a/include/yaz/backend.h +++ b/include/yaz/backend.h @@ -70,6 +70,8 @@ typedef struct { int *srw_setnameIdleTime; /* holds SRU/SRW life-time */ int estimated_hit_count; /* if hit count is estimated */ int partial_resultset; /* if result set is partial */ + Z_SRW_extra_arg *extra_args; /* extra URL arguments */ + char *extra_response_data; /* extra XML response. */ } bend_search_rr; /** \brief Information for present handler. Does not replace bend_fetch. */ diff --git a/include/yaz/srw.h b/include/yaz/srw.h index 1a07418..2136619 100644 --- a/include/yaz/srw.h +++ b/include/yaz/srw.h @@ -212,7 +212,9 @@ typedef struct { char *srw_version; char *username; /* From HTTP header or request */ char *password; /* From HTTP header or request */ - Z_SRW_extra_arg *extra_args; /* only used for SRU GET/POST */ + Z_SRW_extra_arg *extra_args; /* extraRequestData SRU GET/POST */ + char *extraResponseData_buf; + int extraResponseData_len; } Z_SRW_PDU; YAZ_EXPORT int yaz_srw_codec(ODR o, void * pptr, diff --git a/src/seshigh.c b/src/seshigh.c index 15535b1..b0349e7 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -847,9 +847,10 @@ static int ccl2pqf(ODR odr, const Odr_oct *ccl, CCL_bibset bibset, static void srw_bend_search(association *assoc, request *req, Z_SRW_PDU *sr, - Z_SRW_searchRetrieveResponse *srw_res, + Z_SRW_PDU *res, int *http_code) { + Z_SRW_searchRetrieveResponse *srw_res = res->u.response; int srw_error = 0; Z_External *ext; Z_SRW_searchRetrieveRequest *srw_req = sr->u.request; @@ -872,6 +873,8 @@ static void srw_bend_search(association *assoc, request *req, rr.partial_resultset = 0; rr.query = (Z_Query *) odr_malloc(assoc->decode, sizeof(*rr.query)); rr.query->u.type_1 = 0; + rr.extra_args = sr->extra_args; + rr.extra_response_data = 0; if (srw_req->query_type == Z_SRW_query_type_cql) { @@ -1093,6 +1096,11 @@ static void srw_bend_search(association *assoc, request *req, srw_res->records = 0; } } + if (rr.extra_response_data) + { + res->extraResponseData_buf = rr.extra_response_data; + res->extraResponseData_len = strlen(rr.extra_response_data); + } if (rr.estimated_hit_count || rr.partial_resultset) { yaz_add_srw_diagnostic( @@ -1783,8 +1791,7 @@ static void process_http_request(association *assoc, request *req) } else { - srw_bend_search(assoc, req, sr, res->u.response, - &http_code); + srw_bend_search(assoc, req, sr, res, &http_code); } if (http_code == 200) soap_package->u.generic->p = res; @@ -2628,6 +2635,8 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb, bsrr->srw_setnameIdleTime = 0; bsrr->estimated_hit_count = 0; bsrr->partial_resultset = 0; + bsrr->extra_args = 0; + bsrr->extra_response_data = 0; yaz_log (log_requestdetail, "ResultSet '%s'", req->resultSetName); if (req->databaseNames) diff --git a/src/srw.c b/src/srw.c index 869f4d5..bc3c747 100644 --- a/src/srw.c +++ b/src/srw.c @@ -740,6 +740,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; + else if (match_xsd_XML_n(ptr, "extraResponseData", o, + &(*p)->extraResponseData_buf, + &(*p)->extraResponseData_len)) + ; else if (match_xsd_integer(ptr, "numberOfRecords", o, &res->numberOfRecords)) ; @@ -778,6 +782,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; + else if (match_xsd_XML_n(ptr, "extraResponseData", o, + &(*p)->extraResponseData_buf, + &(*p)->extraResponseData_len)) + ; else if (match_xsd_string(ptr, "stylesheet", o, &req->stylesheet)) ; @@ -809,6 +817,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; + else if (match_xsd_XML_n(ptr, "extraResponseData", o, + &(*p)->extraResponseData_buf, + &(*p)->extraResponseData_len)) + ; else if (match_element(ptr, "record")) yaz_srw_record(o, ptr, &res->record, &res->extra_record, client_data, ns); @@ -839,6 +851,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; + else if (match_xsd_XML_n(ptr, "extraResponseData", o, + &(*p)->extraResponseData_buf, + &(*p)->extraResponseData_len)) + ; else if (match_xsd_string(ptr, "scanClause", o, &req->scanClause.cql)) ; @@ -879,6 +895,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; + else if (match_xsd_XML_n(ptr, "extraResponseData", o, + &(*p)->extraResponseData_buf, + &(*p)->extraResponseData_len)) + ; else if (match_element(ptr, "terms")) yaz_srw_terms(o, ptr, &res->terms, &res->num_terms, client_data, @@ -902,12 +922,12 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, { Z_SRW_PDU **p = handler_data; xmlNsPtr ns_srw; + xmlNodePtr ptr = 0; if ((*p)->which == Z_SRW_searchRetrieve_request) { Z_SRW_searchRetrieveRequest *req = (*p)->u.request; - xmlNodePtr ptr = xmlNewChild(pptr, 0, - BAD_CAST "searchRetrieveRequest", 0); + ptr = xmlNewChild(pptr, 0, BAD_CAST "searchRetrieveRequest", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); @@ -948,8 +968,7 @@ 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; - xmlNodePtr ptr = xmlNewChild(pptr, 0, - BAD_CAST "searchRetrieveResponse", 0); + ptr = xmlNewChild(pptr, 0, BAD_CAST "searchRetrieveResponse", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); @@ -978,8 +997,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if ((*p)->which == Z_SRW_explain_request) { Z_SRW_explainRequest *req = (*p)->u.explain_request; - xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainRequest", - 0); + ptr = xmlNewChild(pptr, 0, BAD_CAST "explainRequest", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); @@ -991,8 +1009,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if ((*p)->which == Z_SRW_explain_response) { Z_SRW_explainResponse *res = (*p)->u.explain_response; - xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainResponse", - 0); + ptr = xmlNewChild(pptr, 0, BAD_CAST "explainResponse", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); @@ -1014,7 +1031,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if ((*p)->which == Z_SRW_scan_request) { Z_SRW_scanRequest *req = (*p)->u.scan_request; - xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0); + ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); @@ -1036,7 +1053,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if ((*p)->which == Z_SRW_scan_response) { Z_SRW_scanResponse *res = (*p)->u.scan_response; - xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0); + ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); @@ -1058,6 +1075,11 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, } else return -1; + if (ptr && (*p)->extraResponseData_len) + add_XML_n(ptr, "extraResponseData", + (*p)->extraResponseData_buf, + (*p)->extraResponseData_len, ns_srw); + } return 0; diff --git a/src/srwutil.c b/src/srwutil.c index 6284831..b90ca6e 100644 --- a/src/srwutil.c +++ b/src/srwutil.c @@ -862,6 +862,8 @@ static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version) p->username = 0; p->password = 0; p->extra_args = 0; + p->extraResponseData_buf = 0; + p->extraResponseData_len = 0; return p; } diff --git a/src/zoom-c.c b/src/zoom-c.c index 290fb2f..dc1dc0c 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -4087,6 +4087,8 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) Z_SRW_PDU *sr = (Z_SRW_PDU*) soap_package->u.generic->p; ZOOM_options_set(c->options, "sru_version", sr->srw_version); + ZOOM_options_setl(c->options, "sru_extra_response_data", + sr->extraResponseData_buf, sr->extraResponseData_len); if (sr->which == Z_SRW_searchRetrieve_response) cret = handle_srw_response(c, sr->u.response); else if (sr->which == Z_SRW_scan_response) diff --git a/ztest/ztest.c b/ztest/ztest.c index 170fba5..c95c471 100644 --- a/ztest/ztest.c +++ b/ztest/ztest.c @@ -137,6 +137,29 @@ int ztest_search(void *handle, bend_search_rr *rr) return 0; } + if (rr->extra_args) + { + Z_SRW_extra_arg *a; + WRBUF response_xml = wrbuf_alloc(); + wrbuf_puts(response_xml, ""); + for (a = rr->extra_args; a; a = a->next) + { + wrbuf_puts(response_xml, "name); + wrbuf_puts(response_xml, "\""); + if (a->value) + { + wrbuf_puts(response_xml, " value=\""); + wrbuf_xmlputs(response_xml, a->value); + wrbuf_puts(response_xml, "\""); + } + wrbuf_puts(response_xml, "/>"); + } + wrbuf_puts(response_xml, ""); + rr->extra_response_data = + odr_strdup(rr->stream, wrbuf_cstr(response_xml)); + wrbuf_destroy(response_xml); + } rr->hits = get_hit_count(rr->query); return 0; } -- 1.7.10.4