2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.59 2007-05-24 10:18:36 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");
597 if (strcmp(version, "1.1"))
598 yaz_add_srw_diagnostic(decode, diag, num_diag,
599 YAZ_SRW_UNSUPP_VERSION, "1.1");
603 yaz_add_srw_diagnostic(
604 decode, diag, num_diag,
605 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
606 operation = "explain";
608 if (!strcmp(operation, "searchRetrieve"))
610 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
612 sr->srw_version = version;
614 yaz_srw_decodeauth(sr, hreq, username, password, decode);
617 sr->u.request->query_type = Z_SRW_query_type_cql;
618 sr->u.request->query.cql = query;
622 sr->u.request->query_type = Z_SRW_query_type_pqf;
623 sr->u.request->query.pqf = pQuery;
626 yaz_add_srw_diagnostic(
627 decode, diag, num_diag,
628 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
632 sr->u.request->sort_type = Z_SRW_sort_type_sort;
633 sr->u.request->sort.sortKeys = sortKeys;
635 sr->u.request->recordXPath = recordXPath;
636 sr->u.request->recordSchema = recordSchema;
637 sr->u.request->recordPacking = recordPacking;
638 sr->u.request->stylesheet = stylesheet;
640 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
641 &sr->u.request->maximumRecords,
644 yaz_sru_decode_integer(decode, "startRecord", startRecord,
645 &sr->u.request->startRecord,
648 sr->u.request->database = db;
650 (*soap_package) = (Z_SOAP *)
651 odr_malloc(decode, sizeof(**soap_package));
652 (*soap_package)->which = Z_SOAP_generic;
654 (*soap_package)->u.generic = (Z_SOAP_Generic *)
655 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
657 (*soap_package)->u.generic->p = sr;
658 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
659 (*soap_package)->u.generic->no = 0;
661 (*soap_package)->ns = "SRU";
665 else if (!strcmp(operation, "explain"))
667 /* Transfer SRU explain parameters to common struct */
668 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
669 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
671 sr->srw_version = version;
672 yaz_srw_decodeauth(sr, hreq, username, password, decode);
674 sr->u.explain_request->recordPacking = recordPacking;
675 sr->u.explain_request->database = db;
677 sr->u.explain_request->stylesheet = stylesheet;
679 (*soap_package) = (Z_SOAP *)
680 odr_malloc(decode, sizeof(**soap_package));
681 (*soap_package)->which = Z_SOAP_generic;
683 (*soap_package)->u.generic = (Z_SOAP_Generic *)
684 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
686 (*soap_package)->u.generic->p = sr;
687 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
688 (*soap_package)->u.generic->no = 0;
690 (*soap_package)->ns = "SRU";
694 else if (!strcmp(operation, "scan"))
696 /* Transfer SRU scan parameters to common struct */
697 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
698 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
700 sr->srw_version = version;
702 yaz_srw_decodeauth(sr, hreq, username, password, decode);
706 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
707 sr->u.scan_request->scanClause.cql = scanClause;
709 else if (pScanClause)
711 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
712 sr->u.scan_request->scanClause.pqf = pScanClause;
715 yaz_add_srw_diagnostic(
716 decode, diag, num_diag,
717 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
718 sr->u.scan_request->database = db;
720 yaz_sru_decode_integer(decode, "maximumTerms",
722 &sr->u.scan_request->maximumTerms,
725 yaz_sru_decode_integer(decode, "responsePosition",
727 &sr->u.scan_request->responsePosition,
730 sr->u.scan_request->stylesheet = stylesheet;
732 (*soap_package) = (Z_SOAP *)
733 odr_malloc(decode, sizeof(**soap_package));
734 (*soap_package)->which = Z_SOAP_generic;
736 (*soap_package)->u.generic = (Z_SOAP_Generic *)
737 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
739 (*soap_package)->u.generic->p = sr;
740 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
741 (*soap_package)->u.generic->no = 0;
743 (*soap_package)->ns = "SRU";
749 /* unsupported operation ... */
750 /* Act as if we received a explain request and throw diagnostic. */
752 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
754 sr->srw_version = version;
756 sr->u.explain_request->recordPacking = recordPacking;
757 sr->u.explain_request->database = db;
759 sr->u.explain_request->stylesheet = stylesheet;
761 (*soap_package) = (Z_SOAP *)
762 odr_malloc(decode, sizeof(**soap_package));
763 (*soap_package)->which = Z_SOAP_generic;
765 (*soap_package)->u.generic = (Z_SOAP_Generic *)
766 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
768 (*soap_package)->u.generic->p = sr;
769 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
770 (*soap_package)->u.generic->no = 0;
772 (*soap_package)->ns = "SRU";
774 yaz_add_srw_diagnostic(decode, diag, num_diag,
775 YAZ_SRW_UNSUPP_OPERATION, operation);
784 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
786 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
787 odr_malloc(o, sizeof(*res));
789 res->extraRecordData_buf = 0;
790 res->extraRecordData_len = 0;
791 res->recordIdentifier = 0;
796 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
798 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
801 for (i = 0; i<n; i++)
803 res[i].recordSchema = 0;
804 res[i].recordPacking = Z_SRW_recordPacking_string;
805 res[i].recordData_buf = 0;
806 res[i].recordData_len = 0;
807 res[i].recordPosition = 0;
812 Z_SRW_record *yaz_srw_get_record(ODR o)
814 return yaz_srw_get_records(o, 1);
817 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
819 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
820 p->srw_version = odr_strdup(o, "1.1");
827 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
829 Z_SRW_PDU *sr = yaz_srw_get_core_v_1_1(o);
833 case Z_SRW_searchRetrieve_request:
834 sr->u.request = (Z_SRW_searchRetrieveRequest *)
835 odr_malloc(o, sizeof(*sr->u.request));
836 sr->u.request->query_type = Z_SRW_query_type_cql;
837 sr->u.request->query.cql = 0;
838 sr->u.request->sort_type = Z_SRW_sort_type_none;
839 sr->u.request->sort.none = 0;
840 sr->u.request->startRecord = 0;
841 sr->u.request->maximumRecords = 0;
842 sr->u.request->recordSchema = 0;
843 sr->u.request->recordPacking = 0;
844 sr->u.request->recordXPath = 0;
845 sr->u.request->database = 0;
846 sr->u.request->resultSetTTL = 0;
847 sr->u.request->stylesheet = 0;
849 case Z_SRW_searchRetrieve_response:
850 sr->u.response = (Z_SRW_searchRetrieveResponse *)
851 odr_malloc(o, sizeof(*sr->u.response));
852 sr->u.response->numberOfRecords = 0;
853 sr->u.response->resultSetId = 0;
854 sr->u.response->resultSetIdleTime = 0;
855 sr->u.response->records = 0;
856 sr->u.response->num_records = 0;
857 sr->u.response->diagnostics = 0;
858 sr->u.response->num_diagnostics = 0;
859 sr->u.response->nextRecordPosition = 0;
860 sr->u.response->extra_records = 0;
862 case Z_SRW_explain_request:
863 sr->u.explain_request = (Z_SRW_explainRequest *)
864 odr_malloc(o, sizeof(*sr->u.explain_request));
865 sr->u.explain_request->recordPacking = 0;
866 sr->u.explain_request->database = 0;
867 sr->u.explain_request->stylesheet = 0;
869 case Z_SRW_explain_response:
870 sr->u.explain_response = (Z_SRW_explainResponse *)
871 odr_malloc(o, sizeof(*sr->u.explain_response));
872 sr->u.explain_response->record.recordData_buf = 0;
873 sr->u.explain_response->record.recordData_len = 0;
874 sr->u.explain_response->record.recordSchema = 0;
875 sr->u.explain_response->record.recordPosition = 0;
876 sr->u.explain_response->record.recordPacking =
877 Z_SRW_recordPacking_string;
878 sr->u.explain_response->diagnostics = 0;
879 sr->u.explain_response->num_diagnostics = 0;
880 sr->u.explain_response->extra_record = 0;
882 case Z_SRW_scan_request:
883 sr->u.scan_request = (Z_SRW_scanRequest *)
884 odr_malloc(o, sizeof(*sr->u.scan_request));
885 sr->u.scan_request->database = 0;
886 sr->u.scan_request->stylesheet = 0;
887 sr->u.scan_request->maximumTerms = 0;
888 sr->u.scan_request->responsePosition = 0;
889 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
890 sr->u.scan_request->scanClause.cql = 0;
892 case Z_SRW_scan_response:
893 sr->u.scan_response = (Z_SRW_scanResponse *)
894 odr_malloc(o, sizeof(*sr->u.scan_response));
895 sr->u.scan_response->terms = 0;
896 sr->u.scan_response->num_terms = 0;
897 sr->u.scan_response->diagnostics = 0;
898 sr->u.scan_response->num_diagnostics = 0;
900 case Z_SRW_update_request:
901 sr->u.update_request = (Z_SRW_updateRequest *)
902 odr_malloc(o, sizeof(*sr->u.update_request));
903 sr->u.update_request->database = 0;
904 sr->u.update_request->stylesheet = 0;
905 sr->u.update_request->record = 0;
906 sr->u.update_request->recordId = 0;
907 sr->u.update_request->recordVersions = 0;
908 sr->u.update_request->num_recordVersions = 0;
909 sr->u.update_request->extra_record = 0;
910 sr->u.update_request->extraRequestData_buf = 0;
911 sr->u.update_request->extraRequestData_len = 0;
912 sr->u.request->database = 0;
914 case Z_SRW_update_response:
915 sr->u.update_response = (Z_SRW_updateResponse *)
916 odr_malloc(o, sizeof(*sr->u.update_response));
917 sr->u.update_response->operationStatus = 0;
918 sr->u.update_response->recordId = 0;
919 sr->u.update_response->recordVersions = 0;
920 sr->u.update_response->num_recordVersions = 0;
921 sr->u.update_response->record = 0;
922 sr->u.update_response->extra_record = 0;
923 sr->u.update_response->extraResponseData_buf = 0;
924 sr->u.update_response->extraResponseData_len = 0;
925 sr->u.update_response->diagnostics = 0;
926 sr->u.update_response->num_diagnostics = 0;
932 static int srw_bib1_map[] = {
942 108, 10, /* Malformed query : Syntax error */
972 100, 1, /* bad map */
1020 205, 1, /* bad map */
1021 206, 1, /* bad map */
1023 208, 1, /* bad map */
1034 218, 1, /* bad map */
1035 219, 1, /* bad map */
1036 220, 1, /* bad map */
1037 221, 1, /* bad map */
1039 223, 1, /* bad map */
1040 224, 1, /* bad map */
1041 225, 1, /* bad map */
1042 226, 1, /* bad map */
1044 228, 1, /* bad map */
1049 233, 1, /* bad map */
1050 234, 1, /* bad map */
1056 240, 1, /* bad map */
1057 241, 1, /* bad map */
1059 243, 1, /* bad map */
1064 1001, 1, /* bad map */
1065 1002, 1, /* bad map */
1066 1003, 1, /* bad map */
1067 1004, 1, /* bad map */
1068 1005, 1, /* bad map */
1069 1006, 1, /* bad map */
1101 int yaz_diag_bib1_to_srw (int code)
1103 const int *p = srw_bib1_map;
1113 int yaz_diag_srw_to_bib1(int code)
1115 const int *p = srw_bib1_map;
1125 static void add_val_int(ODR o, char **name, char **value, int *i,
1126 char *a_name, int *val)
1131 value[*i] = (char *) odr_malloc(o, 30);
1132 sprintf(value[*i], "%d", *val);
1137 static void add_val_str(ODR o, char **name, char **value, int *i,
1138 char *a_name, char *val)
1148 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1149 char **name, char **value)
1152 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1153 name[i] = "operation";
1154 switch(srw_pdu->which)
1156 case Z_SRW_searchRetrieve_request:
1157 value[i++] = "searchRetrieve";
1158 switch(srw_pdu->u.request->query_type)
1160 case Z_SRW_query_type_cql:
1161 add_val_str(encode, name, value, &i, "query",
1162 srw_pdu->u.request->query.cql);
1164 case Z_SRW_query_type_pqf:
1165 add_val_str(encode, name, value, &i, "x-pquery",
1166 srw_pdu->u.request->query.pqf);
1168 case Z_SRW_query_type_xcql:
1169 add_val_str(encode, name, value, &i, "x-cql",
1170 srw_pdu->u.request->query.xcql);
1173 switch(srw_pdu->u.request->sort_type)
1175 case Z_SRW_sort_type_none:
1177 case Z_SRW_sort_type_sort:
1178 add_val_str(encode, name, value, &i, "sortKeys",
1179 srw_pdu->u.request->sort.sortKeys);
1182 add_val_int(encode, name, value, &i, "startRecord",
1183 srw_pdu->u.request->startRecord);
1184 add_val_int(encode, name, value, &i, "maximumRecords",
1185 srw_pdu->u.request->maximumRecords);
1186 add_val_str(encode, name, value, &i, "recordSchema",
1187 srw_pdu->u.request->recordSchema);
1188 add_val_str(encode, name, value, &i, "recordPacking",
1189 srw_pdu->u.request->recordPacking);
1190 add_val_str(encode, name, value, &i, "recordXPath",
1191 srw_pdu->u.request->recordXPath);
1192 add_val_str(encode, name, value, &i, "stylesheet",
1193 srw_pdu->u.request->stylesheet);
1194 add_val_int(encode, name, value, &i, "resultSetTTL",
1195 srw_pdu->u.request->resultSetTTL);
1197 case Z_SRW_explain_request:
1198 value[i++] = "explain";
1199 add_val_str(encode, name, value, &i, "stylesheet",
1200 srw_pdu->u.explain_request->stylesheet);
1202 case Z_SRW_scan_request:
1203 value[i++] = "scan";
1205 switch(srw_pdu->u.scan_request->query_type)
1207 case Z_SRW_query_type_cql:
1208 add_val_str(encode, name, value, &i, "scanClause",
1209 srw_pdu->u.scan_request->scanClause.cql);
1211 case Z_SRW_query_type_pqf:
1212 add_val_str(encode, name, value, &i, "x-pScanClause",
1213 srw_pdu->u.scan_request->scanClause.pqf);
1215 case Z_SRW_query_type_xcql:
1216 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1217 srw_pdu->u.scan_request->scanClause.xcql);
1220 add_val_int(encode, name, value, &i, "responsePosition",
1221 srw_pdu->u.scan_request->responsePosition);
1222 add_val_int(encode, name, value, &i, "maximumTerms",
1223 srw_pdu->u.scan_request->maximumTerms);
1224 add_val_str(encode, name, value, &i, "stylesheet",
1225 srw_pdu->u.scan_request->stylesheet);
1227 case Z_SRW_update_request:
1228 value[i++] = "update";
1237 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1238 ODR encode, const char *charset)
1240 char *name[30], *value[30]; /* definite upper limit for SRU params */
1244 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1246 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1248 hreq->method = "GET";
1251 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4
1252 +(srw_pdu->extra_args ? strlen(srw_pdu->extra_args) : 0));
1254 sprintf(path, "%s?%s", hreq->path, uri_args);
1257 z_HTTP_header_add_content_type(encode, &hreq->headers,
1258 "text/xml", charset);
1262 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1263 ODR encode, const char *charset)
1265 char *name[30], *value[30]; /* definite upper limit for SRU params */
1268 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1271 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1273 hreq->method = "POST";
1275 hreq->content_buf = uri_args;
1276 hreq->content_len = strlen(uri_args);
1278 z_HTTP_header_add_content_type(encode, &hreq->headers,
1279 "application/x-www-form-urlencoded",
1284 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1285 ODR odr, const char *charset)
1287 Z_SOAP_Handler handlers[3] = {
1289 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1290 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1294 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1296 z_HTTP_header_add_content_type(odr,
1298 "text/xml", charset);
1300 z_HTTP_header_add(odr, &hreq->headers,
1301 "SOAPAction", "\"\"");
1302 p->which = Z_SOAP_generic;
1303 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1304 p->u.generic->no = 0;
1305 p->u.generic->ns = 0;
1306 p->u.generic->p = srw_pdu;
1307 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1310 if (srw_pdu->which == Z_SRW_update_request ||
1311 srw_pdu->which == Z_SRW_update_response)
1312 p->u.generic->no = 1; /* second handler */
1314 return z_soap_codec_enc(odr, &p,
1316 &hreq->content_len, handlers,
1320 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1322 Z_SRW_recordVersion *ver
1323 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1325 for ( i=0; i < num; ++i ){
1326 ver[i].versionType = 0;
1327 ver[i].versionValue = 0;
1332 const char *yaz_srw_pack_to_str(int pack)
1336 case Z_SRW_recordPacking_string:
1338 case Z_SRW_recordPacking_XML:
1340 case Z_SRW_recordPacking_URL:
1346 int yaz_srw_str_to_pack(const char *str)
1348 if (!yaz_matchstr(str, "string"))
1349 return Z_SRW_recordPacking_string;
1350 if (!yaz_matchstr(str, "xml"))
1351 return Z_SRW_recordPacking_XML;
1352 if (!yaz_matchstr(str, "url"))
1353 return Z_SRW_recordPacking_URL;
1360 * indent-tabs-mode: nil
1362 * vim: shiftwidth=4 tabstop=8 expandtab