Added two new utilities for encoding SRW diagnostics via a URI rather
[yaz-moved-to-github.git] / src / srwutil.c
index 168d7b5..6519422 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2005, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: srwutil.c,v 1.28 2005-06-25 15:46:05 adam Exp $
+ * $Id: srwutil.c,v 1.34 2005-12-14 14:05:55 adam Exp $
  */
 /**
  * \file srwutil.c
@@ -29,17 +29,18 @@ int yaz_uri_array(const char *path, ODR o, char ***name, char ***val)
     int no = 2;
     const char *cp;
     *name = 0;
-    if (*path != '?')
+    if (*path == '?')
+        path++;
+    if (!*path)
         return no;
-    path++;
     cp = path;
     while ((cp = strchr(cp, '&')))
     {
         cp++;
         no++;
     }
-    *name = odr_malloc(o, no * sizeof(char**));
-    *val = odr_malloc(o, no * sizeof(char**));
+    *name = odr_malloc(o, no * sizeof(char*));
+    *val = odr_malloc(o, no * sizeof(char*));
 
     for (no = 0; *path; no++)
     {
@@ -136,20 +137,33 @@ void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp)
         *intp = odr_intdup(o, atoi(v));
 }
 
-void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d, 
-                           int code, const char *details)
+void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d, 
+                           const char *uri, const char *message,
+                           const char *details)
 {
-    d->uri = (char *) odr_malloc(o, 50);
-    sprintf(d->uri, "info:srw/diagnostic/1/%d", code);
-    d->message = 0;
+    d->uri = odr_strdup(o, uri);
+    if (message)
+        d->message = odr_strdup(o, message);
+    else
+        d->message = 0;
     if (details)
         d->details = odr_strdup(o, details);
     else
         d->details = 0;
 }
 
-void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
-                            int *num, int code, const char *addinfo)
+void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d, 
+                           int code, const char *details)
+{
+    char uri[40];
+    
+    sprintf(uri, "info:srw/diagnostic/1/%d", code);
+    return yaz_mk_srw_diagnostic(o, d, uri, 0, details);
+}
+
+void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
+                                int *num, const char *uri,
+                                const char *message, const char *details)
 {
     Z_SRW_diagnostic *d_new;
     d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
@@ -157,10 +171,19 @@ void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
         memcpy (d_new, *d, *num *sizeof(**d));
     *d = d_new;
 
-    yaz_mk_std_diagnostic(o, *d + *num, code, addinfo);
+    yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
     (*num)++;
 }
 
+void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
+                            int *num, int code, const char *addinfo)
+{
+    char uri[40];
+    
+    sprintf(uri, "info:srw/diagnostic/1/%d", code);
+    return yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
+}
+
 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
                    Z_SOAP **soap_package, ODR decode, char **charset)
 {
@@ -177,12 +200,14 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
             int ret = -1;
             const char *charset_p = 0;
             
-            static Z_SOAP_Handler soap_handlers[3] = {
+            static Z_SOAP_Handler soap_handlers[4] = {
 #if HAVE_XML2
                 {"http://www.loc.gov/zing/srw/", 0,
                  (Z_SOAP_fun) yaz_srw_codec},
                 {"http://www.loc.gov/zing/srw/v1.0/", 0,
                  (Z_SOAP_fun) yaz_srw_codec},
+                {"http://www.loc.gov/zing/srw/update/", 0,
+                 (Z_SOAP_fun) yaz_ucp_codec},
 #endif
                 {0, 0, 0}
             };
@@ -229,6 +254,10 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
                     (*srw_pdu)->u.scan_request->database == 0)
                     (*srw_pdu)->u.scan_request->database = db;
 
+                if ((*srw_pdu)->which == Z_SRW_update_request &&
+                    (*srw_pdu)->u.update_request->database == 0)
+                    (*srw_pdu)->u.update_request->database = db;
+
                 return 0;
             }
             return 1;
@@ -251,7 +280,21 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
         {0, 0, 0}
     };
 #endif
-    if (!strcmp(hreq->method, "GET"))
+    const char *content_type = z_HTTP_header_lookup(hreq->headers,
+                                                    "Content-Type");
+    /*
+      SRU GET: allow any content type.
+      SRU POST: we support "application/x-www-form-urlencoded";
+      not  "multipart/form-data" .
+    */
+    if (!strcmp(hreq->method, "GET") 
+        ||
+        (!strcmp(hreq->method, "POST") 
+         && content_type &&
+         !yaz_strcmp_del("application/x-www-form-urlencoded",
+                         content_type, "; ")
+            )
+        )
     {
         char *db = "Default";
         const char *p0 = hreq->path, *p1;
@@ -289,6 +332,8 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
             memcpy (db, p0, p1 - p0);
             db[p1 - p0] = '\0';
         }
