2 * Copyright (C) 1995-2006, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srwutil.c,v 1.46 2006-08-16 22:47:10 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 return 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);
331 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
332 Z_SOAP **soap_package, ODR decode, char **charset)
334 if (!strcmp(hreq->method, "POST"))
336 const char *content_type = z_HTTP_header_lookup(hreq->headers,
339 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
340 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
341 !yaz_strcmp_del("text/plain", content_type, "; ")))
343 char *db = "Default";
344 const char *p0 = hreq->path, *p1;
346 const char *charset_p = 0;
348 static Z_SOAP_Handler soap_handlers[4] = {
350 {"http://www.loc.gov/zing/srw/", 0,
351 (Z_SOAP_fun) yaz_srw_codec},
352 {"http://www.loc.gov/zing/srw/v1.0/", 0,
353 (Z_SOAP_fun) yaz_srw_codec},
354 {"http://www.loc.gov/zing/srw/update/", 0,
355 (Z_SOAP_fun) yaz_ucp_codec},
362 p1 = strchr(p0, '?');
364 p1 = p0 + strlen(p0);
367 db = (char*) odr_malloc(decode, p1 - p0 + 1);
368 memcpy (db, p0, p1 - p0);
372 if (charset && (charset_p = strstr(content_type, "; charset=")))
376 while (i < 20 && charset_p[i] &&
377 !strchr("; \n\r", charset_p[i]))
379 *charset = (char*) odr_malloc(decode, i+1);
380 memcpy(*charset, charset_p, i);
381 (*charset)[i] = '\0';
383 ret = z_soap_codec(decode, soap_package,
384 &hreq->content_buf, &hreq->content_len,
386 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
388 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
390 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
391 (*srw_pdu)->u.request->database == 0)
392 (*srw_pdu)->u.request->database = db;
394 if ((*srw_pdu)->which == Z_SRW_explain_request &&
395 (*srw_pdu)->u.explain_request->database == 0)
396 (*srw_pdu)->u.explain_request->database = db;
398 if ((*srw_pdu)->which == Z_SRW_scan_request &&
399 (*srw_pdu)->u.scan_request->database == 0)
400 (*srw_pdu)->u.scan_request->database = db;
402 if ((*srw_pdu)->which == Z_SRW_update_request &&
403 (*srw_pdu)->u.update_request->database == 0)
404 (*srw_pdu)->u.update_request->database = db;
414 static int yaz_sru_integer_decode(ODR odr, const char *pname,
415 const char *valstr, int **valp,
416 Z_SRW_diagnostic **diag, int *num_diag)
422 if (sscanf(valstr, "%d", &ival) != 1)
424 yaz_add_srw_diagnostic(odr, diag, num_diag,
425 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
428 *valp = odr_intdup(odr, ival);
432 http://www.loc.gov/z3950/agency/zing/srw/service.html
434 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
435 Z_SOAP **soap_package, ODR decode, char **charset,
436 Z_SRW_diagnostic **diag, int *num_diag)
439 static Z_SOAP_Handler soap_handlers[2] = {
440 {"http://www.loc.gov/zing/srw/", 0,
441 (Z_SOAP_fun) yaz_srw_codec},
445 const char *content_type = z_HTTP_header_lookup(hreq->headers,
448 SRU GET: allow any content type.
449 SRU POST: we support "application/x-www-form-urlencoded";
450 not "multipart/form-data" .
452 if (!strcmp(hreq->method, "GET")
454 (!strcmp(hreq->method, "POST")
456 !yaz_strcmp_del("application/x-www-form-urlencoded",
461 char *db = "Default";
462 const char *p0 = hreq->path, *p1;
464 const char *operation = 0;
471 char *stylesheet = 0;
472 char *scanClause = 0;
473 char *pScanClause = 0;
474 char *recordXPath = 0;
475 char *recordSchema = 0;
476 char *recordPacking = "xml"; /* xml packing is default for SRU */
477 char *maximumRecords = 0;
478 char *startRecord = 0;
479 char *maximumTerms = 0;
480 char *responsePosition = 0;
481 char *extraRequestData = 0;
490 p1 = strchr(p0, '?');
492 p1 = p0 + strlen(p0);
495 db = (char*) odr_malloc(decode, p1 - p0 + 1);
496 memcpy (db, p0, p1 - p0);
499 if (!strcmp(hreq->method, "POST"))
500 p1 = hreq->content_buf;
501 yaz_uri_array(p1, decode, &uri_name, &uri_val);
506 for (i = 0; uri_name[i]; i++)
508 char *n = uri_name[i];
509 char *v = uri_val[i];
510 if (!strcmp(n, "query"))
512 else if (!strcmp(n, "x-pquery"))
514 else if (!strcmp(n, "x-username"))
516 else if (!strcmp(n, "x-password"))
518 else if (!strcmp(n, "operation"))
520 else if (!strcmp(n, "stylesheet"))
522 else if (!strcmp(n, "sortKeys"))
524 else if (!strcmp(n, "recordXPath"))
526 else if (!strcmp(n, "recordSchema"))
528 else if (!strcmp(n, "recordPacking"))
530 else if (!strcmp(n, "version"))
532 else if (!strcmp(n, "scanClause"))
534 else if (!strcmp(n, "x-pScanClause"))
536 else if (!strcmp(n, "maximumRecords"))
538 else if (!strcmp(n, "startRecord"))
540 else if (!strcmp(n, "maximumTerms"))
542 else if (!strcmp(n, "responsePosition"))
543 responsePosition = v;
544 else if (!strcmp(n, "extraRequestData"))
545 extraRequestData = v;
547 yaz_add_srw_diagnostic(decode, diag, num_diag,
548 YAZ_SRW_UNSUPP_PARAMETER, n);
554 yaz_add_srw_diagnostic(
555 decode, diag, num_diag,
556 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
559 if (strcmp(version, "1.1"))
560 yaz_add_srw_diagnostic(decode, diag, num_diag,
561 YAZ_SRW_UNSUPP_VERSION, "1.1");
565 yaz_add_srw_diagnostic(
566 decode, diag, num_diag,
567 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
568 operation = "explain";
570 if (!strcmp(operation, "searchRetrieve"))
572 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
574 sr->srw_version = version;
576 yaz_srw_decodeauth(sr, hreq, username, password, decode);
579 sr->u.request->query_type = Z_SRW_query_type_cql;
580 sr->u.request->query.cql = query;
584 sr->u.request->query_type = Z_SRW_query_type_pqf;
585 sr->u.request->query.pqf = pQuery;
588 yaz_add_srw_diagnostic(
589 decode, diag, num_diag,
590 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
594 sr->u.request->sort_type = Z_SRW_sort_type_sort;
595 sr->u.request->sort.sortKeys = sortKeys;
597 sr->u.request->recordXPath = recordXPath;
598 sr->u.request->recordSchema = recordSchema;
599 sr->u.request->recordPacking = recordPacking;
600 sr->u.request->stylesheet = stylesheet;
602 yaz_sru_integer_decode(decode, "maximumRecords", maximumRecords,
603 &sr->u.request->maximumRecords,
606 yaz_sru_integer_decode(decode, "startRecord", startRecord,
607 &sr->u.request->startRecord,
610 sr->u.request->database = db;
612 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
613 (*soap_package)->which = Z_SOAP_generic;
615 (*soap_package)->u.generic =
616 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
618 (*soap_package)->u.generic->p = sr;
619 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
620 (*soap_package)->u.generic->no = 0;
622 (*soap_package)->ns = "SRU";
626 else if (!strcmp(operation, "explain"))
628 /* Transfer SRU explain parameters to common struct */
629 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
630 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
632 sr->srw_version = version;
633 yaz_srw_decodeauth(sr, hreq, username, password, decode);
635 sr->u.explain_request->recordPacking = recordPacking;
636 sr->u.explain_request->database = db;
638 sr->u.explain_request->stylesheet = stylesheet;
640 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
641 (*soap_package)->which = Z_SOAP_generic;
643 (*soap_package)->u.generic =
644 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
646 (*soap_package)->u.generic->p = sr;
647 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
648 (*soap_package)->u.generic->no = 0;
650 (*soap_package)->ns = "SRU";
654 else if (!strcmp(operation, "scan"))
656 /* Transfer SRU scan parameters to common struct */
657 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
658 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
660 sr->srw_version = version;
662 yaz_srw_decodeauth(sr, hreq, username, password, decode);
666 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
667 sr->u.scan_request->scanClause.cql = scanClause;
669 else if (pScanClause)
671 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
672 sr->u.scan_request->scanClause.pqf = pScanClause;
675 yaz_add_srw_diagnostic(
676 decode, diag, num_diag,
677 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
678 sr->u.scan_request->database = db;
680 yaz_sru_integer_decode(decode, "maximumTerms",
682 &sr->u.scan_request->maximumTerms,
685 yaz_sru_integer_decode(decode, "responsePosition",
687 &sr->u.scan_request->responsePosition,
690 sr->u.scan_request->stylesheet = stylesheet;
692 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
693 (*soap_package)->which = Z_SOAP_generic;
695 (*soap_package)->u.generic =
696 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
698 (*soap_package)->u.generic->p = sr;
699 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
700 (*soap_package)->u.generic->no = 0;
702 (*soap_package)->ns = "SRU";
708 /* unsupported operation ... */
709 /* Act as if we received a explain request and throw diagnostic. */
711 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
713 sr->srw_version = version;
715 sr->u.explain_request->recordPacking = recordPacking;
716 sr->u.explain_request->database = db;
718 sr->u.explain_request->stylesheet = stylesheet;
720 (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
721 (*soap_package)->which = Z_SOAP_generic;
723 (*soap_package)->u.generic =
724 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
726 (*soap_package)->u.generic->p = sr;
727 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
728 (*soap_package)->u.generic->no = 0;
730 (*soap_package)->ns = "SRU";
732 yaz_add_srw_diagnostic(decode, diag, num_diag,
733 YAZ_SRW_UNSUPP_OPERATION, operation);
742 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
744 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
745 odr_malloc(o, sizeof(*res));
747 res->recordReviewCode = 0;
748 res->recordReviewNote = 0;
750 res->nonDupRecordId = 0;
751 res->recordLockStatus = 0;
752 res->recordOldVersion = 0;
756 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
758 Z_SRW_PDU *sr = yaz_srw_get_core_v_1_1(o);
762 case Z_SRW_searchRetrieve_request:
763 sr->u.request = (Z_SRW_searchRetrieveRequest *)
764 odr_malloc(o, sizeof(*sr->u.request));
765 sr->u.request->query_type = Z_SRW_query_type_cql;
766 sr->u.request->query.cql = 0;
767 sr->u.request->sort_type = Z_SRW_sort_type_none;
768 sr->u.request->sort.none = 0;
769 sr->u.request->startRecord = 0;
770 sr->u.request->maximumRecords = 0;
771 sr->u.request->recordSchema = 0;
772 sr->u.request->recordPacking = 0;
773 sr->u.request->recordXPath = 0;
774 sr->u.request->database = 0;
775 sr->u.request->resultSetTTL = 0;
776 sr->u.request->stylesheet = 0;
778 case Z_SRW_searchRetrieve_response:
779 sr->u.response = (Z_SRW_searchRetrieveResponse *)
780 odr_malloc(o, sizeof(*sr->u.response));
781 sr->u.response->numberOfRecords = 0;
782 sr->u.response->resultSetId = 0;
783 sr->u.response->resultSetIdleTime = 0;
784 sr->u.response->records = 0;
785 sr->u.response->num_records = 0;
786 sr->u.response->diagnostics = 0;
787 sr->u.response->num_diagnostics = 0;
788 sr->u.response->nextRecordPosition = 0;
789 sr->u.response->extra_records = 0;
791 case Z_SRW_explain_request:
792 sr->u.explain_request = (Z_SRW_explainRequest *)
793 odr_malloc(o, sizeof(*sr->u.explain_request));
794 sr->u.explain_request->recordPacking = 0;
795 sr->u.explain_request->database = 0;
796 sr->u.explain_request->stylesheet = 0;
798 case Z_SRW_explain_response:
799 sr->u.explain_response = (Z_SRW_explainResponse *)
800 odr_malloc(o, sizeof(*sr->u.explain_response));
801 sr->u.explain_response->record.recordData_buf = 0;
802 sr->u.explain_response->record.recordData_len = 0;
803 sr->u.explain_response->record.recordSchema = 0;
804 sr->u.explain_response->record.recordPosition = 0;
805 sr->u.explain_response->record.recordPacking =
806 Z_SRW_recordPacking_string;
807 sr->u.explain_response->diagnostics = 0;
808 sr->u.explain_response->num_diagnostics = 0;
809 sr->u.explain_response->extra_record = 0;
811 case Z_SRW_scan_request:
812 sr->u.scan_request = (Z_SRW_scanRequest *)
813 odr_malloc(o, sizeof(*sr->u.scan_request));
814 sr->u.scan_request->database = 0;
815 sr->u.scan_request->stylesheet = 0;
816 sr->u.scan_request->maximumTerms = 0;
817 sr->u.scan_request->responsePosition = 0;
818 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
819 sr->u.scan_request->scanClause.cql = 0;
821 case Z_SRW_scan_response:
822 sr->u.scan_response = (Z_SRW_scanResponse *)
823 odr_malloc(o, sizeof(*sr->u.scan_response));
824 sr->u.scan_response->terms = 0;
825 sr->u.scan_response->num_terms = 0;
826 sr->u.scan_response->diagnostics = 0;
827 sr->u.scan_response->num_diagnostics = 0;
829 case Z_SRW_update_request:
830 sr->u.update_request = (Z_SRW_updateRequest *)
831 odr_malloc(o, sizeof(*sr->u.update_request));
832 sr->u.update_request->database = 0;
833 sr->u.update_request->stylesheet = 0;
834 sr->u.update_request->record.recordSchema = 0;
835 sr->u.update_request->record.recordPacking = Z_SRW_recordPacking_XML;
836 sr->u.update_request->recordId = 0;
837 sr->u.update_request->recordVersion = 0;
838 sr->u.update_request->recordOldVersion = 0;
839 sr->u.update_request->record.recordData_buf = 0;
840 sr->u.update_request->record.recordData_len = 0;
841 sr->u.update_request->extra_record = 0;
842 sr->u.update_request->extraRequestData = 0;
843 sr->u.request->database = 0;
845 case Z_SRW_update_response:
846 sr->u.update_response = (Z_SRW_updateResponse *)
847 odr_malloc(o, sizeof(*sr->u.update_response));
848 sr->u.update_response->operationStatus = 0;
849 sr->u.update_response->recordId = 0;
850 sr->u.update_response->recordVersion = 0;
851 sr->u.update_response->recordChecksum = 0;
852 sr->u.update_response->record.recordData_buf = 0;
853 sr->u.update_response->record.recordData_len = 0;
854 sr->u.update_response->record.recordSchema = 0;
855 sr->u.update_response->record.recordPacking =
856 Z_SRW_recordPacking_XML;
857 sr->u.update_response->extra_record = 0;
858 sr->u.update_response->extraResponseData = 0;
859 sr->u.update_response->diagnostics = 0;
860 sr->u.update_response->num_diagnostics = 0;
866 static int srw_bib1_map[] = {
876 108, 10, /* Malformed query : Syntax error */
906 100, 1, /* bad map */
954 205, 1, /* bad map */
955 206, 1, /* bad map */
957 208, 1, /* bad map */
968 218, 1, /* bad map */
969 219, 1, /* bad map */
970 220, 1, /* bad map */
971 221, 1, /* bad map */
973 223, 1, /* bad map */
974 224, 1, /* bad map */
975 225, 1, /* bad map */
976 226, 1, /* bad map */
978 228, 1, /* bad map */
983 233, 1, /* bad map */
984 234, 1, /* bad map */
990 240, 1, /* bad map */
991 241, 1, /* bad map */
993 243, 1, /* bad map */
998 1001, 1, /* bad map */
999 1002, 1, /* bad map */
1000 1003, 1, /* bad map */
1001 1004, 1, /* bad map */
1002 1005, 1, /* bad map */
1003 1006, 1, /* bad map */
1035 int yaz_diag_bib1_to_srw (int code)
1037 const int *p = srw_bib1_map;
1047 int yaz_diag_srw_to_bib1(int code)
1049 const int *p = srw_bib1_map;
1059 static void add_val_int(ODR o, char **name, char **value, int *i,
1060 char *a_name, int *val)
1065 value[*i] = odr_malloc(o, 30);
1066 sprintf(value[*i], "%d", *val);
1071 static void add_val_str(ODR o, char **name, char **value, int *i,
1072 char *a_name, char *val)
1082 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1083 char **name, char **value)
1086 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1087 name[i] = "operation";
1088 switch(srw_pdu->which)
1090 case Z_SRW_searchRetrieve_request:
1091 value[i++] = "searchRetrieve";
1092 switch(srw_pdu->u.request->query_type)
1094 case Z_SRW_query_type_cql:
1095 add_val_str(encode, name, value, &i, "query",
1096 srw_pdu->u.request->query.cql);
1098 case Z_SRW_query_type_pqf:
1099 add_val_str(encode, name, value, &i, "x-pquery",
1100 srw_pdu->u.request->query.pqf);
1102 case Z_SRW_query_type_xcql:
1103 add_val_str(encode, name, value, &i, "x-cql",
1104 srw_pdu->u.request->query.xcql);
1107 switch(srw_pdu->u.request->sort_type)
1109 case Z_SRW_sort_type_none:
1111 case Z_SRW_sort_type_sort:
1112 add_val_str(encode, name, value, &i, "sortKeys",
1113 srw_pdu->u.request->sort.sortKeys);
1116 add_val_int(encode, name, value, &i, "startRecord",
1117 srw_pdu->u.request->startRecord);
1118 add_val_int(encode, name, value, &i, "maximumRecords",
1119 srw_pdu->u.request->maximumRecords);
1120 add_val_str(encode, name, value, &i, "recordSchema",
1121 srw_pdu->u.request->recordSchema);
1122 add_val_str(encode, name, value, &i, "recordPacking",
1123 srw_pdu->u.request->recordPacking);
1124 add_val_str(encode, name, value, &i, "recordXPath",
1125 srw_pdu->u.request->recordXPath);
1126 add_val_str(encode, name, value, &i, "stylesheet",
1127 srw_pdu->u.request->stylesheet);
1128 add_val_int(encode, name, value, &i, "resultSetTTL",
1129 srw_pdu->u.request->resultSetTTL);
1131 case Z_SRW_explain_request:
1132 value[i++] = "explain";
1133 add_val_str(encode, name, value, &i, "stylesheet",
1134 srw_pdu->u.explain_request->stylesheet);
1136 case Z_SRW_scan_request:
1137 value[i++] = "scan";
1139 switch(srw_pdu->u.scan_request->query_type)
1141 case Z_SRW_query_type_cql:
1142 add_val_str(encode, name, value, &i, "scanClause",
1143 srw_pdu->u.scan_request->scanClause.cql);
1145 case Z_SRW_query_type_pqf:
1146 add_val_str(encode, name, value, &i, "x-pScanClause",
1147 srw_pdu->u.scan_request->scanClause.pqf);
1149 case Z_SRW_query_type_xcql:
1150 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1151 srw_pdu->u.scan_request->scanClause.xcql);
1154 add_val_int(encode, name, value, &i, "responsePosition",
1155 srw_pdu->u.scan_request->responsePosition);
1156 add_val_int(encode, name, value, &i, "maximumTerms",
1157 srw_pdu->u.scan_request->maximumTerms);
1158 add_val_str(encode, name, value, &i, "stylesheet",
1159 srw_pdu->u.scan_request->stylesheet);
1161 case Z_SRW_update_request:
1162 value[i++] = "update";
1171 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1172 ODR encode, const char *charset)
1174 char *name[30], *value[30]; /* definite upper limit for SRU params */
1178 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1180 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1182 hreq->method = "GET";
1184 path = odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4
1185 +(srw_pdu->extra_args ? strlen(srw_pdu->extra_args) : 0)
1187 sprintf(path, "%s?%s", hreq->path, uri_args);
1190 z_HTTP_header_add_content_type(encode, &hreq->headers,
1191 "text/xml", charset);
1195 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1196 ODR encode, const char *charset)
1198 char *name[30], *value[30]; /* definite upper limit for SRU params */
1201 if (yaz_get_sru_parms(srw_pdu, encode, name, value))
1204 yaz_array_to_uri_ex(&uri_args, encode, name, value, srw_pdu->extra_args);
1206 hreq->method = "POST";
1208 hreq->content_buf = uri_args;
1209 hreq->content_len = strlen(uri_args);
1211 z_HTTP_header_add_content_type(encode, &hreq->headers,
1212 "application/x-www-form-urlencoded",
1217 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1218 ODR odr, const char *charset)
1220 Z_SOAP_Handler handlers[2] = {
1222 {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec},
1226 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1227 z_HTTP_header_add_content_type(odr,
1229 "text/xml", charset);
1231 z_HTTP_header_add(odr, &hreq->headers,
1232 "SOAPAction", "\"\"");
1233 p->which = Z_SOAP_generic;
1234 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1235 p->u.generic->no = 0;
1236 p->u.generic->ns = 0;
1237 p->u.generic->p = srw_pdu;
1238 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1240 return z_soap_codec_enc(odr, &p,
1242 &hreq->content_len, handlers,
1249 * indent-tabs-mode: nil
1251 * vim: shiftwidth=4 tabstop=8 expandtab