Better support for extra data for SRU codecs and GFS
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 27 Oct 2009 13:27:58 +0000 (14:27 +0100)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 27 Oct 2009 13:27:58 +0000 (14:27 +0100)
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
include/yaz/backend.h
include/yaz/srw.h
src/seshigh.c
src/srw.c
src/srwutil.c
src/zoom-c.c
ztest/ztest.c

diff --git a/NEWS b/NEWS
index 632972a..b574e27 100644 (file)
--- 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
index a7a4874..5667e5c 100644 (file)
@@ -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. */
index 1a07418..2136619 100644 (file)
@@ -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,
index 15535b1..b0349e7 100644 (file)
@@ -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)
index 869f4d5..bc3c747 100644 (file)
--- 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;
index 6284831..b90ca6e 100644 (file)
@@ -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;
 }
 
index 290fb2f..dc1dc0c 100644 (file)
@@ -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)
index 170fba5..c95c471 100644 (file)
@@ -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, "<extra>");
+        for (a = rr->extra_args; a; a = a->next)
+        {
+            wrbuf_puts(response_xml, "<extra name=\"");
+            wrbuf_xmlputs(response_xml, a->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, "</extra>");
+        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;
 }