+        if (!strcmp(hreq->method, "POST"))
+            p1 = hreq->content_buf;
         yaz_uri_array(p1, decode, &uri_name, &uri_val);
 #if HAVE_XML2
         if (uri_name)
@@ -509,6 +554,20 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
     return 2;
 }
 
+Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
+{
+    Z_SRW_extra_record *res = (Z_SRW_extra_record *)
+        odr_malloc(o, sizeof(*res));
+    res->type = 1;
+    res->recordReviewCode = 0;
+    res->recordReviewNote = 0;
+    res->recordId = 0;
+    res->nonDupRecordId = 0;
+    res->recordLockStatus = 0;
+    res->recordOldVersion = 0;
+    return res;
+}
+
 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
 {
     Z_SRW_PDU *sr = (Z_SRW_PDU *) odr_malloc(o, sizeof(*o));
@@ -544,6 +603,7 @@ Z_SRW_PDU *yaz_srw_get(ODR o, int which)
         sr->u.response->diagnostics = 0;
         sr->u.response->num_diagnostics = 0;
         sr->u.response->nextRecordPosition = 0;
+        sr->u.response->extra_records = 0;
         break;
     case Z_SRW_explain_request:
         sr->u.explain_request = (Z_SRW_explainRequest *)
@@ -563,6 +623,7 @@ Z_SRW_PDU *yaz_srw_get(ODR o, int which)
             Z_SRW_recordPacking_string;
         sr->u.explain_response->diagnostics = 0;
         sr->u.explain_response->num_diagnostics = 0;
+        sr->u.explain_response->extra_record = 0;
         break;
     case Z_SRW_scan_request:
         sr->u.scan_request = (Z_SRW_scanRequest *)
@@ -577,16 +638,46 @@ Z_SRW_PDU *yaz_srw_get(ODR o, int which)
     case Z_SRW_scan_response:
         sr->u.scan_response = (Z_SRW_scanResponse *)
             odr_malloc(o, sizeof(*sr->u.scan_response));
-        sr->u.scan_response->terms = 0;
-        sr->u.scan_response->num_terms = 0;
-        sr->u.scan_response->diagnostics = 0;
-        sr->u.scan_response->num_diagnostics = 0;
+       sr->u.scan_response->terms = 0;
+       sr->u.scan_response->num_terms = 0;
+       sr->u.scan_response->diagnostics = 0;
+       sr->u.scan_response->num_diagnostics = 0;
+    case Z_SRW_update_request:
+        sr->u.update_request = (Z_SRW_updateRequest *)
+            odr_malloc(o, sizeof(*sr->u.update_request));
+       sr->u.update_request->database = 0;
+       sr->u.update_request->stylesheet = 0;
+        sr->u.update_request->record.recordSchema = 0;
+        sr->u.update_request->record.recordPacking = Z_SRW_recordPacking_XML;
+       sr->u.update_request->recordId = 0;
+       sr->u.update_request->recordVersion = 0;
+       sr->u.update_request->recordOldVersion = 0;
+        sr->u.update_request->record.recordData_buf = 0;
+        sr->u.update_request->record.recordData_len = 0;
+        sr->u.update_request->extra_record = 0;
+        sr->u.update_request->extraRequestData = 0;
+       sr->u.request->database = 0;
+        break;
+    case Z_SRW_update_response:
+        sr->u.update_response = (Z_SRW_updateResponse *)
+            odr_malloc(o, sizeof(*sr->u.update_response));
+       sr->u.update_response->operationStatus = 0;
+       sr->u.update_response->recordId = 0;
+       sr->u.update_response->recordVersion = 0;
+       sr->u.update_response->recordChecksum = 0;
+       sr->u.update_response->record.recordData_buf = 0;
+       sr->u.update_response->record.recordData_len = 0;
+       sr->u.update_response->record.recordSchema = 0;
+       sr->u.update_response->record.recordPacking =
+           Z_SRW_recordPacking_XML;
+        sr->u.update_response->extra_record = 0;
+        sr->u.update_response->extraResponseData = 0;
+       sr->u.update_response->diagnostics = 0;
+       sr->u.update_response->num_diagnostics = 0;
     }
     return sr;
 }
 
-
-
 /* bib1:srw */
 static int srw_bib1_map[] = {
     1, 1,
@@ -694,7 +785,7 @@ static int srw_bib1_map[] = {
     219, 1,  /* bad map */
     220, 1,  /* bad map */
     221, 1,  /* bad map */
-    222, 1,  /* bad map */
+    222, 3,
     223, 1,  /* bad map */
     224, 1,  /* bad map */
     225, 1,  /* bad map */