2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.56 2007-05-06 20:12:20 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 else if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
32 (ch >= '0' && ch <= '9'))
40 sprintf(dst+1, "%02X", (unsigned char ) ch);
44 static void yaz_array_to_uri_ex(char **path, ODR o, char **name, char **value,
45 const char *extra_args)
47 size_t i, szp = 0, sz = extra_args ? 1+strlen(extra_args) : 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);
75 memcpy(*path + szp, extra_args, strlen(extra_args));
76 szp += strlen(extra_args);
81 void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
83 yaz_array_to_uri_ex(path, o, name, value, 0);
86 int yaz_uri_array(const char *path, ODR o, char ***name, char ***val)
96 while ((cp = strchr(cp, '&')))
101 *name = (char **) odr_malloc(o, no * sizeof(char*));
102 *val = (char **) odr_malloc(o, no * sizeof(char*));
104 for (no = 0; *path; no++)
106 const char *p1 = strchr(path, '=');
112 (*name)[no] = (char *) odr_malloc(o, (p1-path)+1);
113 memcpy((*name)[no], path, p1-path);
114 (*name)[no][p1-path] = '\0';
117 p1 = strchr(path, '&');
119 p1 = strlen(path) + path;
120 (*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1);
121 while (*path && *path != '&')
128 else if (*path == '%' && path[1] && path[2])
130 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
146 char *yaz_uri_val(const char *path, const char *name, ODR o)
148 size_t nlen = strlen(name);
152 while (path && *path)
154 const char *p1 = strchr(path, '=');
157 if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
163 p1 = strchr(path, '&');
165 p1 = strlen(path) + path;
166 ret = (char *) odr_malloc(o, p1 - path + 1);
167 while (*path && *path != '&')
174 else if (*path == '%' && path[1] && path[2])
176 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
185 path = strchr(p1, '&');
192 static int yaz_base64decode(const char *in, char *out)
194 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
195 "abcdefghijklmnopqrstuvwxyz0123456789+/";
197 int len = strlen(in);
204 if (!(p = strchr(map, in[0])))
208 if (!(p = strchr(map, in[1])))
212 *(out++) = i0 << 2 | i1 >> 4;
216 if (!(p = strchr(map, in[2])))
220 *(out++) = i1 << 4 | i2 >> 2;
224 if (!(p = strchr(map, in[3])))
228 *(out++) = i2 << 6 | i3;
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;
507 grab_charset(decode, content_type, charset);
508 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
513 p1 = strchr(p0, '?');
515 p1 = p0 + strlen(p0);
518 db = (char*) odr_malloc(decode, p1 - p0 + 1);
519 memcpy (db, p0, p1 - p0);
522 if (!strcmp(hreq->method, "POST"))
523 p1 = hreq->content_buf;
524 yaz_uri_array(p1, decode, &uri_name, &uri_val);
529 for (i = 0; uri_name[i]; i++)
531 char *n = uri_name[i];
532 char *v = uri_val[i];
533 if (!strcmp(n, "query"))
535 else if (!strcmp(n, "x-pquery"))
537 else if (!strcmp(n, "x-username"))
539 else if (!strcmp(n, "x-password"))
541 else if (!strcmp(n, "operation"))
543 else if (!strcmp(n, "stylesheet"))
545 else if (!strcmp(n, "sortKeys"))
547 else if (!strcmp(n, "recordXPath"))
549 else if (!strcmp(n, "recordSchema"))
551 else if (!strcmp(n, "recordPacking"))
553 else if (!strcmp(n, "version"))
555 else if (!strcmp(n, "scanClause"))
557 else if (!strcmp(n, "x-pScanClause"))
559 else if (!strcmp(n, "maximumRecords"))
561 else if (!strcmp(n, "startRecord"))
563 else if (!strcmp(n, "maximumTerms"))
565 else if (!strcmp(n, "responsePosition"))
566 responsePosition = v;
567 else if (!strcmp(n, "extraRequestData"))
568 extraRequestData = v;
570 yaz_add_srw_diagnostic(decode, diag, num_diag,
571 YAZ_SRW_UNSUPP_PARAMETER, n);
577 yaz_add_srw_diagnostic(
578 decode, diag, num_diag,
579 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
582 if (strcmp(version, "1.1"))
583 yaz_add_srw_diagnostic(decode, diag, num_diag,
584 YAZ_SRW_UNSUPP_VERSION, "1.1");
588 yaz_add_srw_diagnostic(
589 decode, diag, num_diag,
590 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
591 operation = "explain";
593 if (!strcmp(operation, "searchRetrieve"))
595 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
597 sr->srw_version = version;
599 yaz_srw_decodeauth(sr, hreq, username, password, decode);
602 sr->u.request->query_type = Z_SRW_query_type_cql;
603 sr->u.request->query.cql = query;
607 sr->u.request->query_type = Z_SRW_query_type_pqf;
608 sr->u.request->query.pqf = pQuery;
611 yaz_add_srw_diagnostic(
612 decode, diag, num_diag,
613 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
617 sr->u.request->sort_type = Z_SRW_sort_type_sort;
618 sr->u.request->sort.sortKeys = sortKeys;
620 sr->u.request->recordXPath = recordXPath;
621 sr->u.request->recordSchema = recordSchema;
622 sr->u.request->recordPacking = recordPacking;
623 sr->u.request->stylesheet = stylesheet;
625 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
626 &sr->u.request->maximumRecords,
629 yaz_sru_decode_integer(decode, "startRecord", startRecord,
630 &sr->u.request->startRecord,
633 sr->u.request->database = db;
635 (*soap_package) = (Z_SOAP *)
636 odr_malloc(decode, sizeof(**soap_package));
637 (*soap_package)->which = Z_SOAP_generic;
639 (*soap_package)->u.generic = (Z_SOAP_Generic *)
640 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
642 (*soap_package)->u.generic->p = sr;
643 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
644 (*soap_package)->u.generic->no = 0;
646 (*soap_package)->ns = "SRU";
650 else if (!strcmp(operation, "explain"))
652 /* Transfer SRU explain parameters to common struct */
653 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
654 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
656 sr->srw_version = version;
657 yaz_srw_decodeauth(sr, hreq, username, password, decode);
659 sr->u.explain_request->recordPacking = recordPacking;
660 sr->u.explain_request->database = db;
662 sr->u.explain_request->stylesheet = stylesheet;
664 (*soap_package) = (Z_SOAP *)
665 odr_malloc(decode, sizeof(**soap_package));
666 (*soap_package)->which = Z_SOAP_generic;
668 (*soap_package)->u.generic = (Z_SOAP_Generic *)
669 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
671 (*soap_package)->u.generic->p = sr;
672 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
673 (*soap_package)->u.generic->no = 0;
675 (*soap_package)->ns = "SRU";
679 else if (!strcmp(operation, "scan"))
681 /* Transfer SRU scan parameters to common struct */
682 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
683 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
685 sr->srw_version = version;
687 yaz_srw_decodeauth(sr, hreq, username, password, decode);
691 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
692 sr->u.scan_request->scanClause.cql = scanClause;
694 else if (pScanClause)
696 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
697 sr->u.scan_request->scanClause.pqf = pScanClause;
700 yaz_add_srw_diagnostic(
701 decode, diag, num_diag,
702 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
703 sr->u.scan_request->database = db;
705 yaz_sru_decode_integer(decode, "maximumTerms",
707 &sr->u.scan_request->maximumTerms,
710 yaz_sru_decode_integer(decode, "responsePosition",
712 &sr->u.scan_request->responsePosition,
715 sr->u.scan_request->stylesheet = stylesheet;
717 (*soap_package) = (Z_SOAP *)
718 odr_malloc(decode, sizeof(**soap_package));
719 (*soap_package)->which = Z_SOAP_generic;
721 (*soap_package)->u.generic = (Z_SOAP_Generic *)
722 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
724 (*soap_package)->u.generic->p = sr;
725 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
726 (*soap_package)->u.generic->no = 0;
728 (*soap_package)->ns = "SRU";
734 /* unsupported operation ... */
735 /* Act as if we received a explain request and throw diagnostic. */
737 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
739 sr->srw_version = version;
741 sr->u.explain_request->recordPacking = recordPacking;
742 sr->u.explain_request->database = db;
744 sr->u.explain_request->stylesheet = stylesheet;
746 (*soap_package) = (Z_SOAP *)
747 odr_malloc(decode, sizeof(**soap_package));
748 (*soap_package)->which = Z_SOAP_generic;
750 (*soap_package)->u.generic = (Z_SOAP_Generic *)
751 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
753 (*soap_package)->u.generic->p = sr;
754 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
755 (*soap_package)->u.generic->no = 0;
757 (*soap_package)->ns = "SRU";
759 yaz_add_srw_diagnostic(decode, diag, num_diag,
760 YAZ_SRW_UNSUPP_OPERATION, operation);
769 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
771 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
772 odr_malloc(o, sizeof(*res));
774 res->extraRecordData_buf = 0;
775 res->extraRecordData_len = 0;
776 res->recordIdentifier = 0;
781 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
783 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
786 for (i = 0; i<n; i++)
788 res[i].recordSchema = 0;
789 res[i].recordPacking = Z_SRW_recordPacking_string;
790 res[i].recordData_buf = 0;
791 res[i].recordData_len = 0;
792 res[i].recordPosition = 0;
797 Z_SRW_record *yaz_srw_get_record(ODR o)
799 return yaz_srw_get_records(o, 1);
802 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
804 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
805 p->srw_version = odr_strdup(o, "1.1");
812 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
814 Z_SRW_PDU *sr = yaz_srw_get_core_v_1_1(o);
818 case Z_SRW_searchRetrieve_request:
819 sr->u.request = (Z_SRW_searchRetrieveRequest *)
820 odr_malloc(o, sizeof(*sr->u.request));
821 sr->u.request->query_type = Z_SRW_query_type_cql;
822 sr->u.request->query.cql = 0;
823 sr->u.request->sort_type = Z_SRW_sort_type_none;
824 sr->u.request->sort.none = 0;
825 sr->u.request->startRecord = 0;
826 sr->u.request->maximumRecords = 0;
827 sr->u.request->recordSchema = 0;
828 sr->u.request->recordPacking = 0;
829 sr->u.request->recordXPath = 0;
830 sr->u.request->database = 0;
831 sr->u.request->resultSetTTL = 0;
832 sr->u.request->stylesheet = 0;
834 case Z_SRW_searchRetrieve_response:
835 sr->u.response = (Z_SRW_searchRetrieveResponse *)
836 odr_malloc(o, sizeof(*sr->u.response));
837 sr->u.response->numberOfRecords = 0;
838 sr->u.response->resultSetId = 0;
839 sr->u.response->resultSetIdleTime = 0;
840 sr->u.response->records = 0;
841 sr->u.response->num_records = 0;
842 sr->u.response->diagnostics = 0;
843 sr->u.response->num_diagnostics = 0;
844 sr->u.response->nextRecordPosition = 0;
845 sr->u.response->extra_records = 0;
847 case Z_SRW_explain_request:
848 sr->u.explain_request = (Z_SRW_explainRequest *)
849 odr_malloc(o, sizeof(*sr->u.explain_request));
850 sr->u.explain_request->recordPacking = 0;
851 sr->u.explain_request->database = 0;
852 sr->u.explain_request->stylesheet = 0;
854 case Z_SRW_explain_response:
855 sr->u.explain_response = (Z_SRW_explainResponse *)
856 odr_malloc(o, sizeof(*sr->u.explain_response));
857 sr->u.explain_response->record.recordData_buf = 0;
858 sr->u.explain_response->record.recordData_len = 0;
859 sr->u.explain_response->record.recordSchema = 0;
860 sr->u.explain_response->record.recordPosition = 0;
861 sr->u.explain_response->record.recordPacking =
862 Z_SRW_recordPacking_string;
863 sr->u.explain_response->diagnostics = 0;
864 sr->u.explain_response->num_diagnostics = 0;
865 sr->u.explain_response->extra_record = 0;
867 case Z_SRW_scan_request:
868 sr->u.scan_request = (Z_SRW_scanRequest *)
869 odr_malloc(o, sizeof(*sr->u.scan_request));
870 sr->u.scan_request->database = 0;
871 sr->u.scan_request->stylesheet = 0;
872 sr->u.scan_request->maximumTerms = 0;
873 sr->u.scan_request->responsePosition = 0;
874 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
875 sr->u.scan_request->scanClause.cql = 0;
877 case Z_SRW_scan_response:
878 sr->u.scan_response = (Z_SRW_scanResponse *)
879 odr_malloc(o, sizeof(*sr->u.scan_response));
880 sr->u.scan_response->terms = 0;
881 sr->u.scan_response->num_terms = 0;
882 sr->u.scan_response->diagnostics = 0;
883 sr->u.scan_response->num_diagnostics = 0;
885 case Z_SRW_update_request:
886 sr->u.update_request = (Z_SRW_updateRequest *)
887 odr_malloc(o, sizeof(*sr->u.update_request));
888 sr->u.update_request->database = 0;
889 sr->u.update_request->stylesheet = 0;
890 sr->u.update_request->record = 0;
891 sr->u.update_request->recordId = 0;
892 sr->u.update_request->recordVersions = 0;
893 sr->u.update_request->num_recordVersions = 0;
894 sr->u.update_request->extra_record = 0;
895 sr->u.update_request->extraRequestData_buf = 0;
896 sr->u.update_request->extraRequestData_len = 0;
897 sr->u.request->database = 0;
899 case Z_SRW_update_response:
900 sr->u.update_response = (Z_SRW_updateResponse *)
901 odr_malloc(o, sizeof(*sr->u.update_response));
902 sr->u.update_response->operationStatus = 0;
903 sr->u.update_response->recordId = 0;
904 sr->u.update_response->recordVersions = 0;
905 sr->u.update_response->num_recordVersions = 0;
906 sr->u.update_response->record = 0;
907 sr->u.update_response->extra_record = 0;
908 sr->u.update_response->extraResponseData_buf = 0;
909 sr->u.update_response->extraResponseData_len = 0;
910 sr->u.update_response->diagnostics = 0;
911 sr->u.update_response->num_diagnostics = 0;
917 static int srw_bib1_map[] = {
927 108, 10, /* Malformed query : Syntax error */
957 100, 1, /* bad map */
1005 205, 1, /* bad map */
1006 206, 1, /* bad map */
1008 208, 1, /* bad map */
1019 218, 1, /* bad map */
1020 219, 1, /* bad map */
1021 220, 1, /* bad map */
1022 221, 1, /* bad map */
1024 223, 1, /* bad map */
1025 224, 1, /* bad map */
1026 225, 1, /* bad map */
1027 226, 1, /* bad map */
1029 228, 1, /* bad map */
1034 233, 1, /* bad map */
1035 234, 1, /* bad map */
1041 240, 1, /* bad map */
1042 241, 1, /* bad map */
1044 243, 1, /* bad map */
1049 1001, 1, /* bad map */
1050 1002, 1, /* bad map */
1051 1003, 1, /* bad map */
1052 1004, 1, /* bad map */
1053 1005, 1, /* bad map */
1054 1006, 1, /* bad map */
1086 int yaz_diag_bib1_to_srw (int code)
1088 const int *p = srw_bib1_map;
1098 int yaz_diag_srw_to_bib1(int code)
1100 const int *p = srw_bib1_map;
1110 static void add_val_int(ODR o, char **name, char **value, int *i,
1111 char *a_name, int *val)
1116 value[*i] = (char *) odr_malloc(o, 30);
1117 sprintf(value[*i], "%d", *val);
1122 static void add_val_str(ODR o, char **name, char **value, int *i,
1123 char *a_name, char *val)
1133 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1134 char **name, char **value)
1137 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1138 name[i] = "operation";
1139 switch(srw_pdu->which)
1141 case Z_SRW_searchRetrieve_request:
1142 value[i++] = "searchRetrieve";
1143 switch(srw_pdu->u.request->query_type)
1145 case Z_SRW_query_type_cql:
1146 add_val_str(encode, name, value, &i, "query",
1147 srw_pdu->u.request->query.cql);
1149 case Z_SRW_query_type_pqf:
1150 add_val_str(encode, name, value, &i, "x-pquery",
1151 srw_pdu->u.request->query.pqf);
1153 case Z_SRW_query_type_xcql:
1154 add_val_str(encode, name, value, &i, "x-cql",
1155 srw_pdu->u.request->query.xcql);
1158 switch(srw_pdu->u.request->sort_type)
1160 case Z_SRW_sort_type_none:
1162 case Z_SRW_sort_type_sort:
1163 add_val_str(encode, name, value, &i, "sortKeys",
1164 srw_pdu->u.request->sort.sortKeys);
1167 add_val_int(encode, name, value, &i, "startRecord",
1168 srw_pdu->u.request->startRecord);
1169 add_val_int(encode, name, value, &i, "maximumRecords",
1170 srw_pdu->u.request->maximumRecords);
1171 add_val_str(encode, name, value, &i, "recordSchema",
1172 srw_pdu->u.request->recordSchema);
1173 add_val_str(encode, name, value, &i, "recordPacking",
1174 srw_pdu->u.request->recordPacking);
1175 add_val_str(encode, name, value, &i, "recordXPath",
1176 srw_pdu->u.request->recordXPath);
1177 add_val_str(encode, name, value, &i, "stylesheet",
1178 srw_pdu->u.request->stylesheet);
1179 add_val_int(encode, name, value, &i, "resultSetTTL",
1180 srw_pdu->u.request->resultSetTTL);
1182 case Z_SRW_explain_request:
1183 value[i++] = "explain";
1184 add_val_str(encode, name, value, &i, "stylesheet",
1185 srw_pdu->u.explain_request->stylesheet);
1187 case Z_SRW_scan_request:
1188 value[i++] = "scan";
1190 switch(srw_pdu->u.scan_request->query_type)
1192 case Z_SRW_query_type_cql:
1193 add_val_str(encode, name, value, &i, "scanClause",
1194 srw_pdu->u.scan_request->scanClause.cql);
1196 case Z_SRW_query_type_pqf:
1197 add_val_str(encode, name, value, &i, "x-pScanClause",
1198 srw_pdu->u.scan_request->scanClause.pqf);
1200 case Z_SRW_query_type_xcql:
1201 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1202 srw_pdu->u.scan_request->scanClause.xcql);
1205 add_val_int(encode, name, value, &i, "responsePosition",
1206 srw_pdu->u.scan_request->responsePosition);
1207 add_val_int(encode, name, value, &i, "maximumTerms",
1208 srw_pdu->u.scan_request->maximumTerms);
1209 add_val_str(encode, name, value, &i, "stylesheet",
1210 srw_pdu->u.scan_request->stylesheet);
1212 case Z_SRW_update_request:
1213 value[i++] = "update";
1222 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1223 ODR encode, const char *charset)
1225 char *name[30], *value[30]; /* definite upper limit for SRU params */
1229 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1231 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1233 hreq->method = "GET";
1236 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4
1237 +(srw_pdu->extra_args ? strlen(srw_pdu->extra_args) : 0));
1239 sprintf(path, "%s?%s", hreq->path, uri_args);
1242 z_HTTP_header_add_content_type(encode, &hreq->headers,
1243 "text/xml", charset);
1247 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1248 ODR encode, const char *charset)
1250 char *name[30], *value[30]; /* definite upper limit for SRU params */
1253 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1256 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1258 hreq->method = "POST";
1260 hreq->content_buf = uri_args;
1261 hreq->content_len = strlen(uri_args);
1263 z_HTTP_header_add_content_type(encode, &hreq->headers,
1264 "application/x-www-form-urlencoded",
1269 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1270 ODR odr, const char *charset)
1272 Z_SOAP_Handler handlers[3] = {
1274 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1275 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1279 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1281 z_HTTP_header_add_content_type(odr,
1283 "text/xml", charset);
1285 z_HTTP_header_add(odr, &hreq->headers,
1286 "SOAPAction", "\"\"");
1287 p->which = Z_SOAP_generic;
1288 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1289 p->u.generic->no = 0;
1290 p->u.generic->ns = 0;
1291 p->u.generic->p = srw_pdu;
1292 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1295 if (srw_pdu->which == Z_SRW_update_request ||
1296 srw_pdu->which == Z_SRW_update_response)
1297 p->u.generic->no = 1; /* second handler */
1299 return z_soap_codec_enc(odr, &p,
1301 &hreq->content_len, handlers,
1305 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1307 Z_SRW_recordVersion *ver
1308 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1310 for ( i=0; i < num; ++i ){
1311 ver[i].versionType = 0;
1312 ver[i].versionValue = 0;
1317 const char *yaz_srw_pack_to_str(int pack)
1321 case Z_SRW_recordPacking_string:
1323 case Z_SRW_recordPacking_XML:
1325 case Z_SRW_recordPacking_URL:
1331 int yaz_srw_str_to_pack(const char *str)
1333 if (!strcmp(str, "string"))
1334 return Z_SRW_recordPacking_string;
1335 if (!strcmp(str, "xml"))
1336 return Z_SRW_recordPacking_XML;
1337 if (!strcmp(str, "url"))
1338 return Z_SRW_recordPacking_URL;
1345 * indent-tabs-mode: nil
1347 * vim: shiftwidth=4 tabstop=8 expandtab