2 * Copyright (C) 1995-2005, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.45 2006-07-06 10:17:54 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 void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
46 size_t i, szp = 0, sz = 0;
47 for(i = 0; name[i]; i++)
48 sz += strlen(name[i]) + 3 + strlen(value[i]) * 3;
49 *path = odr_malloc(o, sz);
51 for(i = 0; name[i]; i++)
56 ilen = strlen(name[i]);
57 memcpy(*path+szp, name[i], ilen);
60 for (j = 0; value[i][j]; j++)
64 encode_uri_char(vstr, value[i][j]);
66 memcpy(*path+szp, vstr, vlen);
73 int yaz_uri_array(const char *path, ODR o, char ***name, char ***val)
83 while ((cp = strchr(cp, '&')))
88 *name = odr_malloc(o, no * sizeof(char*));
89 *val = odr_malloc(o, no * sizeof(char*));
91 for (no = 0; *path; no++)
93 const char *p1 = strchr(path, '=');
99 (*name)[no] = odr_malloc(o, (p1-path)+1);
100 memcpy((*name)[no], path, p1-path);
101 (*name)[no][p1-path] = '\0';
104 p1 = strchr(path, '&');
106 p1 = strlen(path) + path;
107 (*val)[no] = ret = odr_malloc(o, p1 - path + 1);
108 while (*path && *path != '&')
115 else if (*path == '%' && path[1] && path[2])
117 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
133 char *yaz_uri_val(const char *path, const char *name, ODR o)
135 size_t nlen = strlen(name);
139 while (path && *path)
141 const char *p1 = strchr(path, '=');
144 if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
150 p1 = strchr(path, '&');
152 p1 = strlen(path) + path;
153 ret = (char *) odr_malloc(o, p1 - path + 1);
154 while (*path && *path != '&')
161 else if (*path == '%' && path[1] && path[2])
163 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
172 path = strchr(p1, '&');
179 static int yaz_base64decode(const char *in, char *out)
181 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
182 "abcdefghijklmnopqrstuvwxyz0123456789+/";
184 int len = strlen(in);
191 if (!(p = strchr(map, in[0])))
195 if (!(p = strchr(map, in[1])))
199 *(out++) = i0 << 2 | i1 >> 4;
203 if (!(p = strchr(map, in[2])))
207 *(out++) = i1 << 4 | i2 >> 2;
211 if (!(p = strchr(map, in[3])))
215 *(out++) = i2 << 6 | i3;
226 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
227 * parameters. Added by SH.
229 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq, char *username,
230 char *password, ODR decode)
232 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
235 sr->username = username;
237 sr->password = password;
242 char ubuf[256] = "", pbuf[256] = "", *p;
243 if (strncmp(basic, "Basic ", 6))
247 if (!len || len > 256)
249 olen = yaz_base64decode(basic, out);
250 /* Format of out should be username:password at this point */
252 if ((p = strchr(ubuf, ':'))) {
258 sr->username = odr_strdup(decode, ubuf);
260 sr->password = odr_strdup(decode, pbuf);
264 void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp)
266 const char *v = yaz_uri_val(path, name, o);
268 *intp = odr_intdup(o, atoi(v));
271 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
272 const char *uri, const char *message,
275 d->uri = odr_strdup(o, uri);
277 d->message = odr_strdup(o, message);
281 d->details = odr_strdup(o, details);
286 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
287 int code, const char *details)
291 sprintf(uri, "info:srw/diagnostic/1/%d", code);
292 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
295 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
296 int *num, const char *uri,
297 const char *message, const char *details)
299 Z_SRW_diagnostic *d_new;
300 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
302 memcpy (d_new, *d, *num *sizeof(**d));
305 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
309 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
310 int *num, int code, const char *addinfo)
314 sprintf(uri, "info:srw/diagnostic/1/%d", code);
315 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
318 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
319 Z_SOAP **soap_package, ODR decode, char **charset)
321 if (!strcmp(hreq->method, "POST"))
323 const char *content_type = z_HTTP_header_lookup(hreq->headers,
326 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
327 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
328 !yaz_strcmp_del("text/plain", content_type, "; ")))
330 char *db = "Default";
331 const char *p0 = hreq->path, *p1;
333 const char *charset_p = 0;
335 static Z_SOAP_Handler soap_handlers[4] = {
337 {"http://www.loc.gov/zing/srw/", 0,
338 (Z_SOAP_fun) yaz_srw_codec},
339 {"http://www.loc.gov/zing/srw/v1.0/", 0,
340 (Z_SOAP_fun) yaz_srw_codec},
341 {"http://www.loc.gov/zing/srw/update/", 0,
342 (Z_SOAP_fun) yaz_ucp_codec},
349 p1 = strchr(p0, '?');
351 p1 = p0 + strlen(p0);
354 db = (char*) odr_malloc(decode, p1 - p0 + 1);
355 memcpy (db, p0, p1 - p0);
359 if (charset && (charset_p = strstr(content_type, "; charset=")))
363 while (i < 20 && charset_p[i] &&
364 !strchr("; \n\r", charset_p[i]))
366 *charset = (char*) odr_malloc(decode, i+1);
367 memcpy(*charset, charset_p, i);
368 (*charset)[i] = '\0';
370 ret = z_soap_codec(decode, soap_package,
371 &hreq->content_buf, &hreq->content_len,
373 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
375 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
377 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
378 (*srw_pdu)->u.request->database == 0)
379 (*srw_pdu)->u.request->database = db;
381 if ((*srw_pdu)->which == Z_SRW_explain_request &&
382 (*srw_pdu)->u.explain_request->database == 0)
383 (*srw_pdu)->u.explain_request->database = db;
385 if ((*srw_pdu)->which == Z_SRW_scan_request &&
386 (*srw_pdu)->u.scan_request->database == 0)
387 (*srw_pdu)->u.scan_request->database = db;
389 if ((*srw_pdu)->which == Z_SRW_update_request &&
390 (*srw_pdu)->u.update_request->database == 0)
391 (*srw_pdu)->u.update_request->database = db;
401 static int yaz_sru_integer_decode(ODR odr, const char *pname,
402 const char *valstr, int **valp,
403 Z_SRW_diagnostic **diag, int *num_diag)
409 if (sscanf(valstr, "%d", &ival) != 1)
411 yaz_add_srw_diagnostic(odr, diag, num_diag,
412 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
415 *valp = odr_intdup(odr, ival);
419 http://www.loc.gov/z3950/agency/zing/srw/service.html
421 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
422 Z_SOAP **soap_package, ODR decode, char **charset,
423 Z_SRW_diagnostic **diag, int *num_diag)
426 static Z_SOAP_Handler soap_handlers[2] = {
427 {"http://www.loc.gov/zing/srw/", 0,
428 (Z_SOAP_fun) yaz_srw_codec},
432 const char *content_type = z_HTTP_header_lookup(hreq->headers,
435 SRU GET: allow any content type.
436 SRU POST: we support "application/x-www-form-urlencoded";
437 not "multipart/form-data" .
439 if (!strcmp(hreq->method, "GET")
441 (!strcmp(hreq->method, "POST")
443 !yaz_strcmp_del("application/x-www-form-urlencoded",
448 char *db = "Default";
449 const char *p0 = hreq->path, *p1;
451 const char *operation = 0;
458 char *stylesheet = 0;
459 char *scanClause = 0;
460 char *pScanClause = 0;
461 char *recordXPath = 0;
462 char *recordSchema = 0;
463 char *recordPacking = "xml"; /* xml packing is default for SRU */
464 char *maximumRecords = 0;
465 char *startRecord = 0;
466 char *maximumTerms = 0;
467 char *responsePosition = 0;
468 char *extraRequestData = 0;
477 p1 = strchr(p0, '?');
479 p1 = p0 + strlen(p0);
482 db = (char*) odr_malloc(decode, p1 - p0 + 1);
483 memcpy (db, p0, p1 - p0);
486 if (!strcmp(hreq->method, "POST"))
487 p1 = hreq->content_buf;
488 yaz_uri_array(p1, decode, &uri_name, &uri_val);
493 for (i = 0; uri_name[i]; i++)
495 char *n = uri_name[i];
496 char *v = uri_val[i];
497 if (!strcmp(n, "query"))
499 else if (!strcmp(n, "x-pquery"))
501 else if (!strcmp(n, "x-username"))
503 else if (!strcmp(n, "x-password"))
505 else if (!strcmp(n, "operation"))
507 else if (!strcmp(n, "stylesheet"))
509 else if (!strcmp(n, "sortKeys"))
511 else if (!strcmp(n, "recordXPath"))
513 else if (!strcmp(n, "recordSchema"))
515 else if (!strcmp(n, "recordPacking"))
517 else if (!strcmp(n, "version"))
519 else if (!strcmp(n, "scanClause"))
521 else if (!strcmp(n, "x-pScanClause"))
523 else if (!strcmp(n, "maximumRecords"))
525 else if (!strcmp(n, "startRecord"))
527 else if (!strcmp(n, "maximumTerms"))
529 else if (!strcmp(n, "responsePosition"))
530 responsePosition = v;
531 else if (!strcmp(n, "extraRequestData"))
532 extraRequestData = v;
534 yaz_add_srw_diagnostic(decode, diag, num_diag,
535 YAZ_SRW_UNSUPP_PARAMETER, n);
541 yaz_add_srw_diagnostic(
542 decode, diag, num_diag,
543 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
546 if (strcmp(version, "1.1"))
547 yaz_add_srw_diagnostic(decode, diag, num_diag,
548 YAZ_SRW_UNSUPP_VERSION, "1.1");
552 yaz_add_srw_diagnostic(
553 decode, diag, num_diag,
554 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
555 operation = "explain";
557 if (!strcmp(operation, "searchRetrieve"))
559 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
561 sr->srw_version = version;
563 yaz_srw_decodeauth(sr, hreq, username, password, decode);
566 sr->u.request->query_type = Z_SRW_query_type_cql;
567 sr->u.request->query.cql = query;
571 sr->u.request->query_type = Z_SRW_query_type_pqf;
572 sr->u.request->query.pqf = pQuery;
575 yaz_add_srw_diagnostic(
576 decode, diag, num_diag,
577 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
581 sr->u.request->sort_type = Z_SRW_sort_type_sort;
582 sr->u.request->sort.sortKeys = sortKeys;
584 sr->u.request->recordXPath = recordXPath;
585 sr->u.request->recordSchema = recordSchema;
586 sr->u.request->recordPacking = recordPacking;
587 sr->u.request->stylesheet = stylesheet;
589 yaz_sru_integer_decode(decode, "maximumRecords", maximumRecords,
590 &sr->u.request->maximumRecords,
593 yaz_sru_integer_decode(decode, "startRecord", startRecord,
594 &sr->u.request->startRecord,
597 sr->u.request->database = db;
599 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
600 (*soap_package)->which = Z_SOAP_generic;
602 (*soap_package)->u.generic =
603 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
605 (*soap_package)->u.generic->p = sr;
606 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
607 (*soap_package)->u.generic->no = 0;
609 (*soap_package)->ns = "SRU";
613 else if (!strcmp(operation, "explain"))
615 /* Transfer SRU explain parameters to common struct */
616 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
617 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
619 sr->srw_version = version;
620 yaz_srw_decodeauth(sr, hreq, username, password, decode);
622 sr->u.explain_request->recordPacking = recordPacking;
623 sr->u.explain_request->database = db;
625 sr->u.explain_request->stylesheet = stylesheet;
627 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
628 (*soap_package)->which = Z_SOAP_generic;
630 (*soap_package)->u.generic =
631 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
633 (*soap_package)->u.generic->p = sr;
634 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
635 (*soap_package)->u.generic->no = 0;
637 (*soap_package)->ns = "SRU";
641 else if (!strcmp(operation, "scan"))
643 /* Transfer SRU scan parameters to common struct */
644 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
645 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
647 sr->srw_version = version;
649 yaz_srw_decodeauth(sr, hreq, username, password, decode);
653 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
654 sr->u.scan_request->scanClause.cql = scanClause;
656 else if (pScanClause)
658 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
659 sr->u.scan_request->scanClause.pqf = pScanClause;
662 yaz_add_srw_diagnostic(
663 decode, diag, num_diag,
664 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
665 sr->u.scan_request->database = db;
667 yaz_sru_integer_decode(decode, "maximumTerms",
669 &sr->u.scan_request->maximumTerms,
672 yaz_sru_integer_decode(decode, "responsePosition",
674 &sr->u.scan_request->responsePosition,
677 sr->u.scan_request->stylesheet = stylesheet;
679 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
680 (*soap_package)->which = Z_SOAP_generic;
682 (*soap_package)->u.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";
695 /* unsupported operation ... */
696 /* Act as if we received a explain request and throw diagnostic. */
698 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
700 sr->srw_version = version;
702 sr->u.explain_request->recordPacking = recordPacking;
703 sr->u.explain_request->database = db;
705 sr->u.explain_request->stylesheet = stylesheet;
707 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
708 (*soap_package)->which = Z_SOAP_generic;
710 (*soap_package)->u.generic =
711 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
713 (*soap_package)->u.generic->p = sr;
714 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
715 (*soap_package)->u.generic->no = 0;
717 (*soap_package)->ns = "SRU";
719 yaz_add_srw_diagnostic(decode, diag, num_diag,
720 YAZ_SRW_UNSUPP_OPERATION, operation);
729 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
731 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
732 odr_malloc(o, sizeof(*res));
734 res->recordReviewCode = 0;
735 res->recordReviewNote = 0;
737 res->nonDupRecordId = 0;
738 res->recordLockStatus = 0;
739 res->recordOldVersion = 0;
743 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
745 Z_SRW_PDU *sr = (Z_SRW_PDU *) odr_malloc(o, sizeof(*o));
749 sr->srw_version = odr_strdup(o, "1.1");
753 case Z_SRW_searchRetrieve_request:
754 sr->u.request = (Z_SRW_searchRetrieveRequest *)
755 odr_malloc(o, sizeof(*sr->u.request));
756 sr->u.request->query_type = Z_SRW_query_type_cql;
757 sr->u.request->query.cql = 0;
758 sr->u.request->sort_type = Z_SRW_sort_type_none;
759 sr->u.request->sort.none = 0;
760 sr->u.request->startRecord = 0;
761 sr->u.request->maximumRecords = 0;
762 sr->u.request->recordSchema = 0;
763 sr->u.request->recordPacking = 0;
764 sr->u.request->recordXPath = 0;
765 sr->u.request->database = 0;
766 sr->u.request->resultSetTTL = 0;
767 sr->u.request->stylesheet = 0;
769 case Z_SRW_searchRetrieve_response:
770 sr->u.response = (Z_SRW_searchRetrieveResponse *)
771 odr_malloc(o, sizeof(*sr->u.response));
772 sr->u.response->numberOfRecords = 0;
773 sr->u.response->resultSetId = 0;
774 sr->u.response->resultSetIdleTime = 0;
775 sr->u.response->records = 0;
776 sr->u.response->num_records = 0;
777 sr->u.response->diagnostics = 0;
778 sr->u.response->num_diagnostics = 0;
779 sr->u.response->nextRecordPosition = 0;
780 sr->u.response->extra_records = 0;
782 case Z_SRW_explain_request:
783 sr->u.explain_request = (Z_SRW_explainRequest *)
784 odr_malloc(o, sizeof(*sr->u.explain_request));
785 sr->u.explain_request->recordPacking = 0;
786 sr->u.explain_request->database = 0;
787 sr->u.explain_request->stylesheet = 0;
789 case Z_SRW_explain_response:
790 sr->u.explain_response = (Z_SRW_explainResponse *)
791 odr_malloc(o, sizeof(*sr->u.explain_response));
792 sr->u.explain_response->record.recordData_buf = 0;
793 sr->u.explain_response->record.recordData_len = 0;
794 sr->u.explain_response->record.recordSchema = 0;
795 sr->u.explain_response->record.recordPosition = 0;
796 sr->u.explain_response->record.recordPacking =
797 Z_SRW_recordPacking_string;
798 sr->u.explain_response->diagnostics = 0;
799 sr->u.explain_response->num_diagnostics = 0;
800 sr->u.explain_response->extra_record = 0;
802 case Z_SRW_scan_request:
803 sr->u.scan_request = (Z_SRW_scanRequest *)
804 odr_malloc(o, sizeof(*sr->u.scan_request));
805 sr->u.scan_request->database = 0;
806 sr->u.scan_request->stylesheet = 0;
807 sr->u.scan_request->maximumTerms = 0;
808 sr->u.scan_request->responsePosition = 0;
809 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
810 sr->u.scan_request->scanClause.cql = 0;
812 case Z_SRW_scan_response:
813 sr->u.scan_response = (Z_SRW_scanResponse *)
814 odr_malloc(o, sizeof(*sr->u.scan_response));
815 sr->u.scan_response->terms = 0;
816 sr->u.scan_response->num_terms = 0;
817 sr->u.scan_response->diagnostics = 0;
818 sr->u.scan_response->num_diagnostics = 0;
820 case Z_SRW_update_request:
821 sr->u.update_request = (Z_SRW_updateRequest *)
822 odr_malloc(o, sizeof(*sr->u.update_request));
823 sr->u.update_request->database = 0;
824 sr->u.update_request->stylesheet = 0;
825 sr->u.update_request->record.recordSchema = 0;
826 sr->u.update_request->record.recordPacking = Z_SRW_recordPacking_XML;
827 sr->u.update_request->recordId = 0;
828 sr->u.update_request->recordVersion = 0;
829 sr->u.update_request->recordOldVersion = 0;
830 sr->u.update_request->record.recordData_buf = 0;
831 sr->u.update_request->record.recordData_len = 0;
832 sr->u.update_request->extra_record = 0;
833 sr->u.update_request->extraRequestData = 0;
834 sr->u.request->database = 0;
836 case Z_SRW_update_response:
837 sr->u.update_response = (Z_SRW_updateResponse *)
838 odr_malloc(o, sizeof(*sr->u.update_response));
839 sr->u.update_response->operationStatus = 0;
840 sr->u.update_response->recordId = 0;
841 sr->u.update_response->recordVersion = 0;
842 sr->u.update_response->recordChecksum = 0;
843 sr->u.update_response->record.recordData_buf = 0;
844 sr->u.update_response->record.recordData_len = 0;
845 sr->u.update_response->record.recordSchema = 0;
846 sr->u.update_response->record.recordPacking =
847 Z_SRW_recordPacking_XML;
848 sr->u.update_response->extra_record = 0;
849 sr->u.update_response->extraResponseData = 0;
850 sr->u.update_response->diagnostics = 0;
851 sr->u.update_response->num_diagnostics = 0;
857 static int srw_bib1_map[] = {
867 108, 10, /* Malformed query : Syntax error */
897 100, 1, /* bad map */
945 205, 1, /* bad map */
946 206, 1, /* bad map */
948 208, 1, /* bad map */
959 218, 1, /* bad map */
960 219, 1, /* bad map */
961 220, 1, /* bad map */
962 221, 1, /* bad map */
964 223, 1, /* bad map */
965 224, 1, /* bad map */
966 225, 1, /* bad map */
967 226, 1, /* bad map */
969 228, 1, /* bad map */
974 233, 1, /* bad map */
975 234, 1, /* bad map */
981 240, 1, /* bad map */
982 241, 1, /* bad map */
984 243, 1, /* bad map */
989 1001, 1, /* bad map */
990 1002, 1, /* bad map */
991 1003, 1, /* bad map */
992 1004, 1, /* bad map */
993 1005, 1, /* bad map */
994 1006, 1, /* bad map */
1026 int yaz_diag_bib1_to_srw (int code)
1028 const int *p = srw_bib1_map;
1038 int yaz_diag_srw_to_bib1(int code)
1040 const int *p = srw_bib1_map;
1050 static void add_val_int(ODR o, char **name, char **value, int *i,
1051 char *a_name, int *val)
1056 value[*i] = odr_malloc(o, 30);
1057 sprintf(value[*i], "%d", *val);
1062 static void add_val_str(ODR o, char **name, char **value, int *i,
1063 char *a_name, char *val)
1073 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1074 char **name, char **value)
1077 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1078 name[i] = "operation";
1079 switch(srw_pdu->which)
1081 case Z_SRW_searchRetrieve_request:
1082 value[i++] = "searchRetrieve";
1083 switch(srw_pdu->u.request->query_type)
1085 case Z_SRW_query_type_cql:
1086 add_val_str(encode, name, value, &i, "query",
1087 srw_pdu->u.request->query.cql);
1089 case Z_SRW_query_type_pqf:
1090 add_val_str(encode, name, value, &i, "x-pquery",
1091 srw_pdu->u.request->query.pqf);
1093 case Z_SRW_query_type_xcql:
1094 add_val_str(encode, name, value, &i, "x-cql",
1095 srw_pdu->u.request->query.xcql);
1098 switch(srw_pdu->u.request->sort_type)
1100 case Z_SRW_sort_type_none:
1102 case Z_SRW_sort_type_sort:
1103 add_val_str(encode, name, value, &i, "sortKeys",
1104 srw_pdu->u.request->sort.sortKeys);
1107 add_val_int(encode, name, value, &i, "startRecord",
1108 srw_pdu->u.request->startRecord);
1109 add_val_int(encode, name, value, &i, "maximumRecords",
1110 srw_pdu->u.request->maximumRecords);
1111 add_val_str(encode, name, value, &i, "recordSchema",
1112 srw_pdu->u.request->recordSchema);
1113 add_val_str(encode, name, value, &i, "recordPacking",
1114 srw_pdu->u.request->recordPacking);
1115 add_val_str(encode, name, value, &i, "recordXPath",
1116 srw_pdu->u.request->recordXPath);
1117 add_val_str(encode, name, value, &i, "stylesheet",
1118 srw_pdu->u.request->stylesheet);
1119 add_val_int(encode, name, value, &i, "resultSetTTL",
1120 srw_pdu->u.request->resultSetTTL);
1122 case Z_SRW_explain_request:
1123 value[i++] = "explain";
1124 add_val_str(encode, name, value, &i, "stylesheet",
1125 srw_pdu->u.explain_request->stylesheet);
1127 case Z_SRW_scan_request:
1128 value[i++] = "scan";
1130 switch(srw_pdu->u.scan_request->query_type)
1132 case Z_SRW_query_type_cql:
1133 add_val_str(encode, name, value, &i, "scanClause",
1134 srw_pdu->u.scan_request->scanClause.cql);
1136 case Z_SRW_query_type_pqf:
1137 add_val_str(encode, name, value, &i, "x-pScanClause",
1138 srw_pdu->u.scan_request->scanClause.pqf);
1140 case Z_SRW_query_type_xcql:
1141 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1142 srw_pdu->u.scan_request->scanClause.xcql);
1145 add_val_int(encode, name, value, &i, "responsePosition",
1146 srw_pdu->u.scan_request->responsePosition);
1147 add_val_int(encode, name, value, &i, "maximumTerms",
1148 srw_pdu->u.scan_request->maximumTerms);
1149 add_val_str(encode, name, value, &i, "stylesheet",
1150 srw_pdu->u.scan_request->stylesheet);
1152 case Z_SRW_update_request:
1153 value[i++] = "update";
1162 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1163 ODR encode, const char *charset)
1165 char *name[30], *value[30]; /* definite upper limit for SRU params */
1169 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1171 yaz_array_to_uri(&uri_args, encode, name, value);
1173 hreq->method = "GET";
1175 path = odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 3);
1176 sprintf(path, "%s?%s", hreq->path, uri_args);
1179 z_HTTP_header_add_content_type(encode, &hreq->headers,
1180 "text/xml", charset);
1184 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1185 ODR encode, const char *charset)
1187 char *name[30], *value[30]; /* definite upper limit for SRU params */
1190 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1193 yaz_array_to_uri(&uri_args, encode, name, value);
1195 hreq->method = "POST";
1197 hreq->content_buf = uri_args;
1198 hreq->content_len = strlen(uri_args);
1200 z_HTTP_header_add_content_type(encode, &hreq->headers,
1201 "application/x-www-form-urlencoded",
1206 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1207 ODR odr, const char *charset)
1209 Z_SOAP_Handler handlers[2] = {
1211 {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec},
1215 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1216 z_HTTP_header_add_content_type(odr,
1218 "text/xml", charset);
1220 z_HTTP_header_add(odr, &hreq->headers,
1221 "SOAPAction", "\"\"");
1222 p->which = Z_SOAP_generic;
1223 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1224 p->u.generic->no = 0;
1225 p->u.generic->ns = 0;
1226 p->u.generic->p = srw_pdu;
1227 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1229 return z_soap_codec_enc(odr, &p,
1231 &hreq->content_len, handlers,
1238 * indent-tabs-mode: nil
1240 * vim: shiftwidth=4 tabstop=8 expandtab