2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.62 2007-08-24 13:26:03 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_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 srw_bib1_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 */
1119 int yaz_diag_bib1_to_srw (int code)
1121 const int *p = srw_bib1_map;
1131 int yaz_diag_srw_to_bib1(int code)
1133 const int *p = srw_bib1_map;
1143 static void add_val_int(ODR o, char **name, char **value, int *i,
1144 char *a_name, int *val)
1149 value[*i] = (char *) odr_malloc(o, 30);
1150 sprintf(value[*i], "%d", *val);
1155 static void add_val_str(ODR o, char **name, char **value, int *i,
1156 char *a_name, char *val)
1166 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1167 char **name, char **value)
1170 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1171 name[i] = "operation";
1172 switch(srw_pdu->which)
1174 case Z_SRW_searchRetrieve_request:
1175 value[i++] = "searchRetrieve";
1176 switch(srw_pdu->u.request->query_type)
1178 case Z_SRW_query_type_cql:
1179 add_val_str(encode, name, value, &i, "query",
1180 srw_pdu->u.request->query.cql);
1182 case Z_SRW_query_type_pqf:
1183 add_val_str(encode, name, value, &i, "x-pquery",
1184 srw_pdu->u.request->query.pqf);
1186 case Z_SRW_query_type_xcql:
1187 add_val_str(encode, name, value, &i, "x-cql",
1188 srw_pdu->u.request->query.xcql);
1191 switch(srw_pdu->u.request->sort_type)
1193 case Z_SRW_sort_type_none:
1195 case Z_SRW_sort_type_sort:
1196 add_val_str(encode, name, value, &i, "sortKeys",
1197 srw_pdu->u.request->sort.sortKeys);
1200 add_val_int(encode, name, value, &i, "startRecord",
1201 srw_pdu->u.request->startRecord);
1202 add_val_int(encode, name, value, &i, "maximumRecords",
1203 srw_pdu->u.request->maximumRecords);
1204 add_val_str(encode, name, value, &i, "recordSchema",
1205 srw_pdu->u.request->recordSchema);
1206 add_val_str(encode, name, value, &i, "recordPacking",
1207 srw_pdu->u.request->recordPacking);
1208 add_val_str(encode, name, value, &i, "recordXPath",
1209 srw_pdu->u.request->recordXPath);
1210 add_val_str(encode, name, value, &i, "stylesheet",
1211 srw_pdu->u.request->stylesheet);
1212 add_val_int(encode, name, value, &i, "resultSetTTL",
1213 srw_pdu->u.request->resultSetTTL);
1215 case Z_SRW_explain_request:
1216 value[i++] = "explain";
1217 add_val_str(encode, name, value, &i, "stylesheet",
1218 srw_pdu->u.explain_request->stylesheet);
1220 case Z_SRW_scan_request:
1221 value[i++] = "scan";
1223 switch(srw_pdu->u.scan_request->query_type)
1225 case Z_SRW_query_type_cql:
1226 add_val_str(encode, name, value, &i, "scanClause",
1227 srw_pdu->u.scan_request->scanClause.cql);
1229 case Z_SRW_query_type_pqf:
1230 add_val_str(encode, name, value, &i, "x-pScanClause",
1231 srw_pdu->u.scan_request->scanClause.pqf);
1233 case Z_SRW_query_type_xcql:
1234 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1235 srw_pdu->u.scan_request->scanClause.xcql);
1238 add_val_int(encode, name, value, &i, "responsePosition",
1239 srw_pdu->u.scan_request->responsePosition);
1240 add_val_int(encode, name, value, &i, "maximumTerms",
1241 srw_pdu->u.scan_request->maximumTerms);
1242 add_val_str(encode, name, value, &i, "stylesheet",
1243 srw_pdu->u.scan_request->stylesheet);
1245 case Z_SRW_update_request:
1246 value[i++] = "update";
1255 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1256 ODR encode, const char *charset)
1258 char *name[30], *value[30]; /* definite upper limit for SRU params */
1262 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1264 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1266 hreq->method = "GET";
1269 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4
1270 +(srw_pdu->extra_args ? strlen(srw_pdu->extra_args) : 0));
1272 sprintf(path, "%s?%s", hreq->path, uri_args);
1275 z_HTTP_header_add_content_type(encode, &hreq->headers,
1276 "text/xml", charset);
1280 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1281 ODR encode, const char *charset)
1283 char *name[30], *value[30]; /* definite upper limit for SRU params */
1286 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1289 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1291 hreq->method = "POST";
1293 hreq->content_buf = uri_args;
1294 hreq->content_len = strlen(uri_args);
1296 z_HTTP_header_add_content_type(encode, &hreq->headers,
1297 "application/x-www-form-urlencoded",
1302 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1303 ODR odr, const char *charset)
1305 Z_SOAP_Handler handlers[3] = {
1307 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1308 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1312 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1314 z_HTTP_header_add_content_type(odr,
1316 "text/xml", charset);
1318 z_HTTP_header_add(odr, &hreq->headers,
1319 "SOAPAction", "\"\"");
1320 p->which = Z_SOAP_generic;
1321 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1322 p->u.generic->no = 0;
1323 p->u.generic->ns = 0;
1324 p->u.generic->p = srw_pdu;
1325 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1328 if (srw_pdu->which == Z_SRW_update_request ||
1329 srw_pdu->which == Z_SRW_update_response)
1330 p->u.generic->no = 1; /* second handler */
1332 return z_soap_codec_enc(odr, &p,
1334 &hreq->content_len, handlers,
1338 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1340 Z_SRW_recordVersion *ver
1341 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1343 for ( i=0; i < num; ++i ){
1344 ver[i].versionType = 0;
1345 ver[i].versionValue = 0;
1350 const char *yaz_srw_pack_to_str(int pack)
1354 case Z_SRW_recordPacking_string:
1356 case Z_SRW_recordPacking_XML:
1358 case Z_SRW_recordPacking_URL:
1364 int yaz_srw_str_to_pack(const char *str)
1366 if (!yaz_matchstr(str, "string"))
1367 return Z_SRW_recordPacking_string;
1368 if (!yaz_matchstr(str, "xml"))
1369 return Z_SRW_recordPacking_XML;
1370 if (!yaz_matchstr(str, "url"))
1371 return Z_SRW_recordPacking_URL;
1378 * indent-tabs-mode: nil
1380 * vim: shiftwidth=4 tabstop=8 expandtab