1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2009 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SRW/SRU utilities.
12 #include <yaz/matchstr.h>
13 #include <yaz/yaz-iconv.h>
15 static int hex_digit (int ch)
17 if (ch >= '0' && ch <= '9')
19 else if (ch >= 'a' && ch <= 'f')
21 else if (ch >= 'A' && ch <= 'F')
26 void encode_uri_char(char *dst, char ch)
30 /* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */
31 else if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
32 (ch >= '0' && ch <= '9') || strchr("-_.!~*'(|)", ch))
40 sprintf(dst+1, "%02X", (unsigned char ) ch);
44 static void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
46 size_t i, szp = 0, sz = 1;
47 for(i = 0; name[i]; i++)
48 sz += strlen(name[i]) + 3 + strlen(value[i]) * 3;
49 *path = (char *) odr_malloc(o, sz);
51 for(i = 0; name[i]; i++)
56 ilen = strlen(name[i]);
57 memcpy(*path+szp, name[i], ilen);
60 for (j = 0; value[i][j]; j++)
64 encode_uri_char(vstr, value[i][j]);
66 memcpy(*path+szp, vstr, vlen);
73 int yaz_uri_to_array(const char *path, ODR o, char ***name, char ***val)
83 while ((cp = strchr(cp, '&')))
88 *name = (char **) odr_malloc(o, no * sizeof(char*));
89 *val = (char **) odr_malloc(o, no * sizeof(char*));
91 for (no = 0; *path; no++)
93 const char *p1 = strchr(path, '=');
99 (*name)[no] = (char *) odr_malloc(o, (p1-path)+1);
100 memcpy((*name)[no], path, p1-path);
101 (*name)[no][p1-path] = '\0';
104 p1 = strchr(path, '&');
106 p1 = strlen(path) + path;
107 (*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1);
108 while (*path && *path != '&')
115 else if (*path == '%' && path[1] && path[2])
117 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
133 char *yaz_uri_val(const char *path, const char *name, ODR o)
135 size_t nlen = strlen(name);
139 while (path && *path)
141 const char *p1 = strchr(path, '=');
144 if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
150 p1 = strchr(path, '&');
152 p1 = strlen(path) + path;
153 ret = (char *) odr_malloc(o, p1 - path + 1);
154 while (*path && *path != '&')
161 else if (*path == '%' && path[1] && path[2])
163 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
172 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;
227 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
229 const char *content_type = z_HTTP_header_lookup(hres->headers,
233 if (!yaz_strcmp_del("text/xml", content_type, "; "))
235 if (!yaz_strcmp_del("application/xml", content_type, "; "))
242 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
243 * parameters. Added by SH.
246 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
247 char *username, char *password, ODR decode)
249 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
252 sr->username = username;
254 sr->password = password;
259 char ubuf[256] = "", pbuf[256] = "", *p;
260 if (strncmp(basic, "Basic ", 6))
264 if (!len || len > 256)
266 olen = yaz_base64decode(basic, out);
267 /* Format of out should be username:password at this point */
269 if ((p = strchr(ubuf, ':'))) {
275 sr->username = odr_strdup(decode, ubuf);
277 sr->password = odr_strdup(decode, pbuf);
282 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
284 const char *v = yaz_uri_val(path, name, o);
286 *intp = odr_intdup(o, atoi(v));
289 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
290 const char *uri, const char *message,
293 d->uri = odr_strdup(o, uri);
295 d->message = odr_strdup(o, message);
299 d->details = odr_strdup(o, details);
304 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
305 int code, const char *details)
309 sprintf(uri, "info:srw/diagnostic/1/%d", code);
310 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
313 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
314 int *num, const char *uri,
315 const char *message, const char *details)
317 Z_SRW_diagnostic *d_new;
318 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
320 memcpy (d_new, *d, *num *sizeof(**d));
323 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
327 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
328 int *num, int code, const char *addinfo)
332 sprintf(uri, "info:srw/diagnostic/1/%d", code);
333 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
337 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
338 int *num, int code, const char *addinfo)
342 sprintf(uri, "info:srw/diagnostic/12/%d", code);
343 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
347 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
348 int code, const char *details)
350 const char *message = yaz_diag_srw_str(code);
353 len += strlen(message);
355 len += strlen(details);
357 record->recordData_buf = (char *) odr_malloc(o, len);
359 sprintf(record->recordData_buf, "<diagnostic "
360 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
361 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
363 sprintf(record->recordData_buf + strlen(record->recordData_buf),
364 " <details>%s</details>\n", details);
366 sprintf(record->recordData_buf + strlen(record->recordData_buf),
367 " <message>%s</message>\n", message);
368 sprintf(record->recordData_buf + strlen(record->recordData_buf),
370 record->recordData_len = strlen(record->recordData_buf);
371 record->recordPosition = odr_intdup(o, pos);
372 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
375 static void grab_charset(ODR o, const char *content_type, char **charset)
379 const char *charset_p = 0;
380 if (content_type && (charset_p = strstr(content_type, "; charset=")))
384 while (i < 20 && charset_p[i] &&
385 !strchr("; \n\r", charset_p[i]))
387 *charset = (char*) odr_malloc(o, i+1);
388 memcpy(*charset, charset_p, i);
389 (*charset)[i] = '\0';
394 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
395 Z_SOAP **soap_package, ODR decode, char **charset)
397 if (!strcmp(hreq->method, "POST"))
399 const char *content_type = z_HTTP_header_lookup(hreq->headers,
402 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
403 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
404 !yaz_strcmp_del("text/plain", content_type, "; ")))
406 char *db = "Default";
407 const char *p0 = hreq->path, *p1;
410 static Z_SOAP_Handler soap_handlers[4] = {
412 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
413 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
414 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
421 p1 = strchr(p0, '?');
423 p1 = p0 + strlen(p0);
426 db = (char*) odr_malloc(decode, p1 - p0 + 1);
427 memcpy (db, p0, p1 - p0);
431 grab_charset(decode, content_type, charset);
433 ret = z_soap_codec(decode, soap_package,
434 &hreq->content_buf, &hreq->content_len,
436 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
438 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
440 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
441 (*srw_pdu)->u.request->database == 0)
442 (*srw_pdu)->u.request->database = db;
444 if ((*srw_pdu)->which == Z_SRW_explain_request &&
445 (*srw_pdu)->u.explain_request->database == 0)
446 (*srw_pdu)->u.explain_request->database = db;
448 if ((*srw_pdu)->which == Z_SRW_scan_request &&
449 (*srw_pdu)->u.scan_request->database == 0)
450 (*srw_pdu)->u.scan_request->database = db;
452 if ((*srw_pdu)->which == Z_SRW_update_request &&
453 (*srw_pdu)->u.update_request->database == 0)
454 (*srw_pdu)->u.update_request->database = db;
465 static int yaz_sru_decode_integer(ODR odr, const char *pname,
466 const char *valstr, Odr_int **valp,
467 Z_SRW_diagnostic **diag, int *num_diag,
473 if (sscanf(valstr, "%d", &ival) != 1)
475 yaz_add_srw_diagnostic(odr, diag, num_diag,
476 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
479 if (min_value >= 0 && ival < min_value)
481 yaz_add_srw_diagnostic(odr, diag, num_diag,
482 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
485 *valp = odr_intdup(odr, ival);
491 http://www.loc.gov/z3950/agency/zing/srw/service.html
493 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
494 Z_SOAP **soap_package, ODR decode, char **charset,
495 Z_SRW_diagnostic **diag, int *num_diag)
498 static Z_SOAP_Handler soap_handlers[2] = {
499 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
503 const char *content_type = z_HTTP_header_lookup(hreq->headers,
507 SRU GET: ignore content type.
508 SRU POST: we support "application/x-www-form-urlencoded";
509 not "multipart/form-data" .
511 if (!strcmp(hreq->method, "GET")
513 (!strcmp(hreq->method, "POST") && content_type &&
514 !yaz_strcmp_del("application/x-www-form-urlencoded",
515 content_type, "; ")))
517 char *db = "Default";
518 const char *p0 = hreq->path, *p1;
520 const char *operation = 0;
527 char *stylesheet = 0;
528 char *scanClause = 0;
529 char *pScanClause = 0;
530 char *recordXPath = 0;
531 char *recordSchema = 0;
532 char *recordPacking = "xml"; /* xml packing is default for SRU */
533 char *maximumRecords = 0;
534 char *startRecord = 0;
535 char *maximumTerms = 0;
536 char *responsePosition = 0;
537 char *extraRequestData = 0;
538 Z_SRW_extra_arg *extra_args = 0;
543 grab_charset(decode, content_type, charset);
544 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
549 p1 = strchr(p0, '?');
551 p1 = p0 + strlen(p0);
554 db = (char*) odr_malloc(decode, p1 - p0 + 1);
555 memcpy (db, p0, p1 - p0);
558 if (!strcmp(hreq->method, "POST"))
559 p1 = hreq->content_buf;
560 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
565 for (i = 0; uri_name[i]; i++)
567 char *n = uri_name[i];
568 char *v = uri_val[i];
569 if (!strcmp(n, "query"))
571 else if (!strcmp(n, "x-pquery"))
573 else if (!strcmp(n, "x-username"))
575 else if (!strcmp(n, "x-password"))
577 else if (!strcmp(n, "operation"))
579 else if (!strcmp(n, "stylesheet"))
581 else if (!strcmp(n, "sortKeys"))
583 else if (!strcmp(n, "recordXPath"))
585 else if (!strcmp(n, "recordSchema"))
587 else if (!strcmp(n, "recordPacking"))
589 else if (!strcmp(n, "version"))
591 else if (!strcmp(n, "scanClause"))
593 else if (!strcmp(n, "x-pScanClause"))
595 else if (!strcmp(n, "maximumRecords"))
597 else if (!strcmp(n, "startRecord"))
599 else if (!strcmp(n, "maximumTerms"))
601 else if (!strcmp(n, "responsePosition"))
602 responsePosition = v;
603 else if (!strcmp(n, "extraRequestData"))
604 extraRequestData = v;
605 else if (n[0] == 'x' && n[1] == '-')
607 Z_SRW_extra_arg **l = &extra_args;
610 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
611 (*l)->name = odr_strdup(decode, n);
612 (*l)->value = odr_strdup(decode, v);
616 yaz_add_srw_diagnostic(decode, diag, num_diag,
617 YAZ_SRW_UNSUPP_PARAMETER, n);
623 yaz_add_srw_diagnostic(
624 decode, diag, num_diag,
625 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
629 version = yaz_negotiate_sru_version(version);
632 { /* negotiation failed. */
633 yaz_add_srw_diagnostic(decode, diag, num_diag,
634 YAZ_SRW_UNSUPP_VERSION, "1.2");
641 yaz_add_srw_diagnostic(
642 decode, diag, num_diag,
643 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
644 operation = "explain";
646 if (!strcmp(operation, "searchRetrieve"))
648 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
650 sr->srw_version = version;
651 sr->extra_args = extra_args;
653 yaz_srw_decodeauth(sr, hreq, username, password, decode);
656 sr->u.request->query_type = Z_SRW_query_type_cql;
657 sr->u.request->query.cql = query;
661 sr->u.request->query_type = Z_SRW_query_type_pqf;
662 sr->u.request->query.pqf = pQuery;
665 yaz_add_srw_diagnostic(
666 decode, diag, num_diag,
667 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
671 sr->u.request->sort_type = Z_SRW_sort_type_sort;
672 sr->u.request->sort.sortKeys = sortKeys;
674 sr->u.request->recordXPath = recordXPath;
675 sr->u.request->recordSchema = recordSchema;
676 sr->u.request->recordPacking = recordPacking;
677 sr->u.request->stylesheet = stylesheet;
679 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
680 &sr->u.request->maximumRecords,
683 yaz_sru_decode_integer(decode, "startRecord", startRecord,
684 &sr->u.request->startRecord,
687 sr->u.request->database = db;
689 (*soap_package) = (Z_SOAP *)
690 odr_malloc(decode, sizeof(**soap_package));
691 (*soap_package)->which = Z_SOAP_generic;
693 (*soap_package)->u.generic = (Z_SOAP_Generic *)
694 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
696 (*soap_package)->u.generic->p = sr;
697 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
698 (*soap_package)->u.generic->no = 0;
700 (*soap_package)->ns = "SRU";
704 else if (!strcmp(operation, "explain"))
706 /* Transfer SRU explain parameters to common struct */
707 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
708 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
710 sr->srw_version = version;
711 sr->extra_args = extra_args;
712 yaz_srw_decodeauth(sr, hreq, username, password, decode);
714 sr->u.explain_request->recordPacking = recordPacking;
715 sr->u.explain_request->database = db;
717 sr->u.explain_request->stylesheet = stylesheet;
719 (*soap_package) = (Z_SOAP *)
720 odr_malloc(decode, sizeof(**soap_package));
721 (*soap_package)->which = Z_SOAP_generic;
723 (*soap_package)->u.generic = (Z_SOAP_Generic *)
724 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
726 (*soap_package)->u.generic->p = sr;
727 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
728 (*soap_package)->u.generic->no = 0;
730 (*soap_package)->ns = "SRU";
734 else if (!strcmp(operation, "scan"))
736 /* Transfer SRU scan parameters to common struct */
737 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
738 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
740 sr->srw_version = version;
741 sr->extra_args = extra_args;
743 yaz_srw_decodeauth(sr, hreq, username, password, decode);
747 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
748 sr->u.scan_request->scanClause.cql = scanClause;
750 else if (pScanClause)
752 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
753 sr->u.scan_request->scanClause.pqf = pScanClause;
756 yaz_add_srw_diagnostic(
757 decode, diag, num_diag,
758 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
759 sr->u.scan_request->database = db;
761 yaz_sru_decode_integer(decode, "maximumTerms",
763 &sr->u.scan_request->maximumTerms,
766 yaz_sru_decode_integer(decode, "responsePosition",
768 &sr->u.scan_request->responsePosition,
771 sr->u.scan_request->stylesheet = stylesheet;
773 (*soap_package) = (Z_SOAP *)
774 odr_malloc(decode, sizeof(**soap_package));
775 (*soap_package)->which = Z_SOAP_generic;
777 (*soap_package)->u.generic = (Z_SOAP_Generic *)
778 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
780 (*soap_package)->u.generic->p = sr;
781 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
782 (*soap_package)->u.generic->no = 0;
784 (*soap_package)->ns = "SRU";
790 /* unsupported operation ... */
791 /* Act as if we received a explain request and throw diagnostic. */
793 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
795 sr->srw_version = version;
797 sr->u.explain_request->recordPacking = recordPacking;
798 sr->u.explain_request->database = db;
800 sr->u.explain_request->stylesheet = stylesheet;
802 (*soap_package) = (Z_SOAP *)
803 odr_malloc(decode, sizeof(**soap_package));
804 (*soap_package)->which = Z_SOAP_generic;
806 (*soap_package)->u.generic = (Z_SOAP_Generic *)
807 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
809 (*soap_package)->u.generic->p = sr;
810 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
811 (*soap_package)->u.generic->no = 0;
813 (*soap_package)->ns = "SRU";
815 yaz_add_srw_diagnostic(decode, diag, num_diag,
816 YAZ_SRW_UNSUPP_OPERATION, operation);
825 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
827 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
828 odr_malloc(o, sizeof(*res));
830 res->extraRecordData_buf = 0;
831 res->extraRecordData_len = 0;
832 res->recordIdentifier = 0;
837 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
839 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
842 for (i = 0; i<n; i++)
844 res[i].recordSchema = 0;
845 res[i].recordPacking = Z_SRW_recordPacking_string;
846 res[i].recordData_buf = 0;
847 res[i].recordData_len = 0;
848 res[i].recordPosition = 0;
853 Z_SRW_record *yaz_srw_get_record(ODR o)
855 return yaz_srw_get_records(o, 1);
858 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
860 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
861 p->srw_version = odr_strdup(o, version);
865 p->extraResponseData_buf = 0;
866 p->extraResponseData_len = 0;
870 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
872 return yaz_srw_get_core_ver(o, "1.1");
875 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
877 return yaz_srw_get_pdu(o, which, "1.1");
880 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
882 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
887 case Z_SRW_searchRetrieve_request:
888 sr->u.request = (Z_SRW_searchRetrieveRequest *)
889 odr_malloc(o, sizeof(*sr->u.request));
890 sr->u.request->query_type = Z_SRW_query_type_cql;
891 sr->u.request->query.cql = 0;
892 sr->u.request->sort_type = Z_SRW_sort_type_none;
893 sr->u.request->sort.none = 0;
894 sr->u.request->startRecord = 0;
895 sr->u.request->maximumRecords = 0;
896 sr->u.request->recordSchema = 0;
897 sr->u.request->recordPacking = 0;
898 sr->u.request->recordXPath = 0;
899 sr->u.request->database = 0;
900 sr->u.request->resultSetTTL = 0;
901 sr->u.request->stylesheet = 0;
903 case Z_SRW_searchRetrieve_response:
904 sr->u.response = (Z_SRW_searchRetrieveResponse *)
905 odr_malloc(o, sizeof(*sr->u.response));
906 sr->u.response->numberOfRecords = 0;
907 sr->u.response->resultSetId = 0;
908 sr->u.response->resultSetIdleTime = 0;
909 sr->u.response->records = 0;
910 sr->u.response->num_records = 0;
911 sr->u.response->diagnostics = 0;
912 sr->u.response->num_diagnostics = 0;
913 sr->u.response->nextRecordPosition = 0;
914 sr->u.response->extra_records = 0;
916 case Z_SRW_explain_request:
917 sr->u.explain_request = (Z_SRW_explainRequest *)
918 odr_malloc(o, sizeof(*sr->u.explain_request));
919 sr->u.explain_request->recordPacking = 0;
920 sr->u.explain_request->database = 0;
921 sr->u.explain_request->stylesheet = 0;
923 case Z_SRW_explain_response:
924 sr->u.explain_response = (Z_SRW_explainResponse *)
925 odr_malloc(o, sizeof(*sr->u.explain_response));
926 sr->u.explain_response->record.recordData_buf = 0;
927 sr->u.explain_response->record.recordData_len = 0;
928 sr->u.explain_response->record.recordSchema = 0;
929 sr->u.explain_response->record.recordPosition = 0;
930 sr->u.explain_response->record.recordPacking =
931 Z_SRW_recordPacking_string;
932 sr->u.explain_response->diagnostics = 0;
933 sr->u.explain_response->num_diagnostics = 0;
934 sr->u.explain_response->extra_record = 0;
936 case Z_SRW_scan_request:
937 sr->u.scan_request = (Z_SRW_scanRequest *)
938 odr_malloc(o, sizeof(*sr->u.scan_request));
939 sr->u.scan_request->database = 0;
940 sr->u.scan_request->stylesheet = 0;
941 sr->u.scan_request->maximumTerms = 0;
942 sr->u.scan_request->responsePosition = 0;
943 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
944 sr->u.scan_request->scanClause.cql = 0;
946 case Z_SRW_scan_response:
947 sr->u.scan_response = (Z_SRW_scanResponse *)
948 odr_malloc(o, sizeof(*sr->u.scan_response));
949 sr->u.scan_response->terms = 0;
950 sr->u.scan_response->num_terms = 0;
951 sr->u.scan_response->diagnostics = 0;
952 sr->u.scan_response->num_diagnostics = 0;
954 case Z_SRW_update_request:
955 sr->u.update_request = (Z_SRW_updateRequest *)
956 odr_malloc(o, sizeof(*sr->u.update_request));
957 sr->u.update_request->database = 0;
958 sr->u.update_request->stylesheet = 0;
959 sr->u.update_request->record = 0;
960 sr->u.update_request->recordId = 0;
961 sr->u.update_request->recordVersions = 0;
962 sr->u.update_request->num_recordVersions = 0;
963 sr->u.update_request->extra_record = 0;
964 sr->u.update_request->extraRequestData_buf = 0;
965 sr->u.update_request->extraRequestData_len = 0;
966 sr->u.request->database = 0;
968 case Z_SRW_update_response:
969 sr->u.update_response = (Z_SRW_updateResponse *)
970 odr_malloc(o, sizeof(*sr->u.update_response));
971 sr->u.update_response->operationStatus = 0;
972 sr->u.update_response->recordId = 0;
973 sr->u.update_response->recordVersions = 0;
974 sr->u.update_response->num_recordVersions = 0;
975 sr->u.update_response->record = 0;
976 sr->u.update_response->extra_record = 0;
977 sr->u.update_response->extraResponseData_buf = 0;
978 sr->u.update_response->extraResponseData_len = 0;
979 sr->u.update_response->diagnostics = 0;
980 sr->u.update_response->num_diagnostics = 0;
986 static int bib1_srw_map[] = {
996 108, 10, /* Malformed query : Syntax error */
1026 100, 1, /* bad map */
1074 205, 1, /* bad map */
1075 206, 1, /* bad map */
1077 208, 1, /* bad map */
1088 218, 1, /* bad map */
1089 219, 1, /* bad map */
1090 220, 1, /* bad map */
1091 221, 1, /* bad map */
1093 223, 1, /* bad map */
1094 224, 1, /* bad map */
1095 225, 1, /* bad map */
1096 226, 1, /* bad map */
1098 228, 1, /* bad map */
1103 233, 1, /* bad map */
1104 234, 1, /* bad map */
1110 240, 1, /* bad map */
1111 241, 1, /* bad map */
1113 243, 1, /* bad map */
1118 1001, 1, /* bad map */
1119 1002, 1, /* bad map */
1120 1003, 1, /* bad map */
1121 1004, 1, /* bad map */
1122 1005, 1, /* bad map */
1123 1006, 1, /* bad map */
1156 * This array contains overrides for when the first occurrence of a
1157 * particular SRW error in the array above does not correspond with
1158 * the best back-translation of that SRW error.
1160 static int srw_bib1_map[] = {
1162 /* No doubt there are many more */
1167 int yaz_diag_bib1_to_srw (int code)
1169 const int *p = bib1_srw_map;
1179 int yaz_diag_srw_to_bib1(int code)
1181 /* Check explicit reverse-map first */
1182 const int *p = srw_bib1_map;
1190 /* Fall back on reverse lookup in main map */
1201 static void add_val_int(ODR o, char **name, char **value, int *i,
1202 char *a_name, Odr_int *val)
1207 value[*i] = (char *) odr_malloc(o, 40);
1208 sprintf(value[*i], ODR_INT_PRINTF, *val);
1213 static void add_val_str(ODR o, char **name, char **value, int *i,
1214 char *a_name, char *val)
1224 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1225 char **name, char **value, int max_names)
1228 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1229 name[i] = "operation";
1230 switch(srw_pdu->which)
1232 case Z_SRW_searchRetrieve_request:
1233 value[i++] = "searchRetrieve";
1234 switch(srw_pdu->u.request->query_type)
1236 case Z_SRW_query_type_cql:
1237 add_val_str(encode, name, value, &i, "query",
1238 srw_pdu->u.request->query.cql);
1240 case Z_SRW_query_type_pqf:
1241 add_val_str(encode, name, value, &i, "x-pquery",
1242 srw_pdu->u.request->query.pqf);
1244 case Z_SRW_query_type_xcql:
1245 add_val_str(encode, name, value, &i, "x-cql",
1246 srw_pdu->u.request->query.xcql);
1249 switch(srw_pdu->u.request->sort_type)
1251 case Z_SRW_sort_type_none:
1253 case Z_SRW_sort_type_sort:
1254 add_val_str(encode, name, value, &i, "sortKeys",
1255 srw_pdu->u.request->sort.sortKeys);
1258 add_val_int(encode, name, value, &i, "startRecord",
1259 srw_pdu->u.request->startRecord);
1260 add_val_int(encode, name, value, &i, "maximumRecords",
1261 srw_pdu->u.request->maximumRecords);
1262 add_val_str(encode, name, value, &i, "recordSchema",
1263 srw_pdu->u.request->recordSchema);
1264 add_val_str(encode, name, value, &i, "recordPacking",
1265 srw_pdu->u.request->recordPacking);
1266 add_val_str(encode, name, value, &i, "recordXPath",
1267 srw_pdu->u.request->recordXPath);
1268 add_val_str(encode, name, value, &i, "stylesheet",
1269 srw_pdu->u.request->stylesheet);
1270 add_val_int(encode, name, value, &i, "resultSetTTL",
1271 srw_pdu->u.request->resultSetTTL);
1273 case Z_SRW_explain_request:
1274 value[i++] = "explain";
1275 add_val_str(encode, name, value, &i, "stylesheet",
1276 srw_pdu->u.explain_request->stylesheet);
1278 case Z_SRW_scan_request:
1279 value[i++] = "scan";
1281 switch(srw_pdu->u.scan_request->query_type)
1283 case Z_SRW_query_type_cql:
1284 add_val_str(encode, name, value, &i, "scanClause",
1285 srw_pdu->u.scan_request->scanClause.cql);
1287 case Z_SRW_query_type_pqf:
1288 add_val_str(encode, name, value, &i, "x-pScanClause",
1289 srw_pdu->u.scan_request->scanClause.pqf);
1291 case Z_SRW_query_type_xcql:
1292 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1293 srw_pdu->u.scan_request->scanClause.xcql);
1296 add_val_int(encode, name, value, &i, "responsePosition",
1297 srw_pdu->u.scan_request->responsePosition);
1298 add_val_int(encode, name, value, &i, "maximumTerms",
1299 srw_pdu->u.scan_request->maximumTerms);
1300 add_val_str(encode, name, value, &i, "stylesheet",
1301 srw_pdu->u.scan_request->stylesheet);
1303 case Z_SRW_update_request:
1304 value[i++] = "update";
1309 if (srw_pdu->extra_args)
1311 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1312 for (; ea && i < max_names-1; ea = ea->next)
1315 value[i] = ea->value;
1324 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1325 ODR encode, const char *charset)
1327 char *name[30], *value[30]; /* definite upper limit for SRU params */
1331 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1332 srw_pdu->username, srw_pdu->password);
1333 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1335 yaz_array_to_uri(&uri_args, encode, name, value);
1337 hreq->method = "GET";
1340 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1342 sprintf(path, "%s?%s", hreq->path, uri_args);
1345 z_HTTP_header_add_content_type(encode, &hreq->headers,
1346 "text/xml", charset);
1350 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1351 ODR encode, const char *charset)
1353 char *name[30], *value[30]; /* definite upper limit for SRU params */
1356 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1357 srw_pdu->username, srw_pdu->password);
1358 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1361 yaz_array_to_uri(&uri_args, encode, name, value);
1363 hreq->method = "POST";
1365 hreq->content_buf = uri_args;
1366 hreq->content_len = strlen(uri_args);
1368 z_HTTP_header_add_content_type(encode, &hreq->headers,
1369 "application/x-www-form-urlencoded",
1374 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1375 ODR odr, const char *charset)
1377 Z_SOAP_Handler handlers[3] = {
1379 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1380 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1384 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1386 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1387 srw_pdu->username, srw_pdu->password);
1388 z_HTTP_header_add_content_type(odr,
1390 "text/xml", charset);
1392 z_HTTP_header_add(odr, &hreq->headers,
1393 "SOAPAction", "\"\"");
1394 p->which = Z_SOAP_generic;
1395 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1396 p->u.generic->no = 0;
1397 p->u.generic->ns = 0;
1398 p->u.generic->p = srw_pdu;
1399 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1402 if (srw_pdu->which == Z_SRW_update_request ||
1403 srw_pdu->which == Z_SRW_update_response)
1404 p->u.generic->no = 1; /* second handler */
1406 return z_soap_codec_enc(odr, &p,
1408 &hreq->content_len, handlers,
1412 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1414 Z_SRW_recordVersion *ver
1415 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1417 for ( i=0; i < num; ++i ){
1418 ver[i].versionType = 0;
1419 ver[i].versionValue = 0;
1424 const char *yaz_srw_pack_to_str(int pack)
1428 case Z_SRW_recordPacking_string:
1430 case Z_SRW_recordPacking_XML:
1432 case Z_SRW_recordPacking_URL:
1438 int yaz_srw_str_to_pack(const char *str)
1440 if (!yaz_matchstr(str, "string"))
1441 return Z_SRW_recordPacking_string;
1442 if (!yaz_matchstr(str, "xml"))
1443 return Z_SRW_recordPacking_XML;
1444 if (!yaz_matchstr(str, "url"))
1445 return Z_SRW_recordPacking_URL;
1449 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1455 Z_SRW_extra_arg **ea = &sr->extra_args;
1456 yaz_uri_to_array(extra_args, odr, &name, &val);
1460 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1461 (*ea)->name = *name;
1462 (*ea)->value = *val;
1476 * c-file-style: "Stroustrup"
1477 * indent-tabs-mode: nil
1479 * vim: shiftwidth=4 tabstop=8 expandtab