2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.65 2008-01-28 09:51:02 adam 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(char **path, ODR o, char **name, char **value)
47 size_t i, szp = 0, sz = 1;
48 for(i = 0; name[i]; i++)
49 sz += strlen(name[i]) + 3 + strlen(value[i]) * 3;
50 *path = (char *) odr_malloc(o, sz);
52 for(i = 0; name[i]; i++)
57 ilen = strlen(name[i]);
58 memcpy(*path+szp, name[i], ilen);
61 for (j = 0; value[i][j]; j++)
65 encode_uri_char(vstr, value[i][j]);
67 memcpy(*path+szp, vstr, vlen);
74 int yaz_uri_to_array(const char *path, ODR o, char ***name, char ***val)
84 while ((cp = strchr(cp, '&')))
89 *name = (char **) odr_malloc(o, no * sizeof(char*));
90 *val = (char **) odr_malloc(o, no * sizeof(char*));
92 for (no = 0; *path; no++)
94 const char *p1 = strchr(path, '=');
100 (*name)[no] = (char *) odr_malloc(o, (p1-path)+1);
101 memcpy((*name)[no], path, p1-path);
102 (*name)[no][p1-path] = '\0';
105 p1 = strchr(path, '&');
107 p1 = strlen(path) + path;
108 (*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1);
109 while (*path && *path != '&')
116 else if (*path == '%' && path[1] && path[2])
118 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
134 char *yaz_uri_val(const char *path, const char *name, ODR o)
136 size_t nlen = strlen(name);
140 while (path && *path)
142 const char *p1 = strchr(path, '=');
145 if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
151 p1 = strchr(path, '&');
153 p1 = strlen(path) + path;
154 ret = (char *) odr_malloc(o, p1 - path + 1);
155 while (*path && *path != '&')
162 else if (*path == '%' && path[1] && path[2])
164 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
173 path = strchr(p1, '&');
180 static int yaz_base64decode(const char *in, char *out)
182 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
183 "abcdefghijklmnopqrstuvwxyz0123456789+/";
185 int len = strlen(in);
192 if (!(p = strchr(map, in[0])))
196 if (!(p = strchr(map, in[1])))
200 *(out++) = i0 << 2 | i1 >> 4;
204 if (!(p = strchr(map, in[2])))
208 *(out++) = i1 << 4 | i2 >> 2;
212 if (!(p = strchr(map, in[3])))
216 *(out++) = i2 << 6 | i3;
226 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
228 const char *content_type = z_HTTP_header_lookup(hres->headers,
232 if (!yaz_strcmp_del("text/xml", content_type, "; "))
234 if (!yaz_strcmp_del("application/xml", content_type, "; "))
241 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
242 * parameters. Added by SH.
244 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
245 char *username, char *password, ODR decode)
247 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
250 sr->username = username;
252 sr->password = password;
257 char ubuf[256] = "", pbuf[256] = "", *p;
258 if (strncmp(basic, "Basic ", 6))
262 if (!len || len > 256)
264 olen = yaz_base64decode(basic, out);
265 /* Format of out should be username:password at this point */
267 if ((p = strchr(ubuf, ':'))) {
273 sr->username = odr_strdup(decode, ubuf);
275 sr->password = odr_strdup(decode, pbuf);
279 void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp)
281 const char *v = yaz_uri_val(path, name, o);
283 *intp = odr_intdup(o, atoi(v));
286 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
287 const char *uri, const char *message,
290 d->uri = odr_strdup(o, uri);
292 d->message = odr_strdup(o, message);
296 d->details = odr_strdup(o, details);
301 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
302 int code, const char *details)
306 sprintf(uri, "info:srw/diagnostic/1/%d", code);
307 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
310 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
311 int *num, const char *uri,
312 const char *message, const char *details)
314 Z_SRW_diagnostic *d_new;
315 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
317 memcpy (d_new, *d, *num *sizeof(**d));
320 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
324 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
325 int *num, int code, const char *addinfo)
329 sprintf(uri, "info:srw/diagnostic/1/%d", code);
330 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
334 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
335 int *num, int code, const char *addinfo)
339 sprintf(uri, "info:srw/diagnostic/12/%d", code);
340 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
344 static void grab_charset(ODR o, const char *content_type, char **charset)
348 const char *charset_p = 0;
349 if (content_type && (charset_p = strstr(content_type, "; charset=")))
353 while (i < 20 && charset_p[i] &&
354 !strchr("; \n\r", charset_p[i]))
356 *charset = (char*) odr_malloc(o, i+1);
357 memcpy(*charset, charset_p, i);
358 (*charset)[i] = '\0';
363 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
364 Z_SOAP **soap_package, ODR decode, char **charset)
366 if (!strcmp(hreq->method, "POST"))
368 const char *content_type = z_HTTP_header_lookup(hreq->headers,
371 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
372 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
373 !yaz_strcmp_del("text/plain", content_type, "; ")))
375 char *db = "Default";
376 const char *p0 = hreq->path, *p1;
379 static Z_SOAP_Handler soap_handlers[4] = {
381 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
382 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
383 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
390 p1 = strchr(p0, '?');
392 p1 = p0 + strlen(p0);
395 db = (char*) odr_malloc(decode, p1 - p0 + 1);
396 memcpy (db, p0, p1 - p0);
400 grab_charset(decode, content_type, charset);
402 ret = z_soap_codec(decode, soap_package,
403 &hreq->content_buf, &hreq->content_len,
405 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
407 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
409 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
410 (*srw_pdu)->u.request->database == 0)
411 (*srw_pdu)->u.request->database = db;
413 if ((*srw_pdu)->which == Z_SRW_explain_request &&
414 (*srw_pdu)->u.explain_request->database == 0)
415 (*srw_pdu)->u.explain_request->database = db;
417 if ((*srw_pdu)->which == Z_SRW_scan_request &&
418 (*srw_pdu)->u.scan_request->database == 0)
419 (*srw_pdu)->u.scan_request->database = db;
421 if ((*srw_pdu)->which == Z_SRW_update_request &&
422 (*srw_pdu)->u.update_request->database == 0)
423 (*srw_pdu)->u.update_request->database = db;
433 static int yaz_sru_decode_integer(ODR odr, const char *pname,
434 const char *valstr, int **valp,
435 Z_SRW_diagnostic **diag, int *num_diag,
441 if (sscanf(valstr, "%d", &ival) != 1)
443 yaz_add_srw_diagnostic(odr, diag, num_diag,
444 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
447 if (min_value >= 0 && ival < min_value)
449 yaz_add_srw_diagnostic(odr, diag, num_diag,
450 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
453 *valp = odr_intdup(odr, ival);
458 http://www.loc.gov/z3950/agency/zing/srw/service.html
460 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
461 Z_SOAP **soap_package, ODR decode, char **charset,
462 Z_SRW_diagnostic **diag, int *num_diag)
465 static Z_SOAP_Handler soap_handlers[2] = {
466 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
470 const char *content_type = z_HTTP_header_lookup(hreq->headers,
474 SRU GET: ignore content type.
475 SRU POST: we support "application/x-www-form-urlencoded";
476 not "multipart/form-data" .
478 if (!strcmp(hreq->method, "GET")
480 (!strcmp(hreq->method, "POST") && content_type &&
481 !yaz_strcmp_del("application/x-www-form-urlencoded",
482 content_type, "; ")))
484 char *db = "Default";
485 const char *p0 = hreq->path, *p1;
487 const char *operation = 0;
494 char *stylesheet = 0;
495 char *scanClause = 0;
496 char *pScanClause = 0;
497 char *recordXPath = 0;
498 char *recordSchema = 0;
499 char *recordPacking = "xml"; /* xml packing is default for SRU */
500 char *maximumRecords = 0;
501 char *startRecord = 0;
502 char *maximumTerms = 0;
503 char *responsePosition = 0;
504 char *extraRequestData = 0;
505 Z_SRW_extra_arg *extra_args = 0;
510 grab_charset(decode, content_type, charset);
511 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
516 p1 = strchr(p0, '?');
518 p1 = p0 + strlen(p0);
521 db = (char*) odr_malloc(decode, p1 - p0 + 1);
522 memcpy (db, p0, p1 - p0);
525 if (!strcmp(hreq->method, "POST"))
526 p1 = hreq->content_buf;
527 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
532 for (i = 0; uri_name[i]; i++)
534 char *n = uri_name[i];
535 char *v = uri_val[i];
536 if (!strcmp(n, "query"))
538 else if (!strcmp(n, "x-pquery"))
540 else if (!strcmp(n, "x-username"))
542 else if (!strcmp(n, "x-password"))
544 else if (!strcmp(n, "operation"))
546 else if (!strcmp(n, "stylesheet"))
548 else if (!strcmp(n, "sortKeys"))
550 else if (!strcmp(n, "recordXPath"))
552 else if (!strcmp(n, "recordSchema"))
554 else if (!strcmp(n, "recordPacking"))
556 else if (!strcmp(n, "version"))
558 else if (!strcmp(n, "scanClause"))
560 else if (!strcmp(n, "x-pScanClause"))
562 else if (!strcmp(n, "maximumRecords"))
564 else if (!strcmp(n, "startRecord"))
566 else if (!strcmp(n, "maximumTerms"))
568 else if (!strcmp(n, "responsePosition"))
569 responsePosition = v;
570 else if (!strcmp(n, "extraRequestData"))
571 extraRequestData = v;
572 else if (n[0] == 'x' && n[1] == '-')
574 Z_SRW_extra_arg **l = &extra_args;
577 *l = odr_malloc(decode, sizeof(**l));
578 (*l)->name = odr_strdup(decode, n);
579 (*l)->value = odr_strdup(decode, v);
583 yaz_add_srw_diagnostic(decode, diag, num_diag,
584 YAZ_SRW_UNSUPP_PARAMETER, n);
590 yaz_add_srw_diagnostic(
591 decode, diag, num_diag,
592 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
596 version = yaz_negotiate_sru_version(version);
599 { /* negotiation failed. */
600 yaz_add_srw_diagnostic(decode, diag, num_diag,
601 YAZ_SRW_UNSUPP_VERSION, "1.2");
608 yaz_add_srw_diagnostic(
609 decode, diag, num_diag,
610 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
611 operation = "explain";
613 if (!strcmp(operation, "searchRetrieve"))
615 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
617 sr->srw_version = version;
618 sr->extra_args = extra_args;
620 yaz_srw_decodeauth(sr, hreq, username, password, decode);
623 sr->u.request->query_type = Z_SRW_query_type_cql;
624 sr->u.request->query.cql = query;
628 sr->u.request->query_type = Z_SRW_query_type_pqf;
629 sr->u.request->query.pqf = pQuery;
632 yaz_add_srw_diagnostic(
633 decode, diag, num_diag,
634 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
638 sr->u.request->sort_type = Z_SRW_sort_type_sort;
639 sr->u.request->sort.sortKeys = sortKeys;
641 sr->u.request->recordXPath = recordXPath;
642 sr->u.request->recordSchema = recordSchema;
643 sr->u.request->recordPacking = recordPacking;
644 sr->u.request->stylesheet = stylesheet;
646 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
647 &sr->u.request->maximumRecords,
650 yaz_sru_decode_integer(decode, "startRecord", startRecord,
651 &sr->u.request->startRecord,
654 sr->u.request->database = db;
656 (*soap_package) = (Z_SOAP *)
657 odr_malloc(decode, sizeof(**soap_package));
658 (*soap_package)->which = Z_SOAP_generic;
660 (*soap_package)->u.generic = (Z_SOAP_Generic *)
661 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
663 (*soap_package)->u.generic->p = sr;
664 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
665 (*soap_package)->u.generic->no = 0;
667 (*soap_package)->ns = "SRU";
671 else if (!strcmp(operation, "explain"))
673 /* Transfer SRU explain parameters to common struct */
674 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
675 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
677 sr->srw_version = version;
678 sr->extra_args = extra_args;
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;
708 sr->extra_args = extra_args;
710 yaz_srw_decodeauth(sr, hreq, username, password, decode);
714 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
715 sr->u.scan_request->scanClause.cql = scanClause;
717 else if (pScanClause)
719 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
720 sr->u.scan_request->scanClause.pqf = pScanClause;
723 yaz_add_srw_diagnostic(
724 decode, diag, num_diag,
725 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
726 sr->u.scan_request->database = db;
728 yaz_sru_decode_integer(decode, "maximumTerms",
730 &sr->u.scan_request->maximumTerms,
733 yaz_sru_decode_integer(decode, "responsePosition",
735 &sr->u.scan_request->responsePosition,
738 sr->u.scan_request->stylesheet = stylesheet;
740 (*soap_package) = (Z_SOAP *)
741 odr_malloc(decode, sizeof(**soap_package));
742 (*soap_package)->which = Z_SOAP_generic;
744 (*soap_package)->u.generic = (Z_SOAP_Generic *)
745 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
747 (*soap_package)->u.generic->p = sr;
748 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
749 (*soap_package)->u.generic->no = 0;
751 (*soap_package)->ns = "SRU";
757 /* unsupported operation ... */
758 /* Act as if we received a explain request and throw diagnostic. */
760 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
762 sr->srw_version = version;
764 sr->u.explain_request->recordPacking = recordPacking;
765 sr->u.explain_request->database = db;
767 sr->u.explain_request->stylesheet = stylesheet;
769 (*soap_package) = (Z_SOAP *)
770 odr_malloc(decode, sizeof(**soap_package));
771 (*soap_package)->which = Z_SOAP_generic;
773 (*soap_package)->u.generic = (Z_SOAP_Generic *)
774 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
776 (*soap_package)->u.generic->p = sr;
777 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
778 (*soap_package)->u.generic->no = 0;
780 (*soap_package)->ns = "SRU";
782 yaz_add_srw_diagnostic(decode, diag, num_diag,
783 YAZ_SRW_UNSUPP_OPERATION, operation);
792 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
794 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
795 odr_malloc(o, sizeof(*res));
797 res->extraRecordData_buf = 0;
798 res->extraRecordData_len = 0;
799 res->recordIdentifier = 0;
804 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
806 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
809 for (i = 0; i<n; i++)
811 res[i].recordSchema = 0;
812 res[i].recordPacking = Z_SRW_recordPacking_string;
813 res[i].recordData_buf = 0;
814 res[i].recordData_len = 0;
815 res[i].recordPosition = 0;
820 Z_SRW_record *yaz_srw_get_record(ODR o)
822 return yaz_srw_get_records(o, 1);
825 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
827 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
828 p->srw_version = odr_strdup(o, version);
835 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
837 return yaz_srw_get_core_ver(o, "1.1");
840 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
842 return yaz_srw_get_pdu(o, which, "1.1");
845 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
847 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
852 case Z_SRW_searchRetrieve_request:
853 sr->u.request = (Z_SRW_searchRetrieveRequest *)
854 odr_malloc(o, sizeof(*sr->u.request));
855 sr->u.request->query_type = Z_SRW_query_type_cql;
856 sr->u.request->query.cql = 0;
857 sr->u.request->sort_type = Z_SRW_sort_type_none;
858 sr->u.request->sort.none = 0;
859 sr->u.request->startRecord = 0;
860 sr->u.request->maximumRecords = 0;
861 sr->u.request->recordSchema = 0;
862 sr->u.request->recordPacking = 0;
863 sr->u.request->recordXPath = 0;
864 sr->u.request->database = 0;
865 sr->u.request->resultSetTTL = 0;
866 sr->u.request->stylesheet = 0;
868 case Z_SRW_searchRetrieve_response:
869 sr->u.response = (Z_SRW_searchRetrieveResponse *)
870 odr_malloc(o, sizeof(*sr->u.response));
871 sr->u.response->numberOfRecords = 0;
872 sr->u.response->resultSetId = 0;
873 sr->u.response->resultSetIdleTime = 0;
874 sr->u.response->records = 0;
875 sr->u.response->num_records = 0;
876 sr->u.response->diagnostics = 0;
877 sr->u.response->num_diagnostics = 0;
878 sr->u.response->nextRecordPosition = 0;
879 sr->u.response->extra_records = 0;
881 case Z_SRW_explain_request:
882 sr->u.explain_request = (Z_SRW_explainRequest *)
883 odr_malloc(o, sizeof(*sr->u.explain_request));
884 sr->u.explain_request->recordPacking = 0;
885 sr->u.explain_request->database = 0;
886 sr->u.explain_request->stylesheet = 0;
888 case Z_SRW_explain_response:
889 sr->u.explain_response = (Z_SRW_explainResponse *)
890 odr_malloc(o, sizeof(*sr->u.explain_response));
891 sr->u.explain_response->record.recordData_buf = 0;
892 sr->u.explain_response->record.recordData_len = 0;
893 sr->u.explain_response->record.recordSchema = 0;
894 sr->u.explain_response->record.recordPosition = 0;
895 sr->u.explain_response->record.recordPacking =
896 Z_SRW_recordPacking_string;
897 sr->u.explain_response->diagnostics = 0;
898 sr->u.explain_response->num_diagnostics = 0;
899 sr->u.explain_response->extra_record = 0;
901 case Z_SRW_scan_request:
902 sr->u.scan_request = (Z_SRW_scanRequest *)
903 odr_malloc(o, sizeof(*sr->u.scan_request));
904 sr->u.scan_request->database = 0;
905 sr->u.scan_request->stylesheet = 0;
906 sr->u.scan_request->maximumTerms = 0;
907 sr->u.scan_request->responsePosition = 0;
908 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
909 sr->u.scan_request->scanClause.cql = 0;
911 case Z_SRW_scan_response:
912 sr->u.scan_response = (Z_SRW_scanResponse *)
913 odr_malloc(o, sizeof(*sr->u.scan_response));
914 sr->u.scan_response->terms = 0;
915 sr->u.scan_response->num_terms = 0;
916 sr->u.scan_response->diagnostics = 0;
917 sr->u.scan_response->num_diagnostics = 0;
919 case Z_SRW_update_request:
920 sr->u.update_request = (Z_SRW_updateRequest *)
921 odr_malloc(o, sizeof(*sr->u.update_request));
922 sr->u.update_request->database = 0;
923 sr->u.update_request->stylesheet = 0;
924 sr->u.update_request->record = 0;
925 sr->u.update_request->recordId = 0;
926 sr->u.update_request->recordVersions = 0;
927 sr->u.update_request->num_recordVersions = 0;
928 sr->u.update_request->extra_record = 0;
929 sr->u.update_request->extraRequestData_buf = 0;
930 sr->u.update_request->extraRequestData_len = 0;
931 sr->u.request->database = 0;
933 case Z_SRW_update_response:
934 sr->u.update_response = (Z_SRW_updateResponse *)
935 odr_malloc(o, sizeof(*sr->u.update_response));
936 sr->u.update_response->operationStatus = 0;
937 sr->u.update_response->recordId = 0;
938 sr->u.update_response->recordVersions = 0;
939 sr->u.update_response->num_recordVersions = 0;
940 sr->u.update_response->record = 0;
941 sr->u.update_response->extra_record = 0;
942 sr->u.update_response->extraResponseData_buf = 0;
943 sr->u.update_response->extraResponseData_len = 0;
944 sr->u.update_response->diagnostics = 0;
945 sr->u.update_response->num_diagnostics = 0;
951 static int bib1_srw_map[] = {
961 108, 10, /* Malformed query : Syntax error */
991 100, 1, /* bad map */
1039 205, 1, /* bad map */
1040 206, 1, /* bad map */
1042 208, 1, /* bad map */
1053 218, 1, /* bad map */
1054 219, 1, /* bad map */
1055 220, 1, /* bad map */
1056 221, 1, /* bad map */
1058 223, 1, /* bad map */
1059 224, 1, /* bad map */
1060 225, 1, /* bad map */
1061 226, 1, /* bad map */
1063 228, 1, /* bad map */
1068 233, 1, /* bad map */
1069 234, 1, /* bad map */
1075 240, 1, /* bad map */
1076 241, 1, /* bad map */
1078 243, 1, /* bad map */
1083 1001, 1, /* bad map */
1084 1002, 1, /* bad map */
1085 1003, 1, /* bad map */
1086 1004, 1, /* bad map */
1087 1005, 1, /* bad map */
1088 1006, 1, /* bad map */
1121 * This array contains overrides for when the first occurrence of a
1122 * particular SRW error in the array above does not correspond with
1123 * the best back-translation of that SRW error.
1125 static int srw_bib1_map[] = {
1127 /* No doubt there are many more */
1132 int yaz_diag_bib1_to_srw (int code)
1134 const int *p = bib1_srw_map;
1144 int yaz_diag_srw_to_bib1(int code)
1146 /* Check explicit reverse-map first */
1147 const int *p = srw_bib1_map;
1155 /* Fall back on reverse lookup in main map */
1166 static void add_val_int(ODR o, char **name, char **value, int *i,
1167 char *a_name, int *val)
1172 value[*i] = (char *) odr_malloc(o, 30);
1173 sprintf(value[*i], "%d", *val);
1178 static void add_val_str(ODR o, char **name, char **value, int *i,
1179 char *a_name, char *val)
1189 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1190 char **name, char **value, int max_names)
1193 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1194 name[i] = "operation";
1195 switch(srw_pdu->which)
1197 case Z_SRW_searchRetrieve_request:
1198 value[i++] = "searchRetrieve";
1199 switch(srw_pdu->u.request->query_type)
1201 case Z_SRW_query_type_cql:
1202 add_val_str(encode, name, value, &i, "query",
1203 srw_pdu->u.request->query.cql);
1205 case Z_SRW_query_type_pqf:
1206 add_val_str(encode, name, value, &i, "x-pquery",
1207 srw_pdu->u.request->query.pqf);
1209 case Z_SRW_query_type_xcql:
1210 add_val_str(encode, name, value, &i, "x-cql",
1211 srw_pdu->u.request->query.xcql);
1214 switch(srw_pdu->u.request->sort_type)
1216 case Z_SRW_sort_type_none:
1218 case Z_SRW_sort_type_sort:
1219 add_val_str(encode, name, value, &i, "sortKeys",
1220 srw_pdu->u.request->sort.sortKeys);
1223 add_val_int(encode, name, value, &i, "startRecord",
1224 srw_pdu->u.request->startRecord);
1225 add_val_int(encode, name, value, &i, "maximumRecords",
1226 srw_pdu->u.request->maximumRecords);
1227 add_val_str(encode, name, value, &i, "recordSchema",
1228 srw_pdu->u.request->recordSchema);
1229 add_val_str(encode, name, value, &i, "recordPacking",
1230 srw_pdu->u.request->recordPacking);
1231 add_val_str(encode, name, value, &i, "recordXPath",
1232 srw_pdu->u.request->recordXPath);
1233 add_val_str(encode, name, value, &i, "stylesheet",
1234 srw_pdu->u.request->stylesheet);
1235 add_val_int(encode, name, value, &i, "resultSetTTL",
1236 srw_pdu->u.request->resultSetTTL);
1238 case Z_SRW_explain_request:
1239 value[i++] = "explain";
1240 add_val_str(encode, name, value, &i, "stylesheet",
1241 srw_pdu->u.explain_request->stylesheet);
1243 case Z_SRW_scan_request:
1244 value[i++] = "scan";
1246 switch(srw_pdu->u.scan_request->query_type)
1248 case Z_SRW_query_type_cql:
1249 add_val_str(encode, name, value, &i, "scanClause",
1250 srw_pdu->u.scan_request->scanClause.cql);
1252 case Z_SRW_query_type_pqf:
1253 add_val_str(encode, name, value, &i, "x-pScanClause",
1254 srw_pdu->u.scan_request->scanClause.pqf);
1256 case Z_SRW_query_type_xcql:
1257 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1258 srw_pdu->u.scan_request->scanClause.xcql);
1261 add_val_int(encode, name, value, &i, "responsePosition",
1262 srw_pdu->u.scan_request->responsePosition);
1263 add_val_int(encode, name, value, &i, "maximumTerms",
1264 srw_pdu->u.scan_request->maximumTerms);
1265 add_val_str(encode, name, value, &i, "stylesheet",
1266 srw_pdu->u.scan_request->stylesheet);
1268 case Z_SRW_update_request:
1269 value[i++] = "update";
1274 if (srw_pdu->extra_args)
1276 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1277 for (; ea && i < max_names-1; ea = ea->next)
1280 value[i] = ea->value;
1289 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1290 ODR encode, const char *charset)
1292 char *name[30], *value[30]; /* definite upper limit for SRU params */
1296 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1297 srw_pdu->username, srw_pdu->password);
1298 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1300 yaz_array_to_uri(&uri_args, encode, name, value);
1302 hreq->method = "GET";
1305 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1307 sprintf(path, "%s?%s", hreq->path, uri_args);
1310 z_HTTP_header_add_content_type(encode, &hreq->headers,
1311 "text/xml", charset);
1315 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1316 ODR encode, const char *charset)
1318 char *name[30], *value[30]; /* definite upper limit for SRU params */
1321 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1322 srw_pdu->username, srw_pdu->password);
1323 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1326 yaz_array_to_uri(&uri_args, encode, name, value);
1328 hreq->method = "POST";
1330 hreq->content_buf = uri_args;
1331 hreq->content_len = strlen(uri_args);
1333 z_HTTP_header_add_content_type(encode, &hreq->headers,
1334 "application/x-www-form-urlencoded",
1339 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1340 ODR odr, const char *charset)
1342 Z_SOAP_Handler handlers[3] = {
1344 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1345 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1349 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1351 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1352 srw_pdu->username, srw_pdu->password);
1353 z_HTTP_header_add_content_type(odr,
1355 "text/xml", charset);
1357 z_HTTP_header_add(odr, &hreq->headers,
1358 "SOAPAction", "\"\"");
1359 p->which = Z_SOAP_generic;
1360 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1361 p->u.generic->no = 0;
1362 p->u.generic->ns = 0;
1363 p->u.generic->p = srw_pdu;
1364 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1367 if (srw_pdu->which == Z_SRW_update_request ||
1368 srw_pdu->which == Z_SRW_update_response)
1369 p->u.generic->no = 1; /* second handler */
1371 return z_soap_codec_enc(odr, &p,
1373 &hreq->content_len, handlers,
1377 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1379 Z_SRW_recordVersion *ver
1380 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1382 for ( i=0; i < num; ++i ){
1383 ver[i].versionType = 0;
1384 ver[i].versionValue = 0;
1389 const char *yaz_srw_pack_to_str(int pack)
1393 case Z_SRW_recordPacking_string:
1395 case Z_SRW_recordPacking_XML:
1397 case Z_SRW_recordPacking_URL:
1403 int yaz_srw_str_to_pack(const char *str)
1405 if (!yaz_matchstr(str, "string"))
1406 return Z_SRW_recordPacking_string;
1407 if (!yaz_matchstr(str, "xml"))
1408 return Z_SRW_recordPacking_XML;
1409 if (!yaz_matchstr(str, "url"))
1410 return Z_SRW_recordPacking_URL;
1414 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1420 Z_SRW_extra_arg **ea = &sr->extra_args;
1421 yaz_uri_to_array(extra_args, odr, &name, &val);
1425 *ea = odr_malloc(odr, sizeof(**ea));
1426 (*ea)->name = *name;
1427 (*ea)->value = *val;
1441 * indent-tabs-mode: nil
1443 * vim: shiftwidth=4 tabstop=8 expandtab