1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2008 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SRW/SRU utilities.
12 #include <yaz/yaz-iconv.h>
14 static int hex_digit (int ch)
16 if (ch >= '0' && ch <= '9')
18 else if (ch >= 'a' && ch <= 'f')
20 else if (ch >= 'A' && ch <= 'F')
25 void encode_uri_char(char *dst, char ch)
29 /* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */
30 else if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
31 (ch >= '0' && ch <= '9') || strchr("-_.!~*'(|)", ch))
39 sprintf(dst+1, "%02X", (unsigned char ) ch);
43 static void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
45 size_t i, szp = 0, sz = 1;
46 for(i = 0; name[i]; i++)
47 sz += strlen(name[i]) + 3 + strlen(value[i]) * 3;
48 *path = (char *) odr_malloc(o, sz);
50 for(i = 0; name[i]; i++)
55 ilen = strlen(name[i]);
56 memcpy(*path+szp, name[i], ilen);
59 for (j = 0; value[i][j]; j++)
63 encode_uri_char(vstr, value[i][j]);
65 memcpy(*path+szp, vstr, vlen);
72 int yaz_uri_to_array(const char *path, ODR o, char ***name, char ***val)
82 while ((cp = strchr(cp, '&')))
87 *name = (char **) odr_malloc(o, no * sizeof(char*));
88 *val = (char **) odr_malloc(o, no * sizeof(char*));
90 for (no = 0; *path; no++)
92 const char *p1 = strchr(path, '=');
98 (*name)[no] = (char *) odr_malloc(o, (p1-path)+1);
99 memcpy((*name)[no], path, p1-path);
100 (*name)[no][p1-path] = '\0';
103 p1 = strchr(path, '&');
105 p1 = strlen(path) + path;
106 (*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1);
107 while (*path && *path != '&')
114 else if (*path == '%' && path[1] && path[2])
116 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
132 char *yaz_uri_val(const char *path, const char *name, ODR o)
134 size_t nlen = strlen(name);
138 while (path && *path)
140 const char *p1 = strchr(path, '=');
143 if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
149 p1 = strchr(path, '&');
151 p1 = strlen(path) + path;
152 ret = (char *) odr_malloc(o, p1 - path + 1);
153 while (*path && *path != '&')
160 else if (*path == '%' && path[1] && path[2])
162 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
171 path = strchr(p1, '&');
178 static int yaz_base64decode(const char *in, char *out)
180 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
181 "abcdefghijklmnopqrstuvwxyz0123456789+/";
183 int len = strlen(in);
190 if (!(p = strchr(map, in[0])))
194 if (!(p = strchr(map, in[1])))
198 *(out++) = i0 << 2 | i1 >> 4;
202 if (!(p = strchr(map, in[2])))
206 *(out++) = i1 << 4 | i2 >> 2;
210 if (!(p = strchr(map, in[3])))
214 *(out++) = i2 << 6 | i3;
224 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
226 const char *content_type = z_HTTP_header_lookup(hres->headers,
230 if (!yaz_strcmp_del("text/xml", content_type, "; "))
232 if (!yaz_strcmp_del("application/xml", content_type, "; "))
239 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
240 * parameters. Added by SH.
242 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
243 char *username, char *password, ODR decode)
245 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
248 sr->username = username;
250 sr->password = password;
255 char ubuf[256] = "", pbuf[256] = "", *p;
256 if (strncmp(basic, "Basic ", 6))
260 if (!len || len > 256)
262 olen = yaz_base64decode(basic, out);
263 /* Format of out should be username:password at this point */
265 if ((p = strchr(ubuf, ':'))) {
271 sr->username = odr_strdup(decode, ubuf);
273 sr->password = odr_strdup(decode, pbuf);
277 void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp)
279 const char *v = yaz_uri_val(path, name, o);
281 *intp = odr_intdup(o, atoi(v));
284 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
285 const char *uri, const char *message,
288 d->uri = odr_strdup(o, uri);
290 d->message = odr_strdup(o, message);
294 d->details = odr_strdup(o, details);
299 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
300 int code, const char *details)
304 sprintf(uri, "info:srw/diagnostic/1/%d", code);
305 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
308 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
309 int *num, const char *uri,
310 const char *message, const char *details)
312 Z_SRW_diagnostic *d_new;
313 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
315 memcpy (d_new, *d, *num *sizeof(**d));
318 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
322 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
323 int *num, int code, const char *addinfo)
327 sprintf(uri, "info:srw/diagnostic/1/%d", code);
328 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
332 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
333 int *num, int code, const char *addinfo)
337 sprintf(uri, "info:srw/diagnostic/12/%d", code);
338 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
342 static void grab_charset(ODR o, const char *content_type, char **charset)
346 const char *charset_p = 0;
347 if (content_type && (charset_p = strstr(content_type, "; charset=")))
351 while (i < 20 && charset_p[i] &&
352 !strchr("; \n\r", charset_p[i]))
354 *charset = (char*) odr_malloc(o, i+1);
355 memcpy(*charset, charset_p, i);
356 (*charset)[i] = '\0';
361 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
362 Z_SOAP **soap_package, ODR decode, char **charset)
364 if (!strcmp(hreq->method, "POST"))
366 const char *content_type = z_HTTP_header_lookup(hreq->headers,
369 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
370 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
371 !yaz_strcmp_del("text/plain", content_type, "; ")))
373 char *db = "Default";
374 const char *p0 = hreq->path, *p1;
377 static Z_SOAP_Handler soap_handlers[4] = {
379 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
380 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
381 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
388 p1 = strchr(p0, '?');
390 p1 = p0 + strlen(p0);
393 db = (char*) odr_malloc(decode, p1 - p0 + 1);
394 memcpy (db, p0, p1 - p0);
398 grab_charset(decode, content_type, charset);
400 ret = z_soap_codec(decode, soap_package,
401 &hreq->content_buf, &hreq->content_len,
403 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
405 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
407 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
408 (*srw_pdu)->u.request->database == 0)
409 (*srw_pdu)->u.request->database = db;
411 if ((*srw_pdu)->which == Z_SRW_explain_request &&
412 (*srw_pdu)->u.explain_request->database == 0)
413 (*srw_pdu)->u.explain_request->database = db;
415 if ((*srw_pdu)->which == Z_SRW_scan_request &&
416 (*srw_pdu)->u.scan_request->database == 0)
417 (*srw_pdu)->u.scan_request->database = db;
419 if ((*srw_pdu)->which == Z_SRW_update_request &&
420 (*srw_pdu)->u.update_request->database == 0)
421 (*srw_pdu)->u.update_request->database = db;
431 static int yaz_sru_decode_integer(ODR odr, const char *pname,
432 const char *valstr, int **valp,
433 Z_SRW_diagnostic **diag, int *num_diag,
439 if (sscanf(valstr, "%d", &ival) != 1)
441 yaz_add_srw_diagnostic(odr, diag, num_diag,
442 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
445 if (min_value >= 0 && ival < min_value)
447 yaz_add_srw_diagnostic(odr, diag, num_diag,
448 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
451 *valp = odr_intdup(odr, ival);
456 http://www.loc.gov/z3950/agency/zing/srw/service.html
458 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
459 Z_SOAP **soap_package, ODR decode, char **charset,
460 Z_SRW_diagnostic **diag, int *num_diag)
463 static Z_SOAP_Handler soap_handlers[2] = {
464 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
468 const char *content_type = z_HTTP_header_lookup(hreq->headers,
472 SRU GET: ignore content type.
473 SRU POST: we support "application/x-www-form-urlencoded";
474 not "multipart/form-data" .
476 if (!strcmp(hreq->method, "GET")
478 (!strcmp(hreq->method, "POST") && content_type &&
479 !yaz_strcmp_del("application/x-www-form-urlencoded",
480 content_type, "; ")))
482 char *db = "Default";
483 const char *p0 = hreq->path, *p1;
485 const char *operation = 0;
492 char *stylesheet = 0;
493 char *scanClause = 0;
494 char *pScanClause = 0;
495 char *recordXPath = 0;
496 char *recordSchema = 0;
497 char *recordPacking = "xml"; /* xml packing is default for SRU */
498 char *maximumRecords = 0;
499 char *startRecord = 0;
500 char *maximumTerms = 0;
501 char *responsePosition = 0;
502 char *extraRequestData = 0;
503 Z_SRW_extra_arg *extra_args = 0;
508 grab_charset(decode, content_type, charset);
509 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
514 p1 = strchr(p0, '?');
516 p1 = p0 + strlen(p0);
519 db = (char*) odr_malloc(decode, p1 - p0 + 1);
520 memcpy (db, p0, p1 - p0);
523 if (!strcmp(hreq->method, "POST"))
524 p1 = hreq->content_buf;
525 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
530 for (i = 0; uri_name[i]; i++)
532 char *n = uri_name[i];
533 char *v = uri_val[i];
534 if (!strcmp(n, "query"))
536 else if (!strcmp(n, "x-pquery"))
538 else if (!strcmp(n, "x-username"))
540 else if (!strcmp(n, "x-password"))
542 else if (!strcmp(n, "operation"))
544 else if (!strcmp(n, "stylesheet"))
546 else if (!strcmp(n, "sortKeys"))
548 else if (!strcmp(n, "recordXPath"))
550 else if (!strcmp(n, "recordSchema"))
552 else if (!strcmp(n, "recordPacking"))
554 else if (!strcmp(n, "version"))
556 else if (!strcmp(n, "scanClause"))
558 else if (!strcmp(n, "x-pScanClause"))
560 else if (!strcmp(n, "maximumRecords"))
562 else if (!strcmp(n, "startRecord"))
564 else if (!strcmp(n, "maximumTerms"))
566 else if (!strcmp(n, "responsePosition"))
567 responsePosition = v;
568 else if (!strcmp(n, "extraRequestData"))
569 extraRequestData = v;
570 else if (n[0] == 'x' && n[1] == '-')
572 Z_SRW_extra_arg **l = &extra_args;
575 *l = odr_malloc(decode, sizeof(**l));
576 (*l)->name = odr_strdup(decode, n);
577 (*l)->value = odr_strdup(decode, v);
581 yaz_add_srw_diagnostic(decode, diag, num_diag,
582 YAZ_SRW_UNSUPP_PARAMETER, n);
588 yaz_add_srw_diagnostic(
589 decode, diag, num_diag,
590 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
594 version = yaz_negotiate_sru_version(version);
597 { /* negotiation failed. */
598 yaz_add_srw_diagnostic(decode, diag, num_diag,
599 YAZ_SRW_UNSUPP_VERSION, "1.2");
606 yaz_add_srw_diagnostic(
607 decode, diag, num_diag,
608 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
609 operation = "explain";
611 if (!strcmp(operation, "searchRetrieve"))
613 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
615 sr->srw_version = version;
616 sr->extra_args = extra_args;
618 yaz_srw_decodeauth(sr, hreq, username, password, decode);
621 sr->u.request->query_type = Z_SRW_query_type_cql;
622 sr->u.request->query.cql = query;
626 sr->u.request->query_type = Z_SRW_query_type_pqf;
627 sr->u.request->query.pqf = pQuery;
630 yaz_add_srw_diagnostic(
631 decode, diag, num_diag,
632 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
636 sr->u.request->sort_type = Z_SRW_sort_type_sort;
637 sr->u.request->sort.sortKeys = sortKeys;
639 sr->u.request->recordXPath = recordXPath;
640 sr->u.request->recordSchema = recordSchema;
641 sr->u.request->recordPacking = recordPacking;
642 sr->u.request->stylesheet = stylesheet;
644 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
645 &sr->u.request->maximumRecords,
648 yaz_sru_decode_integer(decode, "startRecord", startRecord,
649 &sr->u.request->startRecord,
652 sr->u.request->database = db;
654 (*soap_package) = (Z_SOAP *)
655 odr_malloc(decode, sizeof(**soap_package));
656 (*soap_package)->which = Z_SOAP_generic;
658 (*soap_package)->u.generic = (Z_SOAP_Generic *)
659 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
661 (*soap_package)->u.generic->p = sr;
662 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
663 (*soap_package)->u.generic->no = 0;
665 (*soap_package)->ns = "SRU";
669 else if (!strcmp(operation, "explain"))
671 /* Transfer SRU explain parameters to common struct */
672 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
673 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
675 sr->srw_version = version;
676 sr->extra_args = extra_args;
677 yaz_srw_decodeauth(sr, hreq, username, password, decode);
679 sr->u.explain_request->recordPacking = recordPacking;
680 sr->u.explain_request->database = db;
682 sr->u.explain_request->stylesheet = stylesheet;
684 (*soap_package) = (Z_SOAP *)
685 odr_malloc(decode, sizeof(**soap_package));
686 (*soap_package)->which = Z_SOAP_generic;
688 (*soap_package)->u.generic = (Z_SOAP_Generic *)
689 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
691 (*soap_package)->u.generic->p = sr;
692 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
693 (*soap_package)->u.generic->no = 0;
695 (*soap_package)->ns = "SRU";
699 else if (!strcmp(operation, "scan"))
701 /* Transfer SRU scan parameters to common struct */
702 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
703 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
705 sr->srw_version = version;
706 sr->extra_args = extra_args;
708 yaz_srw_decodeauth(sr, hreq, username, password, decode);
712 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
713 sr->u.scan_request->scanClause.cql = scanClause;
715 else if (pScanClause)
717 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
718 sr->u.scan_request->scanClause.pqf = pScanClause;
721 yaz_add_srw_diagnostic(
722 decode, diag, num_diag,
723 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
724 sr->u.scan_request->database = db;
726 yaz_sru_decode_integer(decode, "maximumTerms",
728 &sr->u.scan_request->maximumTerms,
731 yaz_sru_decode_integer(decode, "responsePosition",
733 &sr->u.scan_request->responsePosition,
736 sr->u.scan_request->stylesheet = stylesheet;
738 (*soap_package) = (Z_SOAP *)
739 odr_malloc(decode, sizeof(**soap_package));
740 (*soap_package)->which = Z_SOAP_generic;
742 (*soap_package)->u.generic = (Z_SOAP_Generic *)
743 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
745 (*soap_package)->u.generic->p = sr;
746 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
747 (*soap_package)->u.generic->no = 0;
749 (*soap_package)->ns = "SRU";
755 /* unsupported operation ... */
756 /* Act as if we received a explain request and throw diagnostic. */
758 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
760 sr->srw_version = version;
762 sr->u.explain_request->recordPacking = recordPacking;
763 sr->u.explain_request->database = db;
765 sr->u.explain_request->stylesheet = stylesheet;
767 (*soap_package) = (Z_SOAP *)
768 odr_malloc(decode, sizeof(**soap_package));
769 (*soap_package)->which = Z_SOAP_generic;
771 (*soap_package)->u.generic = (Z_SOAP_Generic *)
772 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
774 (*soap_package)->u.generic->p = sr;
775 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
776 (*soap_package)->u.generic->no = 0;
778 (*soap_package)->ns = "SRU";
780 yaz_add_srw_diagnostic(decode, diag, num_diag,
781 YAZ_SRW_UNSUPP_OPERATION, operation);
790 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
792 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
793 odr_malloc(o, sizeof(*res));
795 res->extraRecordData_buf = 0;
796 res->extraRecordData_len = 0;
797 res->recordIdentifier = 0;
802 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
804 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
807 for (i = 0; i<n; i++)
809 res[i].recordSchema = 0;
810 res[i].recordPacking = Z_SRW_recordPacking_string;
811 res[i].recordData_buf = 0;
812 res[i].recordData_len = 0;
813 res[i].recordPosition = 0;
818 Z_SRW_record *yaz_srw_get_record(ODR o)
820 return yaz_srw_get_records(o, 1);
823 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
825 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
826 p->srw_version = odr_strdup(o, version);
833 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
835 return yaz_srw_get_core_ver(o, "1.1");
838 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
840 return yaz_srw_get_pdu(o, which, "1.1");
843 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
845 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
850 case Z_SRW_searchRetrieve_request:
851 sr->u.request = (Z_SRW_searchRetrieveRequest *)
852 odr_malloc(o, sizeof(*sr->u.request));
853 sr->u.request->query_type = Z_SRW_query_type_cql;
854 sr->u.request->query.cql = 0;
855 sr->u.request->sort_type = Z_SRW_sort_type_none;
856 sr->u.request->sort.none = 0;
857 sr->u.request->startRecord = 0;
858 sr->u.request->maximumRecords = 0;
859 sr->u.request->recordSchema = 0;
860 sr->u.request->recordPacking = 0;
861 sr->u.request->recordXPath = 0;
862 sr->u.request->database = 0;
863 sr->u.request->resultSetTTL = 0;
864 sr->u.request->stylesheet = 0;
866 case Z_SRW_searchRetrieve_response:
867 sr->u.response = (Z_SRW_searchRetrieveResponse *)
868 odr_malloc(o, sizeof(*sr->u.response));
869 sr->u.response->numberOfRecords = 0;
870 sr->u.response->resultSetId = 0;
871 sr->u.response->resultSetIdleTime = 0;
872 sr->u.response->records = 0;
873 sr->u.response->num_records = 0;
874 sr->u.response->diagnostics = 0;
875 sr->u.response->num_diagnostics = 0;
876 sr->u.response->nextRecordPosition = 0;
877 sr->u.response->extra_records = 0;
879 case Z_SRW_explain_request:
880 sr->u.explain_request = (Z_SRW_explainRequest *)
881 odr_malloc(o, sizeof(*sr->u.explain_request));
882 sr->u.explain_request->recordPacking = 0;
883 sr->u.explain_request->database = 0;
884 sr->u.explain_request->stylesheet = 0;
886 case Z_SRW_explain_response:
887 sr->u.explain_response = (Z_SRW_explainResponse *)
888 odr_malloc(o, sizeof(*sr->u.explain_response));
889 sr->u.explain_response->record.recordData_buf = 0;
890 sr->u.explain_response->record.recordData_len = 0;
891 sr->u.explain_response->record.recordSchema = 0;
892 sr->u.explain_response->record.recordPosition = 0;
893 sr->u.explain_response->record.recordPacking =
894 Z_SRW_recordPacking_string;
895 sr->u.explain_response->diagnostics = 0;
896 sr->u.explain_response->num_diagnostics = 0;
897 sr->u.explain_response->extra_record = 0;
899 case Z_SRW_scan_request:
900 sr->u.scan_request = (Z_SRW_scanRequest *)
901 odr_malloc(o, sizeof(*sr->u.scan_request));
902 sr->u.scan_request->database = 0;
903 sr->u.scan_request->stylesheet = 0;
904 sr->u.scan_request->maximumTerms = 0;
905 sr->u.scan_request->responsePosition = 0;
906 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
907 sr->u.scan_request->scanClause.cql = 0;
909 case Z_SRW_scan_response:
910 sr->u.scan_response = (Z_SRW_scanResponse *)
911 odr_malloc(o, sizeof(*sr->u.scan_response));
912 sr->u.scan_response->terms = 0;
913 sr->u.scan_response->num_terms = 0;
914 sr->u.scan_response->diagnostics = 0;
915 sr->u.scan_response->num_diagnostics = 0;
917 case Z_SRW_update_request:
918 sr->u.update_request = (Z_SRW_updateRequest *)
919 odr_malloc(o, sizeof(*sr->u.update_request));
920 sr->u.update_request->database = 0;
921 sr->u.update_request->stylesheet = 0;
922 sr->u.update_request->record = 0;
923 sr->u.update_request->recordId = 0;
924 sr->u.update_request->recordVersions = 0;
925 sr->u.update_request->num_recordVersions = 0;
926 sr->u.update_request->extra_record = 0;
927 sr->u.update_request->extraRequestData_buf = 0;
928 sr->u.update_request->extraRequestData_len = 0;
929 sr->u.request->database = 0;
931 case Z_SRW_update_response:
932 sr->u.update_response = (Z_SRW_updateResponse *)
933 odr_malloc(o, sizeof(*sr->u.update_response));
934 sr->u.update_response->operationStatus = 0;
935 sr->u.update_response->recordId = 0;
936 sr->u.update_response->recordVersions = 0;
937 sr->u.update_response->num_recordVersions = 0;
938 sr->u.update_response->record = 0;
939 sr->u.update_response->extra_record = 0;
940 sr->u.update_response->extraResponseData_buf = 0;
941 sr->u.update_response->extraResponseData_len = 0;
942 sr->u.update_response->diagnostics = 0;
943 sr->u.update_response->num_diagnostics = 0;
949 static int bib1_srw_map[] = {
959 108, 10, /* Malformed query : Syntax error */
989 100, 1, /* bad map */
1037 205, 1, /* bad map */
1038 206, 1, /* bad map */
1040 208, 1, /* bad map */
1051 218, 1, /* bad map */
1052 219, 1, /* bad map */
1053 220, 1, /* bad map */
1054 221, 1, /* bad map */
1056 223, 1, /* bad map */
1057 224, 1, /* bad map */
1058 225, 1, /* bad map */
1059 226, 1, /* bad map */
1061 228, 1, /* bad map */
1066 233, 1, /* bad map */
1067 234, 1, /* bad map */
1073 240, 1, /* bad map */
1074 241, 1, /* bad map */
1076 243, 1, /* bad map */
1081 1001, 1, /* bad map */
1082 1002, 1, /* bad map */
1083 1003, 1, /* bad map */
1084 1004, 1, /* bad map */
1085 1005, 1, /* bad map */
1086 1006, 1, /* bad map */
1119 * This array contains overrides for when the first occurrence of a
1120 * particular SRW error in the array above does not correspond with
1121 * the best back-translation of that SRW error.
1123 static int srw_bib1_map[] = {
1125 /* No doubt there are many more */
1130 int yaz_diag_bib1_to_srw (int code)
1132 const int *p = bib1_srw_map;
1142 int yaz_diag_srw_to_bib1(int code)
1144 /* Check explicit reverse-map first */
1145 const int *p = srw_bib1_map;
1153 /* Fall back on reverse lookup in main map */
1164 static void add_val_int(ODR o, char **name, char **value, int *i,
1165 char *a_name, int *val)
1170 value[*i] = (char *) odr_malloc(o, 30);
1171 sprintf(value[*i], "%d", *val);
1176 static void add_val_str(ODR o, char **name, char **value, int *i,
1177 char *a_name, char *val)
1187 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1188 char **name, char **value, int max_names)
1191 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1192 name[i] = "operation";
1193 switch(srw_pdu->which)
1195 case Z_SRW_searchRetrieve_request:
1196 value[i++] = "searchRetrieve";
1197 switch(srw_pdu->u.request->query_type)
1199 case Z_SRW_query_type_cql:
1200 add_val_str(encode, name, value, &i, "query",
1201 srw_pdu->u.request->query.cql);
1203 case Z_SRW_query_type_pqf:
1204 add_val_str(encode, name, value, &i, "x-pquery",
1205 srw_pdu->u.request->query.pqf);
1207 case Z_SRW_query_type_xcql:
1208 add_val_str(encode, name, value, &i, "x-cql",
1209 srw_pdu->u.request->query.xcql);
1212 switch(srw_pdu->u.request->sort_type)
1214 case Z_SRW_sort_type_none:
1216 case Z_SRW_sort_type_sort:
1217 add_val_str(encode, name, value, &i, "sortKeys",
1218 srw_pdu->u.request->sort.sortKeys);
1221 add_val_int(encode, name, value, &i, "startRecord",
1222 srw_pdu->u.request->startRecord);
1223 add_val_int(encode, name, value, &i, "maximumRecords",
1224 srw_pdu->u.request->maximumRecords);
1225 add_val_str(encode, name, value, &i, "recordSchema",
1226 srw_pdu->u.request->recordSchema);
1227 add_val_str(encode, name, value, &i, "recordPacking",
1228 srw_pdu->u.request->recordPacking);
1229 add_val_str(encode, name, value, &i, "recordXPath",
1230 srw_pdu->u.request->recordXPath);
1231 add_val_str(encode, name, value, &i, "stylesheet",
1232 srw_pdu->u.request->stylesheet);
1233 add_val_int(encode, name, value, &i, "resultSetTTL",
1234 srw_pdu->u.request->resultSetTTL);
1236 case Z_SRW_explain_request:
1237 value[i++] = "explain";
1238 add_val_str(encode, name, value, &i, "stylesheet",
1239 srw_pdu->u.explain_request->stylesheet);
1241 case Z_SRW_scan_request:
1242 value[i++] = "scan";
1244 switch(srw_pdu->u.scan_request->query_type)
1246 case Z_SRW_query_type_cql:
1247 add_val_str(encode, name, value, &i, "scanClause",
1248 srw_pdu->u.scan_request->scanClause.cql);
1250 case Z_SRW_query_type_pqf:
1251 add_val_str(encode, name, value, &i, "x-pScanClause",
1252 srw_pdu->u.scan_request->scanClause.pqf);
1254 case Z_SRW_query_type_xcql:
1255 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1256 srw_pdu->u.scan_request->scanClause.xcql);
1259 add_val_int(encode, name, value, &i, "responsePosition",
1260 srw_pdu->u.scan_request->responsePosition);
1261 add_val_int(encode, name, value, &i, "maximumTerms",
1262 srw_pdu->u.scan_request->maximumTerms);
1263 add_val_str(encode, name, value, &i, "stylesheet",
1264 srw_pdu->u.scan_request->stylesheet);
1266 case Z_SRW_update_request:
1267 value[i++] = "update";
1272 if (srw_pdu->extra_args)
1274 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1275 for (; ea && i < max_names-1; ea = ea->next)
1278 value[i] = ea->value;
1287 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1288 ODR encode, const char *charset)
1290 char *name[30], *value[30]; /* definite upper limit for SRU params */
1294 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1295 srw_pdu->username, srw_pdu->password);
1296 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1298 yaz_array_to_uri(&uri_args, encode, name, value);
1300 hreq->method = "GET";
1303 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1305 sprintf(path, "%s?%s", hreq->path, uri_args);
1308 z_HTTP_header_add_content_type(encode, &hreq->headers,
1309 "text/xml", charset);
1313 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1314 ODR encode, const char *charset)
1316 char *name[30], *value[30]; /* definite upper limit for SRU params */
1319 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1320 srw_pdu->username, srw_pdu->password);
1321 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1324 yaz_array_to_uri(&uri_args, encode, name, value);
1326 hreq->method = "POST";
1328 hreq->content_buf = uri_args;
1329 hreq->content_len = strlen(uri_args);
1331 z_HTTP_header_add_content_type(encode, &hreq->headers,
1332 "application/x-www-form-urlencoded",
1337 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1338 ODR odr, const char *charset)
1340 Z_SOAP_Handler handlers[3] = {
1342 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1343 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1347 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1349 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1350 srw_pdu->username, srw_pdu->password);
1351 z_HTTP_header_add_content_type(odr,
1353 "text/xml", charset);
1355 z_HTTP_header_add(odr, &hreq->headers,
1356 "SOAPAction", "\"\"");
1357 p->which = Z_SOAP_generic;
1358 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1359 p->u.generic->no = 0;
1360 p->u.generic->ns = 0;
1361 p->u.generic->p = srw_pdu;
1362 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1365 if (srw_pdu->which == Z_SRW_update_request ||
1366 srw_pdu->which == Z_SRW_update_response)
1367 p->u.generic->no = 1; /* second handler */
1369 return z_soap_codec_enc(odr, &p,
1371 &hreq->content_len, handlers,
1375 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1377 Z_SRW_recordVersion *ver
1378 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1380 for ( i=0; i < num; ++i ){
1381 ver[i].versionType = 0;
1382 ver[i].versionValue = 0;
1387 const char *yaz_srw_pack_to_str(int pack)
1391 case Z_SRW_recordPacking_string:
1393 case Z_SRW_recordPacking_XML:
1395 case Z_SRW_recordPacking_URL:
1401 int yaz_srw_str_to_pack(const char *str)
1403 if (!yaz_matchstr(str, "string"))
1404 return Z_SRW_recordPacking_string;
1405 if (!yaz_matchstr(str, "xml"))
1406 return Z_SRW_recordPacking_XML;
1407 if (!yaz_matchstr(str, "url"))
1408 return Z_SRW_recordPacking_URL;
1412 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1418 Z_SRW_extra_arg **ea = &sr->extra_args;
1419 yaz_uri_to_array(extra_args, odr, &name, &val);
1423 *ea = odr_malloc(odr, sizeof(**ea));
1424 (*ea)->name = *name;
1425 (*ea)->value = *val;
1439 * indent-tabs-mode: nil
1441 * vim: shiftwidth=4 tabstop=8 expandtab