2 * Copyright (C) 1995-2006, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.54 2006-12-06 21:35:58 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 = 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 = odr_malloc(o, no * sizeof(char*));
102 *val = odr_malloc(o, no * sizeof(char*));
104 for (no = 0; *path; no++)
106 const char *p1 = strchr(path, '=');
112 (*name)[no] = 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 = 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) = odr_malloc(decode, sizeof(**soap_package));
636 (*soap_package)->which = Z_SOAP_generic;
638 (*soap_package)->u.generic =
639 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
641 (*soap_package)->u.generic->p = sr;
642 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
643 (*soap_package)->u.generic->no = 0;
645 (*soap_package)->ns = "SRU";
649 else if (!strcmp(operation, "explain"))
651 /* Transfer SRU explain parameters to common struct */
652 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
653 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
655 sr->srw_version = version;
656 yaz_srw_decodeauth(sr, hreq, username, password, decode);
658 sr->u.explain_request->recordPacking = recordPacking;
659 sr->u.explain_request->database = db;
661 sr->u.explain_request->stylesheet = stylesheet;
663 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
664 (*soap_package)->which = Z_SOAP_generic;
666 (*soap_package)->u.generic =
667 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
669 (*soap_package)->u.generic->p = sr;
670 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
671 (*soap_package)->u.generic->no = 0;
673 (*soap_package)->ns = "SRU";
677 else if (!strcmp(operation, "scan"))
679 /* Transfer SRU scan parameters to common struct */
680 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
681 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
683 sr->srw_version = version;
685 yaz_srw_decodeauth(sr, hreq, username, password, decode);
689 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
690 sr->u.scan_request->scanClause.cql = scanClause;
692 else if (pScanClause)
694 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
695 sr->u.scan_request->scanClause.pqf = pScanClause;
698 yaz_add_srw_diagnostic(
699 decode, diag, num_diag,
700 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
701 sr->u.scan_request->database = db;
703 yaz_sru_decode_integer(decode, "maximumTerms",
705 &sr->u.scan_request->maximumTerms,
708 yaz_sru_decode_integer(decode, "responsePosition",
710 &sr->u.scan_request->responsePosition,
713 sr->u.scan_request->stylesheet = stylesheet;
715 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
716 (*soap_package)->which = Z_SOAP_generic;
718 (*soap_package)->u.generic =
719 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
721 (*soap_package)->u.generic->p = sr;
722 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
723 (*soap_package)->u.generic->no = 0;
725 (*soap_package)->ns = "SRU";
731 /* unsupported operation ... */
732 /* Act as if we received a explain request and throw diagnostic. */
734 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
736 sr->srw_version = version;
738 sr->u.explain_request->recordPacking = recordPacking;
739 sr->u.explain_request->database = db;
741 sr->u.explain_request->stylesheet = stylesheet;
743 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
744 (*soap_package)->which = Z_SOAP_generic;
746 (*soap_package)->u.generic =
747 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
749 (*soap_package)->u.generic->p = sr;
750 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
751 (*soap_package)->u.generic->no = 0;
753 (*soap_package)->ns = "SRU";
755 yaz_add_srw_diagnostic(decode, diag, num_diag,
756 YAZ_SRW_UNSUPP_OPERATION, operation);
765 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
767 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
768 odr_malloc(o, sizeof(*res));
770 res->extraRecordData_buf = 0;
771 res->extraRecordData_len = 0;
772 res->recordIdentifier = 0;
777 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
779 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
782 for (i = 0; i<n; i++)
784 res[i].recordSchema = 0;
785 res[i].recordPacking = Z_SRW_recordPacking_string;
786 res[i].recordData_buf = 0;
787 res[i].recordData_len = 0;
788 res[i].recordPosition = 0;
793 Z_SRW_record *yaz_srw_get_record(ODR o)
795 return yaz_srw_get_records(o, 1);
798 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
800 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
801 p->srw_version = odr_strdup(o, "1.1");
808 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
810 Z_SRW_PDU *sr = yaz_srw_get_core_v_1_1(o);
814 case Z_SRW_searchRetrieve_request:
815 sr->u.request = (Z_SRW_searchRetrieveRequest *)
816 odr_malloc(o, sizeof(*sr->u.request));
817 sr->u.request->query_type = Z_SRW_query_type_cql;
818 sr->u.request->query.cql = 0;
819 sr->u.request->sort_type = Z_SRW_sort_type_none;
820 sr->u.request->sort.none = 0;
821 sr->u.request->startRecord = 0;
822 sr->u.request->maximumRecords = 0;
823 sr->u.request->recordSchema = 0;
824 sr->u.request->recordPacking = 0;
825 sr->u.request->recordXPath = 0;
826 sr->u.request->database = 0;
827 sr->u.request->resultSetTTL = 0;
828 sr->u.request->stylesheet = 0;
830 case Z_SRW_searchRetrieve_response:
831 sr->u.response = (Z_SRW_searchRetrieveResponse *)
832 odr_malloc(o, sizeof(*sr->u.response));
833 sr->u.response->numberOfRecords = 0;
834 sr->u.response->resultSetId = 0;
835 sr->u.response->resultSetIdleTime = 0;
836 sr->u.response->records = 0;
837 sr->u.response->num_records = 0;
838 sr->u.response->diagnostics = 0;
839 sr->u.response->num_diagnostics = 0;
840 sr->u.response->nextRecordPosition = 0;
841 sr->u.response->extra_records = 0;
843 case Z_SRW_explain_request:
844 sr->u.explain_request = (Z_SRW_explainRequest *)
845 odr_malloc(o, sizeof(*sr->u.explain_request));
846 sr->u.explain_request->recordPacking = 0;
847 sr->u.explain_request->database = 0;
848 sr->u.explain_request->stylesheet = 0;
850 case Z_SRW_explain_response:
851 sr->u.explain_response = (Z_SRW_explainResponse *)
852 odr_malloc(o, sizeof(*sr->u.explain_response));
853 sr->u.explain_response->record.recordData_buf = 0;
854 sr->u.explain_response->record.recordData_len = 0;
855 sr->u.explain_response->record.recordSchema = 0;
856 sr->u.explain_response->record.recordPosition = 0;
857 sr->u.explain_response->record.recordPacking =
858 Z_SRW_recordPacking_string;
859 sr->u.explain_response->diagnostics = 0;
860 sr->u.explain_response->num_diagnostics = 0;
861 sr->u.explain_response->extra_record = 0;
863 case Z_SRW_scan_request:
864 sr->u.scan_request = (Z_SRW_scanRequest *)
865 odr_malloc(o, sizeof(*sr->u.scan_request));
866 sr->u.scan_request->database = 0;
867 sr->u.scan_request->stylesheet = 0;
868 sr->u.scan_request->maximumTerms = 0;
869 sr->u.scan_request->responsePosition = 0;
870 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
871 sr->u.scan_request->scanClause.cql = 0;
873 case Z_SRW_scan_response:
874 sr->u.scan_response = (Z_SRW_scanResponse *)
875 odr_malloc(o, sizeof(*sr->u.scan_response));
876 sr->u.scan_response->terms = 0;
877 sr->u.scan_response->num_terms = 0;
878 sr->u.scan_response->diagnostics = 0;
879 sr->u.scan_response->num_diagnostics = 0;
881 case Z_SRW_update_request:
882 sr->u.update_request = (Z_SRW_updateRequest *)
883 odr_malloc(o, sizeof(*sr->u.update_request));
884 sr->u.update_request->database = 0;
885 sr->u.update_request->stylesheet = 0;
886 sr->u.update_request->record = 0;
887 sr->u.update_request->recordId = 0;
888 sr->u.update_request->recordVersions = 0;
889 sr->u.update_request->num_recordVersions = 0;
890 sr->u.update_request->extra_record = 0;
891 sr->u.update_request->extraRequestData_buf = 0;
892 sr->u.update_request->extraRequestData_len = 0;
893 sr->u.request->database = 0;
895 case Z_SRW_update_response:
896 sr->u.update_response = (Z_SRW_updateResponse *)
897 odr_malloc(o, sizeof(*sr->u.update_response));
898 sr->u.update_response->operationStatus = 0;
899 sr->u.update_response->recordId = 0;
900 sr->u.update_response->recordVersions = 0;
901 sr->u.update_response->num_recordVersions = 0;
902 sr->u.update_response->record = 0;
903 sr->u.update_response->extra_record = 0;
904 sr->u.update_response->extraResponseData_buf = 0;
905 sr->u.update_response->extraResponseData_len = 0;
906 sr->u.update_response->diagnostics = 0;
907 sr->u.update_response->num_diagnostics = 0;
913 static int srw_bib1_map[] = {
923 108, 10, /* Malformed query : Syntax error */
953 100, 1, /* bad map */
1001 205, 1, /* bad map */
1002 206, 1, /* bad map */
1004 208, 1, /* bad map */
1015 218, 1, /* bad map */
1016 219, 1, /* bad map */
1017 220, 1, /* bad map */
1018 221, 1, /* bad map */
1020 223, 1, /* bad map */
1021 224, 1, /* bad map */
1022 225, 1, /* bad map */
1023 226, 1, /* bad map */
1025 228, 1, /* bad map */
1030 233, 1, /* bad map */
1031 234, 1, /* bad map */
1037 240, 1, /* bad map */
1038 241, 1, /* bad map */
1040 243, 1, /* bad map */
1045 1001, 1, /* bad map */
1046 1002, 1, /* bad map */
1047 1003, 1, /* bad map */
1048 1004, 1, /* bad map */
1049 1005, 1, /* bad map */
1050 1006, 1, /* bad map */
1082 int yaz_diag_bib1_to_srw (int code)
1084 const int *p = srw_bib1_map;
1094 int yaz_diag_srw_to_bib1(int code)
1096 const int *p = srw_bib1_map;
1106 static void add_val_int(ODR o, char **name, char **value, int *i,
1107 char *a_name, int *val)
1112 value[*i] = odr_malloc(o, 30);
1113 sprintf(value[*i], "%d", *val);
1118 static void add_val_str(ODR o, char **name, char **value, int *i,
1119 char *a_name, char *val)
1129 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1130 char **name, char **value)
1133 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1134 name[i] = "operation";
1135 switch(srw_pdu->which)
1137 case Z_SRW_searchRetrieve_request:
1138 value[i++] = "searchRetrieve";
1139 switch(srw_pdu->u.request->query_type)
1141 case Z_SRW_query_type_cql:
1142 add_val_str(encode, name, value, &i, "query",
1143 srw_pdu->u.request->query.cql);
1145 case Z_SRW_query_type_pqf:
1146 add_val_str(encode, name, value, &i, "x-pquery",
1147 srw_pdu->u.request->query.pqf);
1149 case Z_SRW_query_type_xcql:
1150 add_val_str(encode, name, value, &i, "x-cql",
1151 srw_pdu->u.request->query.xcql);
1154 switch(srw_pdu->u.request->sort_type)
1156 case Z_SRW_sort_type_none:
1158 case Z_SRW_sort_type_sort:
1159 add_val_str(encode, name, value, &i, "sortKeys",
1160 srw_pdu->u.request->sort.sortKeys);
1163 add_val_int(encode, name, value, &i, "startRecord",
1164 srw_pdu->u.request->startRecord);
1165 add_val_int(encode, name, value, &i, "maximumRecords",
1166 srw_pdu->u.request->maximumRecords);
1167 add_val_str(encode, name, value, &i, "recordSchema",
1168 srw_pdu->u.request->recordSchema);
1169 add_val_str(encode, name, value, &i, "recordPacking",
1170 srw_pdu->u.request->recordPacking);
1171 add_val_str(encode, name, value, &i, "recordXPath",
1172 srw_pdu->u.request->recordXPath);
1173 add_val_str(encode, name, value, &i, "stylesheet",
1174 srw_pdu->u.request->stylesheet);
1175 add_val_int(encode, name, value, &i, "resultSetTTL",
1176 srw_pdu->u.request->resultSetTTL);
1178 case Z_SRW_explain_request:
1179 value[i++] = "explain";
1180 add_val_str(encode, name, value, &i, "stylesheet",
1181 srw_pdu->u.explain_request->stylesheet);
1183 case Z_SRW_scan_request:
1184 value[i++] = "scan";
1186 switch(srw_pdu->u.scan_request->query_type)
1188 case Z_SRW_query_type_cql:
1189 add_val_str(encode, name, value, &i, "scanClause",
1190 srw_pdu->u.scan_request->scanClause.cql);
1192 case Z_SRW_query_type_pqf:
1193 add_val_str(encode, name, value, &i, "x-pScanClause",
1194 srw_pdu->u.scan_request->scanClause.pqf);
1196 case Z_SRW_query_type_xcql:
1197 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1198 srw_pdu->u.scan_request->scanClause.xcql);
1201 add_val_int(encode, name, value, &i, "responsePosition",
1202 srw_pdu->u.scan_request->responsePosition);
1203 add_val_int(encode, name, value, &i, "maximumTerms",
1204 srw_pdu->u.scan_request->maximumTerms);
1205 add_val_str(encode, name, value, &i, "stylesheet",
1206 srw_pdu->u.scan_request->stylesheet);
1208 case Z_SRW_update_request:
1209 value[i++] = "update";
1218 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1219 ODR encode, const char *charset)
1221 char *name[30], *value[30]; /* definite upper limit for SRU params */
1225 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1227 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1229 hreq->method = "GET";
1231 path = odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4
1232 +(srw_pdu->extra_args ? strlen(srw_pdu->extra_args) : 0)
1234 sprintf(path, "%s?%s", hreq->path, uri_args);
1237 z_HTTP_header_add_content_type(encode, &hreq->headers,
1238 "text/xml", charset);
1242 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1243 ODR encode, const char *charset)
1245 char *name[30], *value[30]; /* definite upper limit for SRU params */
1248 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1251 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1253 hreq->method = "POST";
1255 hreq->content_buf = uri_args;
1256 hreq->content_len = strlen(uri_args);
1258 z_HTTP_header_add_content_type(encode, &hreq->headers,
1259 "application/x-www-form-urlencoded",
1264 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1265 ODR odr, const char *charset)
1267 Z_SOAP_Handler handlers[3] = {
1269 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1270 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1274 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1276 z_HTTP_header_add_content_type(odr,
1278 "text/xml", charset);
1280 z_HTTP_header_add(odr, &hreq->headers,
1281 "SOAPAction", "\"\"");
1282 p->which = Z_SOAP_generic;
1283 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1284 p->u.generic->no = 0;
1285 p->u.generic->ns = 0;
1286 p->u.generic->p = srw_pdu;
1287 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1290 if (srw_pdu->which == Z_SRW_update_request ||
1291 srw_pdu->which == Z_SRW_update_response)
1292 p->u.generic->no = 1; /* second handler */
1294 return z_soap_codec_enc(odr, &p,
1296 &hreq->content_len, handlers,
1300 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1302 Z_SRW_recordVersion *ver
1303 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1305 for ( i=0; i < num; ++i ){
1306 ver[i].versionType = 0;
1307 ver[i].versionValue = 0;
1312 const char *yaz_srw_pack_to_str(int pack)
1316 case Z_SRW_recordPacking_string:
1318 case Z_SRW_recordPacking_XML:
1320 case Z_SRW_recordPacking_URL:
1326 int yaz_srw_str_to_pack(const char *str)
1328 if (!strcmp(str, "string"))
1329 return Z_SRW_recordPacking_string;
1330 if (!strcmp(str, "xml"))
1331 return Z_SRW_recordPacking_XML;
1332 if (!strcmp(str, "url"))
1333 return Z_SRW_recordPacking_URL;
1340 * indent-tabs-mode: nil
1342 * vim: shiftwidth=4 tabstop=8 expandtab