2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.57 2007-05-23 11:54:47 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;
238 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
240 const char *content_type = z_HTTP_header_lookup(hres->headers,
244 if (!yaz_strcmp_del("text/xml", content_type, "; "))
246 if (!yaz_strcmp_del("application/xml", content_type, "; "))
253 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
254 * parameters. Added by SH.
256 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
257 char *username, char *password, ODR decode)
259 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
262 sr->username = username;
264 sr->password = password;
269 char ubuf[256] = "", pbuf[256] = "", *p;
270 if (strncmp(basic, "Basic ", 6))
274 if (!len || len > 256)
276 olen = yaz_base64decode(basic, out);
277 /* Format of out should be username:password at this point */
279 if ((p = strchr(ubuf, ':'))) {
285 sr->username = odr_strdup(decode, ubuf);
287 sr->password = odr_strdup(decode, pbuf);
291 void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp)
293 const char *v = yaz_uri_val(path, name, o);
295 *intp = odr_intdup(o, atoi(v));
298 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
299 const char *uri, const char *message,
302 d->uri = odr_strdup(o, uri);
304 d->message = odr_strdup(o, message);
308 d->details = odr_strdup(o, details);
313 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
314 int code, const char *details)
318 sprintf(uri, "info:srw/diagnostic/1/%d", code);
319 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
322 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
323 int *num, const char *uri,
324 const char *message, const char *details)
326 Z_SRW_diagnostic *d_new;
327 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
329 memcpy (d_new, *d, *num *sizeof(**d));
332 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
336 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
337 int *num, int code, const char *addinfo)
341 sprintf(uri, "info:srw/diagnostic/1/%d", code);
342 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
346 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
347 int *num, int code, const char *addinfo)
351 sprintf(uri, "info:srw/diagnostic/12/%d", code);
352 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
356 static void grab_charset(ODR o, const char *content_type, char **charset)
360 const char *charset_p = 0;
361 if (content_type && (charset_p = strstr(content_type, "; charset=")))
365 while (i < 20 && charset_p[i] &&
366 !strchr("; \n\r", charset_p[i]))
368 *charset = (char*) odr_malloc(o, i+1);
369 memcpy(*charset, charset_p, i);
370 (*charset)[i] = '\0';
375 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
376 Z_SOAP **soap_package, ODR decode, char **charset)
378 if (!strcmp(hreq->method, "POST"))
380 const char *content_type = z_HTTP_header_lookup(hreq->headers,
383 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
384 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
385 !yaz_strcmp_del("text/plain", content_type, "; ")))
387 char *db = "Default";
388 const char *p0 = hreq->path, *p1;
391 static Z_SOAP_Handler soap_handlers[4] = {
393 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
394 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
395 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
402 p1 = strchr(p0, '?');
404 p1 = p0 + strlen(p0);
407 db = (char*) odr_malloc(decode, p1 - p0 + 1);
408 memcpy (db, p0, p1 - p0);
412 grab_charset(decode, content_type, charset);
414 ret = z_soap_codec(decode, soap_package,
415 &hreq->content_buf, &hreq->content_len,
417 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
419 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
421 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
422 (*srw_pdu)->u.request->database == 0)
423 (*srw_pdu)->u.request->database = db;
425 if ((*srw_pdu)->which == Z_SRW_explain_request &&
426 (*srw_pdu)->u.explain_request->database == 0)
427 (*srw_pdu)->u.explain_request->database = db;
429 if ((*srw_pdu)->which == Z_SRW_scan_request &&
430 (*srw_pdu)->u.scan_request->database == 0)
431 (*srw_pdu)->u.scan_request->database = db;
433 if ((*srw_pdu)->which == Z_SRW_update_request &&
434 (*srw_pdu)->u.update_request->database == 0)
435 (*srw_pdu)->u.update_request->database = db;
445 static int yaz_sru_decode_integer(ODR odr, const char *pname,
446 const char *valstr, int **valp,
447 Z_SRW_diagnostic **diag, int *num_diag,
453 if (sscanf(valstr, "%d", &ival) != 1)
455 yaz_add_srw_diagnostic(odr, diag, num_diag,
456 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
459 if (min_value >= 0 && ival < min_value)
461 yaz_add_srw_diagnostic(odr, diag, num_diag,
462 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
465 *valp = odr_intdup(odr, ival);
470 http://www.loc.gov/z3950/agency/zing/srw/service.html
472 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
473 Z_SOAP **soap_package, ODR decode, char **charset,
474 Z_SRW_diagnostic **diag, int *num_diag)
477 static Z_SOAP_Handler soap_handlers[2] = {
478 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
482 const char *content_type = z_HTTP_header_lookup(hreq->headers,
486 SRU GET: ignore content type.
487 SRU POST: we support "application/x-www-form-urlencoded";
488 not "multipart/form-data" .
490 if (!strcmp(hreq->method, "GET")
492 (!strcmp(hreq->method, "POST") && content_type &&
493 !yaz_strcmp_del("application/x-www-form-urlencoded",
494 content_type, "; ")))
496 char *db = "Default";
497 const char *p0 = hreq->path, *p1;
499 const char *operation = 0;
506 char *stylesheet = 0;
507 char *scanClause = 0;
508 char *pScanClause = 0;
509 char *recordXPath = 0;
510 char *recordSchema = 0;
511 char *recordPacking = "xml"; /* xml packing is default for SRU */
512 char *maximumRecords = 0;
513 char *startRecord = 0;
514 char *maximumTerms = 0;
515 char *responsePosition = 0;
516 char *extraRequestData = 0;
521 grab_charset(decode, content_type, charset);
522 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
527 p1 = strchr(p0, '?');
529 p1 = p0 + strlen(p0);
532 db = (char*) odr_malloc(decode, p1 - p0 + 1);
533 memcpy (db, p0, p1 - p0);
536 if (!strcmp(hreq->method, "POST"))
537 p1 = hreq->content_buf;
538 yaz_uri_array(p1, decode, &uri_name, &uri_val);
543 for (i = 0; uri_name[i]; i++)
545 char *n = uri_name[i];
546 char *v = uri_val[i];
547 if (!strcmp(n, "query"))
549 else if (!strcmp(n, "x-pquery"))
551 else if (!strcmp(n, "x-username"))
553 else if (!strcmp(n, "x-password"))
555 else if (!strcmp(n, "operation"))
557 else if (!strcmp(n, "stylesheet"))
559 else if (!strcmp(n, "sortKeys"))
561 else if (!strcmp(n, "recordXPath"))
563 else if (!strcmp(n, "recordSchema"))
565 else if (!strcmp(n, "recordPacking"))
567 else if (!strcmp(n, "version"))
569 else if (!strcmp(n, "scanClause"))
571 else if (!strcmp(n, "x-pScanClause"))
573 else if (!strcmp(n, "maximumRecords"))
575 else if (!strcmp(n, "startRecord"))
577 else if (!strcmp(n, "maximumTerms"))
579 else if (!strcmp(n, "responsePosition"))
580 responsePosition = v;
581 else if (!strcmp(n, "extraRequestData"))
582 extraRequestData = v;
584 yaz_add_srw_diagnostic(decode, diag, num_diag,
585 YAZ_SRW_UNSUPP_PARAMETER, n);
591 yaz_add_srw_diagnostic(
592 decode, diag, num_diag,
593 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
596 if (strcmp(version, "1.1"))
597 yaz_add_srw_diagnostic(decode, diag, num_diag,
598 YAZ_SRW_UNSUPP_VERSION, "1.1");
602 yaz_add_srw_diagnostic(
603 decode, diag, num_diag,
604 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
605 operation = "explain";
607 if (!strcmp(operation, "searchRetrieve"))
609 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
611 sr->srw_version = version;
613 yaz_srw_decodeauth(sr, hreq, username, password, decode);
616 sr->u.request->query_type = Z_SRW_query_type_cql;
617 sr->u.request->query.cql = query;
621 sr->u.request->query_type = Z_SRW_query_type_pqf;
622 sr->u.request->query.pqf = pQuery;
625 yaz_add_srw_diagnostic(
626 decode, diag, num_diag,
627 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
631 sr->u.request->sort_type = Z_SRW_sort_type_sort;
632 sr->u.request->sort.sortKeys = sortKeys;
634 sr->u.request->recordXPath = recordXPath;
635 sr->u.request->recordSchema = recordSchema;
636 sr->u.request->recordPacking = recordPacking;
637 sr->u.request->stylesheet = stylesheet;
639 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
640 &sr->u.request->maximumRecords,
643 yaz_sru_decode_integer(decode, "startRecord", startRecord,
644 &sr->u.request->startRecord,
647 sr->u.request->database = db;
649 (*soap_package) = (Z_SOAP *)
650 odr_malloc(decode, sizeof(**soap_package));
651 (*soap_package)->which = Z_SOAP_generic;
653 (*soap_package)->u.generic = (Z_SOAP_Generic *)
654 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
656 (*soap_package)->u.generic->p = sr;
657 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
658 (*soap_package)->u.generic->no = 0;
660 (*soap_package)->ns = "SRU";
664 else if (!strcmp(operation, "explain"))
666 /* Transfer SRU explain parameters to common struct */
667 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
668 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
670 sr->srw_version = version;
671 yaz_srw_decodeauth(sr, hreq, username, password, decode);
673 sr->u.explain_request->recordPacking = recordPacking;
674 sr->u.explain_request->database = db;
676 sr->u.explain_request->stylesheet = stylesheet;
678 (*soap_package) = (Z_SOAP *)
679 odr_malloc(decode, sizeof(**soap_package));
680 (*soap_package)->which = Z_SOAP_generic;
682 (*soap_package)->u.generic = (Z_SOAP_Generic *)
683 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
685 (*soap_package)->u.generic->p = sr;
686 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
687 (*soap_package)->u.generic->no = 0;
689 (*soap_package)->ns = "SRU";
693 else if (!strcmp(operation, "scan"))
695 /* Transfer SRU scan parameters to common struct */
696 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
697 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
699 sr->srw_version = version;
701 yaz_srw_decodeauth(sr, hreq, username, password, decode);
705 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
706 sr->u.scan_request->scanClause.cql = scanClause;
708 else if (pScanClause)
710 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
711 sr->u.scan_request->scanClause.pqf = pScanClause;
714 yaz_add_srw_diagnostic(
715 decode, diag, num_diag,
716 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
717 sr->u.scan_request->database = db;
719 yaz_sru_decode_integer(decode, "maximumTerms",
721 &sr->u.scan_request->maximumTerms,
724 yaz_sru_decode_integer(decode, "responsePosition",
726 &sr->u.scan_request->responsePosition,
729 sr->u.scan_request->stylesheet = stylesheet;
731 (*soap_package) = (Z_SOAP *)
732 odr_malloc(decode, sizeof(**soap_package));
733 (*soap_package)->which = Z_SOAP_generic;
735 (*soap_package)->u.generic = (Z_SOAP_Generic *)
736 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
738 (*soap_package)->u.generic->p = sr;
739 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
740 (*soap_package)->u.generic->no = 0;
742 (*soap_package)->ns = "SRU";
748 /* unsupported operation ... */
749 /* Act as if we received a explain request and throw diagnostic. */
751 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
753 sr->srw_version = version;
755 sr->u.explain_request->recordPacking = recordPacking;
756 sr->u.explain_request->database = db;
758 sr->u.explain_request->stylesheet = stylesheet;
760 (*soap_package) = (Z_SOAP *)
761 odr_malloc(decode, sizeof(**soap_package));
762 (*soap_package)->which = Z_SOAP_generic;
764 (*soap_package)->u.generic = (Z_SOAP_Generic *)
765 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
767 (*soap_package)->u.generic->p = sr;
768 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
769 (*soap_package)->u.generic->no = 0;
771 (*soap_package)->ns = "SRU";
773 yaz_add_srw_diagnostic(decode, diag, num_diag,
774 YAZ_SRW_UNSUPP_OPERATION, operation);
783 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
785 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
786 odr_malloc(o, sizeof(*res));
788 res->extraRecordData_buf = 0;
789 res->extraRecordData_len = 0;
790 res->recordIdentifier = 0;
795 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
797 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
800 for (i = 0; i<n; i++)
802 res[i].recordSchema = 0;
803 res[i].recordPacking = Z_SRW_recordPacking_string;
804 res[i].recordData_buf = 0;
805 res[i].recordData_len = 0;
806 res[i].recordPosition = 0;
811 Z_SRW_record *yaz_srw_get_record(ODR o)
813 return yaz_srw_get_records(o, 1);
816 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
818 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
819 p->srw_version = odr_strdup(o, "1.1");
826 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
828 Z_SRW_PDU *sr = yaz_srw_get_core_v_1_1(o);
832 case Z_SRW_searchRetrieve_request:
833 sr->u.request = (Z_SRW_searchRetrieveRequest *)
834 odr_malloc(o, sizeof(*sr->u.request));
835 sr->u.request->query_type = Z_SRW_query_type_cql;
836 sr->u.request->query.cql = 0;
837 sr->u.request->sort_type = Z_SRW_sort_type_none;
838 sr->u.request->sort.none = 0;
839 sr->u.request->startRecord = 0;
840 sr->u.request->maximumRecords = 0;
841 sr->u.request->recordSchema = 0;
842 sr->u.request->recordPacking = 0;
843 sr->u.request->recordXPath = 0;
844 sr->u.request->database = 0;
845 sr->u.request->resultSetTTL = 0;
846 sr->u.request->stylesheet = 0;
848 case Z_SRW_searchRetrieve_response:
849 sr->u.response = (Z_SRW_searchRetrieveResponse *)
850 odr_malloc(o, sizeof(*sr->u.response));
851 sr->u.response->numberOfRecords = 0;
852 sr->u.response->resultSetId = 0;
853 sr->u.response->resultSetIdleTime = 0;
854 sr->u.response->records = 0;
855 sr->u.response->num_records = 0;
856 sr->u.response->diagnostics = 0;
857 sr->u.response->num_diagnostics = 0;
858 sr->u.response->nextRecordPosition = 0;
859 sr->u.response->extra_records = 0;
861 case Z_SRW_explain_request:
862 sr->u.explain_request = (Z_SRW_explainRequest *)
863 odr_malloc(o, sizeof(*sr->u.explain_request));
864 sr->u.explain_request->recordPacking = 0;
865 sr->u.explain_request->database = 0;
866 sr->u.explain_request->stylesheet = 0;
868 case Z_SRW_explain_response:
869 sr->u.explain_response = (Z_SRW_explainResponse *)
870 odr_malloc(o, sizeof(*sr->u.explain_response));
871 sr->u.explain_response->record.recordData_buf = 0;
872 sr->u.explain_response->record.recordData_len = 0;
873 sr->u.explain_response->record.recordSchema = 0;
874 sr->u.explain_response->record.recordPosition = 0;
875 sr->u.explain_response->record.recordPacking =
876 Z_SRW_recordPacking_string;
877 sr->u.explain_response->diagnostics = 0;
878 sr->u.explain_response->num_diagnostics = 0;
879 sr->u.explain_response->extra_record = 0;
881 case Z_SRW_scan_request:
882 sr->u.scan_request = (Z_SRW_scanRequest *)
883 odr_malloc(o, sizeof(*sr->u.scan_request));
884 sr->u.scan_request->database = 0;
885 sr->u.scan_request->stylesheet = 0;
886 sr->u.scan_request->maximumTerms = 0;
887 sr->u.scan_request->responsePosition = 0;
888 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
889 sr->u.scan_request->scanClause.cql = 0;
891 case Z_SRW_scan_response:
892 sr->u.scan_response = (Z_SRW_scanResponse *)
893 odr_malloc(o, sizeof(*sr->u.scan_response));
894 sr->u.scan_response->terms = 0;
895 sr->u.scan_response->num_terms = 0;
896 sr->u.scan_response->diagnostics = 0;
897 sr->u.scan_response->num_diagnostics = 0;
899 case Z_SRW_update_request:
900 sr->u.update_request = (Z_SRW_updateRequest *)
901 odr_malloc(o, sizeof(*sr->u.update_request));
902 sr->u.update_request->database = 0;
903 sr->u.update_request->stylesheet = 0;
904 sr->u.update_request->record = 0;
905 sr->u.update_request->recordId = 0;
906 sr->u.update_request->recordVersions = 0;
907 sr->u.update_request->num_recordVersions = 0;
908 sr->u.update_request->extra_record = 0;
909 sr->u.update_request->extraRequestData_buf = 0;
910 sr->u.update_request->extraRequestData_len = 0;
911 sr->u.request->database = 0;
913 case Z_SRW_update_response:
914 sr->u.update_response = (Z_SRW_updateResponse *)
915 odr_malloc(o, sizeof(*sr->u.update_response));
916 sr->u.update_response->operationStatus = 0;
917 sr->u.update_response->recordId = 0;
918 sr->u.update_response->recordVersions = 0;
919 sr->u.update_response->num_recordVersions = 0;
920 sr->u.update_response->record = 0;
921 sr->u.update_response->extra_record = 0;
922 sr->u.update_response->extraResponseData_buf = 0;
923 sr->u.update_response->extraResponseData_len = 0;
924 sr->u.update_response->diagnostics = 0;
925 sr->u.update_response->num_diagnostics = 0;
931 static int srw_bib1_map[] = {
941 108, 10, /* Malformed query : Syntax error */
971 100, 1, /* bad map */
1019 205, 1, /* bad map */
1020 206, 1, /* bad map */
1022 208, 1, /* bad map */
1033 218, 1, /* bad map */
1034 219, 1, /* bad map */
1035 220, 1, /* bad map */
1036 221, 1, /* bad map */
1038 223, 1, /* bad map */
1039 224, 1, /* bad map */
1040 225, 1, /* bad map */
1041 226, 1, /* bad map */
1043 228, 1, /* bad map */
1048 233, 1, /* bad map */
1049 234, 1, /* bad map */
1055 240, 1, /* bad map */
1056 241, 1, /* bad map */
1058 243, 1, /* bad map */
1063 1001, 1, /* bad map */
1064 1002, 1, /* bad map */
1065 1003, 1, /* bad map */
1066 1004, 1, /* bad map */
1067 1005, 1, /* bad map */
1068 1006, 1, /* bad map */
1100 int yaz_diag_bib1_to_srw (int code)
1102 const int *p = srw_bib1_map;
1112 int yaz_diag_srw_to_bib1(int code)
1114 const int *p = srw_bib1_map;
1124 static void add_val_int(ODR o, char **name, char **value, int *i,
1125 char *a_name, int *val)
1130 value[*i] = (char *) odr_malloc(o, 30);
1131 sprintf(value[*i], "%d", *val);
1136 static void add_val_str(ODR o, char **name, char **value, int *i,
1137 char *a_name, char *val)
1147 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1148 char **name, char **value)
1151 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1152 name[i] = "operation";
1153 switch(srw_pdu->which)
1155 case Z_SRW_searchRetrieve_request:
1156 value[i++] = "searchRetrieve";
1157 switch(srw_pdu->u.request->query_type)
1159 case Z_SRW_query_type_cql:
1160 add_val_str(encode, name, value, &i, "query",
1161 srw_pdu->u.request->query.cql);
1163 case Z_SRW_query_type_pqf:
1164 add_val_str(encode, name, value, &i, "x-pquery",
1165 srw_pdu->u.request->query.pqf);
1167 case Z_SRW_query_type_xcql:
1168 add_val_str(encode, name, value, &i, "x-cql",
1169 srw_pdu->u.request->query.xcql);
1172 switch(srw_pdu->u.request->sort_type)
1174 case Z_SRW_sort_type_none:
1176 case Z_SRW_sort_type_sort:
1177 add_val_str(encode, name, value, &i, "sortKeys",
1178 srw_pdu->u.request->sort.sortKeys);
1181 add_val_int(encode, name, value, &i, "startRecord",
1182 srw_pdu->u.request->startRecord);
1183 add_val_int(encode, name, value, &i, "maximumRecords",
1184 srw_pdu->u.request->maximumRecords);
1185 add_val_str(encode, name, value, &i, "recordSchema",
1186 srw_pdu->u.request->recordSchema);
1187 add_val_str(encode, name, value, &i, "recordPacking",
1188 srw_pdu->u.request->recordPacking);
1189 add_val_str(encode, name, value, &i, "recordXPath",
1190 srw_pdu->u.request->recordXPath);
1191 add_val_str(encode, name, value, &i, "stylesheet",
1192 srw_pdu->u.request->stylesheet);
1193 add_val_int(encode, name, value, &i, "resultSetTTL",
1194 srw_pdu->u.request->resultSetTTL);
1196 case Z_SRW_explain_request:
1197 value[i++] = "explain";
1198 add_val_str(encode, name, value, &i, "stylesheet",
1199 srw_pdu->u.explain_request->stylesheet);
1201 case Z_SRW_scan_request:
1202 value[i++] = "scan";
1204 switch(srw_pdu->u.scan_request->query_type)
1206 case Z_SRW_query_type_cql:
1207 add_val_str(encode, name, value, &i, "scanClause",
1208 srw_pdu->u.scan_request->scanClause.cql);
1210 case Z_SRW_query_type_pqf:
1211 add_val_str(encode, name, value, &i, "x-pScanClause",
1212 srw_pdu->u.scan_request->scanClause.pqf);
1214 case Z_SRW_query_type_xcql:
1215 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1216 srw_pdu->u.scan_request->scanClause.xcql);
1219 add_val_int(encode, name, value, &i, "responsePosition",
1220 srw_pdu->u.scan_request->responsePosition);
1221 add_val_int(encode, name, value, &i, "maximumTerms",
1222 srw_pdu->u.scan_request->maximumTerms);
1223 add_val_str(encode, name, value, &i, "stylesheet",
1224 srw_pdu->u.scan_request->stylesheet);
1226 case Z_SRW_update_request:
1227 value[i++] = "update";
1236 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1237 ODR encode, const char *charset)
1239 char *name[30], *value[30]; /* definite upper limit for SRU params */
1243 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1245 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1247 hreq->method = "GET";
1250 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4
1251 +(srw_pdu->extra_args ? strlen(srw_pdu->extra_args) : 0));
1253 sprintf(path, "%s?%s", hreq->path, uri_args);
1256 z_HTTP_header_add_content_type(encode, &hreq->headers,
1257 "text/xml", charset);
1261 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1262 ODR encode, const char *charset)
1264 char *name[30], *value[30]; /* definite upper limit for SRU params */
1267 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1270 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1272 hreq->method = "POST";
1274 hreq->content_buf = uri_args;
1275 hreq->content_len = strlen(uri_args);
1277 z_HTTP_header_add_content_type(encode, &hreq->headers,
1278 "application/x-www-form-urlencoded",
1283 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1284 ODR odr, const char *charset)
1286 Z_SOAP_Handler handlers[3] = {
1288 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1289 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1293 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1295 z_HTTP_header_add_content_type(odr,
1297 "text/xml", charset);
1299 z_HTTP_header_add(odr, &hreq->headers,
1300 "SOAPAction", "\"\"");
1301 p->which = Z_SOAP_generic;
1302 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1303 p->u.generic->no = 0;
1304 p->u.generic->ns = 0;
1305 p->u.generic->p = srw_pdu;
1306 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1309 if (srw_pdu->which == Z_SRW_update_request ||
1310 srw_pdu->which == Z_SRW_update_response)
1311 p->u.generic->no = 1; /* second handler */
1313 return z_soap_codec_enc(odr, &p,
1315 &hreq->content_len, handlers,
1319 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1321 Z_SRW_recordVersion *ver
1322 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1324 for ( i=0; i < num; ++i ){
1325 ver[i].versionType = 0;
1326 ver[i].versionValue = 0;
1331 const char *yaz_srw_pack_to_str(int pack)
1335 case Z_SRW_recordPacking_string:
1337 case Z_SRW_recordPacking_XML:
1339 case Z_SRW_recordPacking_URL:
1345 int yaz_srw_str_to_pack(const char *str)
1347 if (!strcmp(str, "string"))
1348 return Z_SRW_recordPacking_string;
1349 if (!strcmp(str, "xml"))
1350 return Z_SRW_recordPacking_XML;
1351 if (!strcmp(str, "url"))
1352 return Z_SRW_recordPacking_URL;
1359 * indent-tabs-mode: nil
1361 * vim: shiftwidth=4 tabstop=8 expandtab