2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.64 2007-09-07 17:41:47 mike Exp $
9 * \brief Implements SRW/SRU utilities.
14 #include <yaz/yaz-iconv.h>
16 static int hex_digit (int ch)
18 if (ch >= '0' && ch <= '9')
20 else if (ch >= 'a' && ch <= 'f')
22 else if (ch >= 'A' && ch <= 'F')
27 void encode_uri_char(char *dst, char ch)
31 /* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */
32 else if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
33 (ch >= '0' && ch <= '9') || strchr("-_.!~*'(|)", ch))
41 sprintf(dst+1, "%02X", (unsigned char ) ch);
45 static void yaz_array_to_uri_ex(char **path, ODR o, char **name, char **value,
46 const char *extra_args)
48 size_t i, szp = 0, sz = extra_args ? 1+strlen(extra_args) : 1;
49 for(i = 0; name[i]; i++)
50 sz += strlen(name[i]) + 3 + strlen(value[i]) * 3;
51 *path = (char *) odr_malloc(o, sz);
53 for(i = 0; name[i]; i++)
58 ilen = strlen(name[i]);
59 memcpy(*path+szp, name[i], ilen);
62 for (j = 0; value[i][j]; j++)
66 encode_uri_char(vstr, value[i][j]);
68 memcpy(*path+szp, vstr, vlen);
76 memcpy(*path + szp, extra_args, strlen(extra_args));
77 szp += strlen(extra_args);
82 void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
84 yaz_array_to_uri_ex(path, o, name, value, 0);
87 int yaz_uri_array(const char *path, ODR o, char ***name, char ***val)
97 while ((cp = strchr(cp, '&')))
102 *name = (char **) odr_malloc(o, no * sizeof(char*));
103 *val = (char **) odr_malloc(o, no * sizeof(char*));
105 for (no = 0; *path; no++)
107 const char *p1 = strchr(path, '=');
113 (*name)[no] = (char *) odr_malloc(o, (p1-path)+1);
114 memcpy((*name)[no], path, p1-path);
115 (*name)[no][p1-path] = '\0';
118 p1 = strchr(path, '&');
120 p1 = strlen(path) + path;
121 (*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1);
122 while (*path && *path != '&')
129 else if (*path == '%' && path[1] && path[2])
131 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
147 char *yaz_uri_val(const char *path, const char *name, ODR o)
149 size_t nlen = strlen(name);
153 while (path && *path)
155 const char *p1 = strchr(path, '=');
158 if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
164 p1 = strchr(path, '&');
166 p1 = strlen(path) + path;
167 ret = (char *) odr_malloc(o, p1 - path + 1);
168 while (*path && *path != '&')
175 else if (*path == '%' && path[1] && path[2])
177 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
186 path = strchr(p1, '&');
193 static int yaz_base64decode(const char *in, char *out)
195 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
196 "abcdefghijklmnopqrstuvwxyz0123456789+/";
198 int len = strlen(in);
205 if (!(p = strchr(map, in[0])))
209 if (!(p = strchr(map, in[1])))
213 *(out++) = i0 << 2 | i1 >> 4;
217 if (!(p = strchr(map, in[2])))
221 *(out++) = i1 << 4 | i2 >> 2;
225 if (!(p = strchr(map, in[3])))
229 *(out++) = i2 << 6 | i3;
239 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
241 const char *content_type = z_HTTP_header_lookup(hres->headers,
245 if (!yaz_strcmp_del("text/xml", content_type, "; "))
247 if (!yaz_strcmp_del("application/xml", content_type, "; "))
254 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
255 * parameters. Added by SH.
257 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
258 char *username, char *password, ODR decode)
260 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
263 sr->username = username;
265 sr->password = password;
270 char ubuf[256] = "", pbuf[256] = "", *p;
271 if (strncmp(basic, "Basic ", 6))
275 if (!len || len > 256)
277 olen = yaz_base64decode(basic, out);
278 /* Format of out should be username:password at this point */
280 if ((p = strchr(ubuf, ':'))) {
286 sr->username = odr_strdup(decode, ubuf);
288 sr->password = odr_strdup(decode, pbuf);
292 void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp)
294 const char *v = yaz_uri_val(path, name, o);
296 *intp = odr_intdup(o, atoi(v));
299 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
300 const char *uri, const char *message,
303 d->uri = odr_strdup(o, uri);
305 d->message = odr_strdup(o, message);
309 d->details = odr_strdup(o, details);
314 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
315 int code, const char *details)
319 sprintf(uri, "info:srw/diagnostic/1/%d", code);
320 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
323 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
324 int *num, const char *uri,
325 const char *message, const char *details)
327 Z_SRW_diagnostic *d_new;
328 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
330 memcpy (d_new, *d, *num *sizeof(**d));
333 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
337 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
338 int *num, int code, const char *addinfo)
342 sprintf(uri, "info:srw/diagnostic/1/%d", code);
343 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
347 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
348 int *num, int code, const char *addinfo)
352 sprintf(uri, "info:srw/diagnostic/12/%d", code);
353 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
357 static void grab_charset(ODR o, const char *content_type, char **charset)
361 const char *charset_p = 0;
362 if (content_type && (charset_p = strstr(content_type, "; charset=")))
366 while (i < 20 && charset_p[i] &&
367 !strchr("; \n\r", charset_p[i]))
369 *charset = (char*) odr_malloc(o, i+1);
370 memcpy(*charset, charset_p, i);
371 (*charset)[i] = '\0';
376 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
377 Z_SOAP **soap_package, ODR decode, char **charset)
379 if (!strcmp(hreq->method, "POST"))
381 const char *content_type = z_HTTP_header_lookup(hreq->headers,
384 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
385 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
386 !yaz_strcmp_del("text/plain", content_type, "; ")))
388 char *db = "Default";
389 const char *p0 = hreq->path, *p1;
392 static Z_SOAP_Handler soap_handlers[4] = {
394 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
395 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
396 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
403 p1 = strchr(p0, '?');
405 p1 = p0 + strlen(p0);
408 db = (char*) odr_malloc(decode, p1 - p0 + 1);
409 memcpy (db, p0, p1 - p0);
413 grab_charset(decode, content_type, charset);
415 ret = z_soap_codec(decode, soap_package,
416 &hreq->content_buf, &hreq->content_len,
418 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
420 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
422 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
423 (*srw_pdu)->u.request->database == 0)
424 (*srw_pdu)->u.request->database = db;
426 if ((*srw_pdu)->which == Z_SRW_explain_request &&
427 (*srw_pdu)->u.explain_request->database == 0)
428 (*srw_pdu)->u.explain_request->database = db;
430 if ((*srw_pdu)->which == Z_SRW_scan_request &&
431 (*srw_pdu)->u.scan_request->database == 0)
432 (*srw_pdu)->u.scan_request->database = db;
434 if ((*srw_pdu)->which == Z_SRW_update_request &&
435 (*srw_pdu)->u.update_request->database == 0)
436 (*srw_pdu)->u.update_request->database = db;
446 static int yaz_sru_decode_integer(ODR odr, const char *pname,
447 const char *valstr, int **valp,
448 Z_SRW_diagnostic **diag, int *num_diag,
454 if (sscanf(valstr, "%d", &ival) != 1)
456 yaz_add_srw_diagnostic(odr, diag, num_diag,
457 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
460 if (min_value >= 0 && ival < min_value)
462 yaz_add_srw_diagnostic(odr, diag, num_diag,
463 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
466 *valp = odr_intdup(odr, ival);
471 http://www.loc.gov/z3950/agency/zing/srw/service.html
473 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
474 Z_SOAP **soap_package, ODR decode, char **charset,
475 Z_SRW_diagnostic **diag, int *num_diag)
478 static Z_SOAP_Handler soap_handlers[2] = {
479 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
483 const char *content_type = z_HTTP_header_lookup(hreq->headers,
487 SRU GET: ignore content type.
488 SRU POST: we support "application/x-www-form-urlencoded";
489 not "multipart/form-data" .
491 if (!strcmp(hreq->method, "GET")
493 (!strcmp(hreq->method, "POST") && content_type &&
494 !yaz_strcmp_del("application/x-www-form-urlencoded",
495 content_type, "; ")))
497 char *db = "Default";
498 const char *p0 = hreq->path, *p1;
500 const char *operation = 0;
507 char *stylesheet = 0;
508 char *scanClause = 0;
509 char *pScanClause = 0;
510 char *recordXPath = 0;
511 char *recordSchema = 0;
512 char *recordPacking = "xml"; /* xml packing is default for SRU */
513 char *maximumRecords = 0;
514 char *startRecord = 0;
515 char *maximumTerms = 0;
516 char *responsePosition = 0;
517 char *extraRequestData = 0;
522 grab_charset(decode, content_type, charset);
523 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
528 p1 = strchr(p0, '?');
530 p1 = p0 + strlen(p0);
533 db = (char*) odr_malloc(decode, p1 - p0 + 1);
534 memcpy (db, p0, p1 - p0);
537 if (!strcmp(hreq->method, "POST"))
538 p1 = hreq->content_buf;
539 yaz_uri_array(p1, decode, &uri_name, &uri_val);
544 for (i = 0; uri_name[i]; i++)
546 char *n = uri_name[i];
547 char *v = uri_val[i];
548 if (!strcmp(n, "query"))
550 else if (!strcmp(n, "x-pquery"))
552 else if (!strcmp(n, "x-username"))
554 else if (!strcmp(n, "x-password"))
556 else if (!strcmp(n, "operation"))
558 else if (!strcmp(n, "stylesheet"))
560 else if (!strcmp(n, "sortKeys"))
562 else if (!strcmp(n, "recordXPath"))
564 else if (!strcmp(n, "recordSchema"))
566 else if (!strcmp(n, "recordPacking"))
568 else if (!strcmp(n, "version"))
570 else if (!strcmp(n, "scanClause"))
572 else if (!strcmp(n, "x-pScanClause"))
574 else if (!strcmp(n, "maximumRecords"))
576 else if (!strcmp(n, "startRecord"))
578 else if (!strcmp(n, "maximumTerms"))
580 else if (!strcmp(n, "responsePosition"))
581 responsePosition = v;
582 else if (!strcmp(n, "extraRequestData"))
583 extraRequestData = v;
585 yaz_add_srw_diagnostic(decode, diag, num_diag,
586 YAZ_SRW_UNSUPP_PARAMETER, n);
592 yaz_add_srw_diagnostic(
593 decode, diag, num_diag,
594 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
598 version = yaz_negotiate_sru_version(version);
601 { /* negotiation failed. */
602 yaz_add_srw_diagnostic(decode, diag, num_diag,
603 YAZ_SRW_UNSUPP_VERSION, "1.2");
610 yaz_add_srw_diagnostic(
611 decode, diag, num_diag,
612 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
613 operation = "explain";
615 if (!strcmp(operation, "searchRetrieve"))
617 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
619 sr->srw_version = version;
621 yaz_srw_decodeauth(sr, hreq, username, password, decode);
624 sr->u.request->query_type = Z_SRW_query_type_cql;
625 sr->u.request->query.cql = query;
629 sr->u.request->query_type = Z_SRW_query_type_pqf;
630 sr->u.request->query.pqf = pQuery;
633 yaz_add_srw_diagnostic(
634 decode, diag, num_diag,
635 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
639 sr->u.request->sort_type = Z_SRW_sort_type_sort;
640 sr->u.request->sort.sortKeys = sortKeys;
642 sr->u.request->recordXPath = recordXPath;
643 sr->u.request->recordSchema = recordSchema;
644 sr->u.request->recordPacking = recordPacking;
645 sr->u.request->stylesheet = stylesheet;
647 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
648 &sr->u.request->maximumRecords,
651 yaz_sru_decode_integer(decode, "startRecord", startRecord,
652 &sr->u.request->startRecord,
655 sr->u.request->database = db;
657 (*soap_package) = (Z_SOAP *)
658 odr_malloc(decode, sizeof(**soap_package));
659 (*soap_package)->which = Z_SOAP_generic;
661 (*soap_package)->u.generic = (Z_SOAP_Generic *)
662 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
664 (*soap_package)->u.generic->p = sr;
665 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
666 (*soap_package)->u.generic->no = 0;
668 (*soap_package)->ns = "SRU";
672 else if (!strcmp(operation, "explain"))
674 /* Transfer SRU explain parameters to common struct */
675 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
676 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
678 sr->srw_version = version;
679 yaz_srw_decodeauth(sr, hreq, username, password, decode);
681 sr->u.explain_request->recordPacking = recordPacking;
682 sr->u.explain_request->database = db;
684 sr->u.explain_request->stylesheet = stylesheet;
686 (*soap_package) = (Z_SOAP *)
687 odr_malloc(decode, sizeof(**soap_package));
688 (*soap_package)->which = Z_SOAP_generic;
690 (*soap_package)->u.generic = (Z_SOAP_Generic *)
691 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
693 (*soap_package)->u.generic->p = sr;
694 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
695 (*soap_package)->u.generic->no = 0;
697 (*soap_package)->ns = "SRU";
701 else if (!strcmp(operation, "scan"))
703 /* Transfer SRU scan parameters to common struct */
704 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
705 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
707 sr->srw_version = version;
709 yaz_srw_decodeauth(sr, hreq, username, password, decode);
713 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
714 sr->u.scan_request->scanClause.cql = scanClause;
716 else if (pScanClause)
718 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
719 sr->u.scan_request->scanClause.pqf = pScanClause;
722 yaz_add_srw_diagnostic(
723 decode, diag, num_diag,
724 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
725 sr->u.scan_request->database = db;
727 yaz_sru_decode_integer(decode, "maximumTerms",
729 &sr->u.scan_request->maximumTerms,
732 yaz_sru_decode_integer(decode, "responsePosition",
734 &sr->u.scan_request->responsePosition,
737 sr->u.scan_request->stylesheet = stylesheet;
739 (*soap_package) = (Z_SOAP *)
740 odr_malloc(decode, sizeof(**soap_package));
741 (*soap_package)->which = Z_SOAP_generic;
743 (*soap_package)->u.generic = (Z_SOAP_Generic *)
744 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
746 (*soap_package)->u.generic->p = sr;
747 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
748 (*soap_package)->u.generic->no = 0;
750 (*soap_package)->ns = "SRU";
756 /* unsupported operation ... */
757 /* Act as if we received a explain request and throw diagnostic. */
759 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
761 sr->srw_version = version;
763 sr->u.explain_request->recordPacking = recordPacking;
764 sr->u.explain_request->database = db;
766 sr->u.explain_request->stylesheet = stylesheet;
768 (*soap_package) = (Z_SOAP *)
769 odr_malloc(decode, sizeof(**soap_package));
770 (*soap_package)->which = Z_SOAP_generic;
772 (*soap_package)->u.generic = (Z_SOAP_Generic *)
773 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
775 (*soap_package)->u.generic->p = sr;
776 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
777 (*soap_package)->u.generic->no = 0;
779 (*soap_package)->ns = "SRU";
781 yaz_add_srw_diagnostic(decode, diag, num_diag,
782 YAZ_SRW_UNSUPP_OPERATION, operation);
791 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
793 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
794 odr_malloc(o, sizeof(*res));
796 res->extraRecordData_buf = 0;
797 res->extraRecordData_len = 0;
798 res->recordIdentifier = 0;
803 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
805 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
808 for (i = 0; i<n; i++)
810 res[i].recordSchema = 0;
811 res[i].recordPacking = Z_SRW_recordPacking_string;
812 res[i].recordData_buf = 0;
813 res[i].recordData_len = 0;
814 res[i].recordPosition = 0;
819 Z_SRW_record *yaz_srw_get_record(ODR o)
821 return yaz_srw_get_records(o, 1);
824 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
826 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
827 p->srw_version = odr_strdup(o, version);
834 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
836 return yaz_srw_get_core_ver(o, "1.1");
839 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
841 return yaz_srw_get_pdu(o, which, "1.1");
844 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
846 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
851 case Z_SRW_searchRetrieve_request:
852 sr->u.request = (Z_SRW_searchRetrieveRequest *)
853 odr_malloc(o, sizeof(*sr->u.request));
854 sr->u.request->query_type = Z_SRW_query_type_cql;
855 sr->u.request->query.cql = 0;
856 sr->u.request->sort_type = Z_SRW_sort_type_none;
857 sr->u.request->sort.none = 0;
858 sr->u.request->startRecord = 0;
859 sr->u.request->maximumRecords = 0;
860 sr->u.request->recordSchema = 0;
861 sr->u.request->recordPacking = 0;
862 sr->u.request->recordXPath = 0;
863 sr->u.request->database = 0;
864 sr->u.request->resultSetTTL = 0;
865 sr->u.request->stylesheet = 0;
867 case Z_SRW_searchRetrieve_response:
868 sr->u.response = (Z_SRW_searchRetrieveResponse *)
869 odr_malloc(o, sizeof(*sr->u.response));
870 sr->u.response->numberOfRecords = 0;
871 sr->u.response->resultSetId = 0;
872 sr->u.response->resultSetIdleTime = 0;
873 sr->u.response->records = 0;
874 sr->u.response->num_records = 0;
875 sr->u.response->diagnostics = 0;
876 sr->u.response->num_diagnostics = 0;
877 sr->u.response->nextRecordPosition = 0;
878 sr->u.response->extra_records = 0;
880 case Z_SRW_explain_request:
881 sr->u.explain_request = (Z_SRW_explainRequest *)
882 odr_malloc(o, sizeof(*sr->u.explain_request));
883 sr->u.explain_request->recordPacking = 0;
884 sr->u.explain_request->database = 0;
885 sr->u.explain_request->stylesheet = 0;
887 case Z_SRW_explain_response:
888 sr->u.explain_response = (Z_SRW_explainResponse *)
889 odr_malloc(o, sizeof(*sr->u.explain_response));
890 sr->u.explain_response->record.recordData_buf = 0;
891 sr->u.explain_response->record.recordData_len = 0;
892 sr->u.explain_response->record.recordSchema = 0;
893 sr->u.explain_response->record.recordPosition = 0;
894 sr->u.explain_response->record.recordPacking =
895 Z_SRW_recordPacking_string;
896 sr->u.explain_response->diagnostics = 0;
897 sr->u.explain_response->num_diagnostics = 0;
898 sr->u.explain_response->extra_record = 0;
900 case Z_SRW_scan_request:
901 sr->u.scan_request = (Z_SRW_scanRequest *)
902 odr_malloc(o, sizeof(*sr->u.scan_request));
903 sr->u.scan_request->database = 0;
904 sr->u.scan_request->stylesheet = 0;
905 sr->u.scan_request->maximumTerms = 0;
906 sr->u.scan_request->responsePosition = 0;
907 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
908 sr->u.scan_request->scanClause.cql = 0;
910 case Z_SRW_scan_response:
911 sr->u.scan_response = (Z_SRW_scanResponse *)
912 odr_malloc(o, sizeof(*sr->u.scan_response));
913 sr->u.scan_response->terms = 0;
914 sr->u.scan_response->num_terms = 0;
915 sr->u.scan_response->diagnostics = 0;
916 sr->u.scan_response->num_diagnostics = 0;
918 case Z_SRW_update_request:
919 sr->u.update_request = (Z_SRW_updateRequest *)
920 odr_malloc(o, sizeof(*sr->u.update_request));
921 sr->u.update_request->database = 0;
922 sr->u.update_request->stylesheet = 0;
923 sr->u.update_request->record = 0;
924 sr->u.update_request->recordId = 0;
925 sr->u.update_request->recordVersions = 0;
926 sr->u.update_request->num_recordVersions = 0;
927 sr->u.update_request->extra_record = 0;
928 sr->u.update_request->extraRequestData_buf = 0;
929 sr->u.update_request->extraRequestData_len = 0;
930 sr->u.request->database = 0;
932 case Z_SRW_update_response:
933 sr->u.update_response = (Z_SRW_updateResponse *)
934 odr_malloc(o, sizeof(*sr->u.update_response));
935 sr->u.update_response->operationStatus = 0;
936 sr->u.update_response->recordId = 0;
937 sr->u.update_response->recordVersions = 0;
938 sr->u.update_response->num_recordVersions = 0;
939 sr->u.update_response->record = 0;
940 sr->u.update_response->extra_record = 0;
941 sr->u.update_response->extraResponseData_buf = 0;
942 sr->u.update_response->extraResponseData_len = 0;
943 sr->u.update_response->diagnostics = 0;
944 sr->u.update_response->num_diagnostics = 0;
950 static int bib1_srw_map[] = {
960 108, 10, /* Malformed query : Syntax error */
990 100, 1, /* bad map */
1038 205, 1, /* bad map */
1039 206, 1, /* bad map */
1041 208, 1, /* bad map */
1052 218, 1, /* bad map */
1053 219, 1, /* bad map */
1054 220, 1, /* bad map */
1055 221, 1, /* bad map */
1057 223, 1, /* bad map */
1058 224, 1, /* bad map */
1059 225, 1, /* bad map */
1060 226, 1, /* bad map */
1062 228, 1, /* bad map */
1067 233, 1, /* bad map */
1068 234, 1, /* bad map */
1074 240, 1, /* bad map */
1075 241, 1, /* bad map */
1077 243, 1, /* bad map */
1082 1001, 1, /* bad map */
1083 1002, 1, /* bad map */
1084 1003, 1, /* bad map */
1085 1004, 1, /* bad map */
1086 1005, 1, /* bad map */
1087 1006, 1, /* bad map */
1120 * This array contains overrides for when the first occurrence of a
1121 * particular SRW error in the array above does not correspond with
1122 * the best back-translation of that SRW error.
1124 static int srw_bib1_map[] = {
1126 /* No doubt there are many more */
1131 int yaz_diag_bib1_to_srw (int code)
1133 const int *p = bib1_srw_map;
1143 int yaz_diag_srw_to_bib1(int code)
1145 /* Check explicit reverse-map first */
1146 const int *p = srw_bib1_map;
1154 /* Fall back on reverse lookup in main map */
1165 static void add_val_int(ODR o, char **name, char **value, int *i,
1166 char *a_name, int *val)
1171 value[*i] = (char *) odr_malloc(o, 30);
1172 sprintf(value[*i], "%d", *val);
1177 static void add_val_str(ODR o, char **name, char **value, int *i,
1178 char *a_name, char *val)
1188 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1189 char **name, char **value)
1192 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1193 name[i] = "operation";
1194 switch(srw_pdu->which)
1196 case Z_SRW_searchRetrieve_request:
1197 value[i++] = "searchRetrieve";
1198 switch(srw_pdu->u.request->query_type)
1200 case Z_SRW_query_type_cql:
1201 add_val_str(encode, name, value, &i, "query",
1202 srw_pdu->u.request->query.cql);
1204 case Z_SRW_query_type_pqf:
1205 add_val_str(encode, name, value, &i, "x-pquery",
1206 srw_pdu->u.request->query.pqf);
1208 case Z_SRW_query_type_xcql:
1209 add_val_str(encode, name, value, &i, "x-cql",
1210 srw_pdu->u.request->query.xcql);
1213 switch(srw_pdu->u.request->sort_type)
1215 case Z_SRW_sort_type_none:
1217 case Z_SRW_sort_type_sort:
1218 add_val_str(encode, name, value, &i, "sortKeys",
1219 srw_pdu->u.request->sort.sortKeys);
1222 add_val_int(encode, name, value, &i, "startRecord",
1223 srw_pdu->u.request->startRecord);
1224 add_val_int(encode, name, value, &i, "maximumRecords",
1225 srw_pdu->u.request->maximumRecords);
1226 add_val_str(encode, name, value, &i, "recordSchema",
1227 srw_pdu->u.request->recordSchema);
1228 add_val_str(encode, name, value, &i, "recordPacking",
1229 srw_pdu->u.request->recordPacking);
1230 add_val_str(encode, name, value, &i, "recordXPath",
1231 srw_pdu->u.request->recordXPath);
1232 add_val_str(encode, name, value, &i, "stylesheet",
1233 srw_pdu->u.request->stylesheet);
1234 add_val_int(encode, name, value, &i, "resultSetTTL",
1235 srw_pdu->u.request->resultSetTTL);
1237 case Z_SRW_explain_request:
1238 value[i++] = "explain";
1239 add_val_str(encode, name, value, &i, "stylesheet",
1240 srw_pdu->u.explain_request->stylesheet);
1242 case Z_SRW_scan_request:
1243 value[i++] = "scan";
1245 switch(srw_pdu->u.scan_request->query_type)
1247 case Z_SRW_query_type_cql:
1248 add_val_str(encode, name, value, &i, "scanClause",
1249 srw_pdu->u.scan_request->scanClause.cql);
1251 case Z_SRW_query_type_pqf:
1252 add_val_str(encode, name, value, &i, "x-pScanClause",
1253 srw_pdu->u.scan_request->scanClause.pqf);
1255 case Z_SRW_query_type_xcql:
1256 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1257 srw_pdu->u.scan_request->scanClause.xcql);
1260 add_val_int(encode, name, value, &i, "responsePosition",
1261 srw_pdu->u.scan_request->responsePosition);
1262 add_val_int(encode, name, value, &i, "maximumTerms",
1263 srw_pdu->u.scan_request->maximumTerms);
1264 add_val_str(encode, name, value, &i, "stylesheet",
1265 srw_pdu->u.scan_request->stylesheet);
1267 case Z_SRW_update_request:
1268 value[i++] = "update";
1277 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1278 ODR encode, const char *charset)
1280 char *name[30], *value[30]; /* definite upper limit for SRU params */
1284 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1285 srw_pdu->username, srw_pdu->password);
1286 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1288 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1290 hreq->method = "GET";
1293 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4
1294 +(srw_pdu->extra_args ? strlen(srw_pdu->extra_args) : 0));
1296 sprintf(path, "%s?%s", hreq->path, uri_args);
1299 z_HTTP_header_add_content_type(encode, &hreq->headers,
1300 "text/xml", charset);
1304 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1305 ODR encode, const char *charset)
1307 char *name[30], *value[30]; /* definite upper limit for SRU params */
1310 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1311 srw_pdu->username, srw_pdu->password);
1312 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1315 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1317 hreq->method = "POST";
1319 hreq->content_buf = uri_args;
1320 hreq->content_len = strlen(uri_args);
1322 z_HTTP_header_add_content_type(encode, &hreq->headers,
1323 "application/x-www-form-urlencoded",
1328 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1329 ODR odr, const char *charset)
1331 Z_SOAP_Handler handlers[3] = {
1333 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1334 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1338 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1340 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1341 srw_pdu->username, srw_pdu->password);
1342 z_HTTP_header_add_content_type(odr,
1344 "text/xml", charset);
1346 z_HTTP_header_add(odr, &hreq->headers,
1347 "SOAPAction", "\"\"");
1348 p->which = Z_SOAP_generic;
1349 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1350 p->u.generic->no = 0;
1351 p->u.generic->ns = 0;
1352 p->u.generic->p = srw_pdu;
1353 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1356 if (srw_pdu->which == Z_SRW_update_request ||
1357 srw_pdu->which == Z_SRW_update_response)
1358 p->u.generic->no = 1; /* second handler */
1360 return z_soap_codec_enc(odr, &p,
1362 &hreq->content_len, handlers,
1366 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1368 Z_SRW_recordVersion *ver
1369 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1371 for ( i=0; i < num; ++i ){
1372 ver[i].versionType = 0;
1373 ver[i].versionValue = 0;
1378 const char *yaz_srw_pack_to_str(int pack)
1382 case Z_SRW_recordPacking_string:
1384 case Z_SRW_recordPacking_XML:
1386 case Z_SRW_recordPacking_URL:
1392 int yaz_srw_str_to_pack(const char *str)
1394 if (!yaz_matchstr(str, "string"))
1395 return Z_SRW_recordPacking_string;
1396 if (!yaz_matchstr(str, "xml"))
1397 return Z_SRW_recordPacking_XML;
1398 if (!yaz_matchstr(str, "url"))
1399 return Z_SRW_recordPacking_URL;
1406 * indent-tabs-mode: nil
1408 * vim: shiftwidth=4 tabstop=8 expandtab