1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2013 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SRW/SRU utilities.
16 #include <yaz/matchstr.h>
17 #include <yaz/base64.h>
18 #include <yaz/yaz-iconv.h>
21 #define MAX_SRU_PARAMETERS 30
23 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
25 return odr_strdupn(n, uri, len);
28 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
35 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
37 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
38 yaz_encode_sru_dbpath_buf(dst, db);
42 Z_AttributeList *yaz_use_attribute_create(ODR o, const char *name)
44 Z_AttributeList *attributes= (Z_AttributeList *)
45 odr_malloc(o, sizeof(*attributes));
46 Z_AttributeElement ** elements;
47 attributes->num_attributes = 1;
48 elements = (Z_AttributeElement**)
49 odr_malloc(o, attributes->num_attributes * sizeof(*elements));
50 elements[0] = (Z_AttributeElement*) odr_malloc(o,sizeof(**elements));
51 elements[0]->attributeType = odr_intdup(o, 1);
52 elements[0]->attributeSet = odr_nullval();
53 elements[0]->which = Z_AttributeValue_complex;
54 elements[0]->value.complex = (Z_ComplexAttribute *)
55 odr_malloc(o, sizeof(Z_ComplexAttribute));
56 elements[0]->value.complex->num_list = 1;
57 elements[0]->value.complex->list = (Z_StringOrNumeric **)
58 odr_malloc(o, 1 * sizeof(Z_StringOrNumeric *));
59 elements[0]->value.complex->list[0] = (Z_StringOrNumeric *)
60 odr_malloc(o, sizeof(Z_StringOrNumeric));
61 elements[0]->value.complex->list[0]->which = Z_StringOrNumeric_string;
62 elements[0]->value.complex->list[0]->u.string = odr_strdup(o, name);
63 elements[0]->value.complex->semanticAction = 0;
64 elements[0]->value.complex->num_semanticAction = 0;
65 attributes->attributes = elements;
70 const char *yaz_element_attribute_value_get(xmlNodePtr ptr,
71 const char *node_name,
72 const char *attribute_name)
74 struct _xmlAttr *attr;
75 // check if the node name matches
76 if (strcmp((const char*) ptr->name, node_name))
78 // check if the attribute name and return the value
79 for (attr = ptr->properties; attr; attr = attr->next)
80 if (attr->children && attr->children->type == XML_TEXT_NODE)
82 if (!strcmp((const char *) attr->name, attribute_name))
83 return (const char *) attr->children->content;
89 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
91 const char *content_type = z_HTTP_header_lookup(hres->headers,
95 if (!yaz_strcmp_del("text/xml", content_type, "; "))
97 if (!yaz_strcmp_del("application/xml", content_type, "; "))
104 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
105 * parameters. Added by SH.
107 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
108 char *username, char *password, ODR decode)
110 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
113 sr->username = username;
115 sr->password = password;
121 char ubuf[256] = "", pbuf[256] = "", *p;
122 if (strncmp(basic, "Basic ", 6))
126 if (!len || len > 256)
128 yaz_base64decode(basic, out);
129 /* Format of out should be username:password at this point */
131 if ((p = strchr(ubuf, ':')))
138 sr->username = odr_strdup(decode, ubuf);
140 sr->password = odr_strdup(decode, pbuf);
144 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
146 const char *v = yaz_uri_val(path, name, o);
148 *intp = odr_intdup(o, atoi(v));
151 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
152 const char *uri, const char *message,
155 d->uri = odr_strdup(o, uri);
157 d->message = odr_strdup(o, message);
161 d->details = odr_strdup(o, details);
166 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
167 int code, const char *details)
171 sprintf(uri, "info:srw/diagnostic/1/%d", code);
172 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
175 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
176 int *num, const char *uri,
177 const char *message, const char *details)
179 Z_SRW_diagnostic *d_new;
180 d_new = (Z_SRW_diagnostic *) odr_malloc(o, (*num + 1)* sizeof(**d));
182 memcpy(d_new, *d, *num *sizeof(**d));
185 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
189 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
190 int *num, int code, const char *addinfo)
194 sprintf(uri, "info:srw/diagnostic/1/%d", code);
195 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
199 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
200 int *num, int code, const char *addinfo)
204 sprintf(uri, "info:srw/diagnostic/12/%d", code);
205 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
209 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
210 int code, const char *details)
212 const char *message = yaz_diag_srw_str(code);
215 len += strlen(message);
217 len += strlen(details);
219 record->recordData_buf = (char *) odr_malloc(o, len);
221 sprintf(record->recordData_buf, "<diagnostic "
222 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
223 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
225 sprintf(record->recordData_buf + strlen(record->recordData_buf),
226 " <details>%s</details>\n", details);
228 sprintf(record->recordData_buf + strlen(record->recordData_buf),
229 " <message>%s</message>\n", message);
230 sprintf(record->recordData_buf + strlen(record->recordData_buf),
232 record->recordData_len = strlen(record->recordData_buf);
233 record->recordPosition = odr_intdup(o, pos);
234 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
237 static void grab_charset(ODR o, const char *content_type, char **charset)
241 const char *charset_p = 0;
242 if (content_type && (charset_p = strstr(content_type, "; charset=")))
246 while (i < 20 && charset_p[i] &&
247 !strchr("; \n\r", charset_p[i]))
249 *charset = (char*) odr_malloc(o, i+1);
250 memcpy(*charset, charset_p, i);
251 (*charset)[i] = '\0';
256 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
257 Z_SOAP **soap_package, ODR decode, char **charset)
259 if (!strcmp(hreq->method, "POST"))
261 const char *content_type = z_HTTP_header_lookup(hreq->headers,
264 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
265 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
266 !yaz_strcmp_del("text/plain", content_type, "; ")))
268 char *db = "Default";
269 const char *p0 = hreq->path, *p1;
272 static Z_SOAP_Handler soap_handlers[5] = {
274 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
275 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
276 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
277 { YAZ_XMLNS_SRU_v2_mask, 0, (Z_SOAP_fun) yaz_srw_codec },
284 p1 = strchr(p0, '?');
286 p1 = p0 + strlen(p0);
288 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
289 grab_charset(decode, content_type, charset);
291 ret = z_soap_codec(decode, soap_package,
292 &hreq->content_buf, &hreq->content_len,
294 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
296 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
297 yaz_srw_decodeauth(*srw_pdu, hreq, 0, 0, decode);
299 /* last entry in handlers - SRU 2.0 - is turned into
300 offset 0.. due to other pieces relying on it */
301 if ((*soap_package)->u.generic->no == 3)
302 (*soap_package)->u.generic->no = 0;
303 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
304 (*srw_pdu)->u.request->database == 0)
305 (*srw_pdu)->u.request->database = db;
307 if ((*srw_pdu)->which == Z_SRW_explain_request &&
308 (*srw_pdu)->u.explain_request->database == 0)
309 (*srw_pdu)->u.explain_request->database = db;
311 if ((*srw_pdu)->which == Z_SRW_scan_request &&
312 (*srw_pdu)->u.scan_request->database == 0)
313 (*srw_pdu)->u.scan_request->database = db;
315 if ((*srw_pdu)->which == Z_SRW_update_request &&
316 (*srw_pdu)->u.update_request->database == 0)
317 (*srw_pdu)->u.update_request->database = db;
328 static int yaz_sru_decode_integer(ODR odr, const char *pname,
329 const char *valstr, Odr_int **valp,
330 Z_SRW_diagnostic **diag, int *num_diag,
336 if (sscanf(valstr, "%d", &ival) != 1)
338 yaz_add_srw_diagnostic(odr, diag, num_diag,
339 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
342 if (min_value >= 0 && ival < min_value)
344 yaz_add_srw_diagnostic(odr, diag, num_diag,
345 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
348 *valp = odr_intdup(odr, ival);
354 http://www.loc.gov/z3950/agency/zing/srw/service.html
356 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
357 Z_SOAP **soap_package, ODR decode, char **charset,
358 Z_SRW_diagnostic **diag, int *num_diag)
361 static Z_SOAP_Handler soap_handlers[2] = {
362 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
366 const char *content_type = z_HTTP_header_lookup(hreq->headers,
370 SRU GET: ignore content type.
371 SRU POST: we support "application/x-www-form-urlencoded";
372 not "multipart/form-data" .
374 if (!strcmp(hreq->method, "GET")
376 (!strcmp(hreq->method, "POST") && content_type &&
377 !yaz_strcmp_del("application/x-www-form-urlencoded",
378 content_type, "; ")))
380 char *db = "Default";
381 const char *p0 = hreq->path, *p1;
383 const char *operation = 0;
386 char *queryType = "cql";
390 char *stylesheet = 0;
391 char *scanClause = 0;
392 char *recordXPath = 0;
393 char *recordSchema = 0;
394 char *recordXMLEscaping = 0;
395 char *recordPacking = 0;
396 char *maximumRecords = 0;
397 char *startRecord = 0;
398 char *maximumTerms = 0;
399 char *responsePosition = 0;
400 Z_SRW_extra_arg *extra_args = 0;
405 grab_charset(decode, content_type, charset);
406 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
411 p1 = strchr(p0, '?');
413 p1 = p0 + strlen(p0);
415 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
416 if (!strcmp(hreq->method, "POST"))
417 p1 = hreq->content_buf;
418 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
423 for (i = 0; uri_name[i]; i++)
425 char *n = uri_name[i];
426 char *v = uri_val[i];
427 if (!strcmp(n, "query"))
429 else if (!strcmp(n, "x-pquery"))
434 else if (!strcmp(n, "queryType"))
436 else if (!strcmp(n, "x-username"))
438 else if (!strcmp(n, "x-password"))
440 else if (!strcmp(n, "operation"))
442 else if (!strcmp(n, "stylesheet"))
444 else if (!strcmp(n, "sortKeys"))
446 else if (!strcmp(n, "recordXPath"))
448 else if (!strcmp(n, "recordSchema"))
450 else if (!strcmp(n, "recordPacking"))
452 else if (!strcmp(n, "recordXMLEscaping"))
453 recordXMLEscaping = v;
454 else if (!strcmp(n, "version"))
456 else if (!strcmp(n, "scanClause"))
458 else if (!strcmp(n, "x-pScanClause"))
463 else if (!strcmp(n, "maximumRecords"))
465 else if (!strcmp(n, "startRecord"))
467 else if (!strcmp(n, "maximumTerms"))
469 else if (!strcmp(n, "responsePosition"))
470 responsePosition = v;
471 else if (!strcmp(n, "extraRequestData"))
472 ; /* ignoring extraRequestData */
473 else if (n[0] == 'x' && n[1] == '-')
475 Z_SRW_extra_arg **l = &extra_args;
478 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
479 (*l)->name = odr_strdup(decode, n);
480 (*l)->value = odr_strdup(decode, v);
486 yaz_add_srw_diagnostic(decode, diag, num_diag,
487 YAZ_SRW_UNSUPP_PARAMETER, n);
494 operation = "searchRetrieve";
498 version = yaz_negotiate_sru_version(version);
501 { /* negotiation failed. */
502 yaz_add_srw_diagnostic(decode, diag, num_diag,
503 YAZ_SRW_UNSUPP_VERSION, "2.0");
509 yaz_add_srw_diagnostic(
510 decode, diag, num_diag,
511 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
512 operation = "explain";
514 if (strcmp(version, "2.0"))
516 if (recordXMLEscaping)
518 yaz_add_srw_diagnostic(decode, diag, num_diag,
519 YAZ_SRW_UNSUPP_PARAMETER,
520 "recordXMLEscaping");
523 recordXMLEscaping = recordPacking;
524 recordPacking = "packed";
526 if (!recordXMLEscaping)
527 recordXMLEscaping = "xml";
528 if (!strcmp(operation, "searchRetrieve"))
530 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
532 sr->srw_version = version;
533 sr->extra_args = extra_args;
535 yaz_srw_decodeauth(sr, hreq, username, password, decode);
537 sr->u.request->queryType = queryType;
538 sr->u.request->query = query;
541 yaz_add_srw_diagnostic(
542 decode, diag, num_diag,
543 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
547 sr->u.request->sort_type = Z_SRW_sort_type_sort;
548 sr->u.request->sort.sortKeys = sortKeys;
550 sr->u.request->recordXPath = recordXPath;
551 sr->u.request->recordSchema = recordSchema;
552 sr->u.request->recordPacking = recordXMLEscaping;
553 sr->u.request->packing = recordPacking;
554 sr->u.request->stylesheet = stylesheet;
556 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
557 &sr->u.request->maximumRecords,
560 yaz_sru_decode_integer(decode, "startRecord", startRecord,
561 &sr->u.request->startRecord,
564 sr->u.request->database = db;
566 (*soap_package) = (Z_SOAP *)
567 odr_malloc(decode, sizeof(**soap_package));
568 (*soap_package)->which = Z_SOAP_generic;
570 (*soap_package)->u.generic = (Z_SOAP_Generic *)
571 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
573 (*soap_package)->u.generic->p = sr;
574 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
575 (*soap_package)->u.generic->no = 0;
577 (*soap_package)->ns = "SRU";
581 else if (!strcmp(operation, "explain"))
583 /* Transfer SRU explain parameters to common struct */
584 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
585 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
587 sr->srw_version = version;
588 sr->extra_args = extra_args;
589 yaz_srw_decodeauth(sr, hreq, username, password, decode);
591 sr->u.explain_request->recordPacking = recordXMLEscaping;
592 sr->u.explain_request->packing = recordPacking;
593 sr->u.explain_request->database = db;
595 sr->u.explain_request->stylesheet = stylesheet;
597 (*soap_package) = (Z_SOAP *)
598 odr_malloc(decode, sizeof(**soap_package));
599 (*soap_package)->which = Z_SOAP_generic;
601 (*soap_package)->u.generic = (Z_SOAP_Generic *)
602 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
604 (*soap_package)->u.generic->p = sr;
605 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
606 (*soap_package)->u.generic->no = 0;
608 (*soap_package)->ns = "SRU";
612 else if (!strcmp(operation, "scan"))
614 /* Transfer SRU scan parameters to common struct */
615 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
616 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
618 sr->srw_version = version;
619 sr->extra_args = extra_args;
621 yaz_srw_decodeauth(sr, hreq, username, password, decode);
623 sr->u.scan_request->queryType = queryType;
624 sr->u.scan_request->scanClause = scanClause;
627 yaz_add_srw_diagnostic(
628 decode, diag, num_diag,
629 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
630 sr->u.scan_request->database = db;
632 yaz_sru_decode_integer(decode, "maximumTerms",
634 &sr->u.scan_request->maximumTerms,
637 yaz_sru_decode_integer(decode, "responsePosition",
639 &sr->u.scan_request->responsePosition,
642 sr->u.scan_request->stylesheet = stylesheet;
644 (*soap_package) = (Z_SOAP *)
645 odr_malloc(decode, sizeof(**soap_package));
646 (*soap_package)->which = Z_SOAP_generic;
648 (*soap_package)->u.generic = (Z_SOAP_Generic *)
649 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
651 (*soap_package)->u.generic->p = sr;
652 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
653 (*soap_package)->u.generic->no = 0;
655 (*soap_package)->ns = "SRU";
661 /* unsupported operation ... */
662 /* Act as if we received a explain request and throw diagnostic. */
664 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
666 sr->srw_version = version;
668 sr->u.explain_request->recordPacking = recordPacking;
669 sr->u.explain_request->database = db;
671 sr->u.explain_request->stylesheet = stylesheet;
673 (*soap_package) = (Z_SOAP *)
674 odr_malloc(decode, sizeof(**soap_package));
675 (*soap_package)->which = Z_SOAP_generic;
677 (*soap_package)->u.generic = (Z_SOAP_Generic *)
678 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
680 (*soap_package)->u.generic->p = sr;
681 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
682 (*soap_package)->u.generic->no = 0;
684 (*soap_package)->ns = "SRU";
686 yaz_add_srw_diagnostic(decode, diag, num_diag,
687 YAZ_SRW_UNSUPP_OPERATION, operation);
697 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
699 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
700 odr_malloc(o, sizeof(*res));
702 res->extraRecordData_buf = 0;
703 res->extraRecordData_len = 0;
704 res->recordIdentifier = 0;
709 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
711 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
714 for (i = 0; i<n; i++)
716 res[i].recordSchema = 0;
717 res[i].recordPacking = Z_SRW_recordPacking_string;
718 res[i].recordData_buf = 0;
719 res[i].recordData_len = 0;
720 res[i].recordPosition = 0;
725 Z_SRW_record *yaz_srw_get_record(ODR o)
727 return yaz_srw_get_records(o, 1);
730 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
732 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
733 p->srw_version = odr_strdup(o, version);
737 p->extraResponseData_buf = 0;
738 p->extraResponseData_len = 0;
742 Z_SRW_PDU *yaz_srw_get_core_v_2_0(ODR o)
744 return yaz_srw_get_core_ver(o, "2.0");
747 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
749 return yaz_srw_get_pdu(o, which, "2.0");
752 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
754 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
759 case Z_SRW_searchRetrieve_request:
760 sr->u.request = (Z_SRW_searchRetrieveRequest *)
761 odr_malloc(o, sizeof(*sr->u.request));
762 sr->u.request->queryType = "cql";
763 sr->u.request->query = 0;
764 sr->u.request->sort_type = Z_SRW_sort_type_none;
765 sr->u.request->sort.none = 0;
766 sr->u.request->startRecord = 0;
767 sr->u.request->maximumRecords = 0;
768 sr->u.request->recordSchema = 0;
769 sr->u.request->recordPacking = 0;
770 sr->u.request->packing = 0;
771 sr->u.request->recordXPath = 0;
772 sr->u.request->database = 0;
773 sr->u.request->resultSetTTL = 0;
774 sr->u.request->stylesheet = 0;
775 sr->u.request->facetList = 0;
777 case Z_SRW_searchRetrieve_response:
778 sr->u.response = (Z_SRW_searchRetrieveResponse *)
779 odr_malloc(o, sizeof(*sr->u.response));
780 sr->u.response->numberOfRecords = 0;
781 sr->u.response->resultCountPrecision = 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;
790 sr->u.response->facetList = 0;
791 sr->u.response->suggestions = 0;
793 case Z_SRW_explain_request:
794 sr->u.explain_request = (Z_SRW_explainRequest *)
795 odr_malloc(o, sizeof(*sr->u.explain_request));
796 sr->u.explain_request->recordPacking = 0;
797 sr->u.explain_request->packing = 0;
798 sr->u.explain_request->database = 0;
799 sr->u.explain_request->stylesheet = 0;
801 case Z_SRW_explain_response:
802 sr->u.explain_response = (Z_SRW_explainResponse *)
803 odr_malloc(o, sizeof(*sr->u.explain_response));
804 sr->u.explain_response->record.recordData_buf = 0;
805 sr->u.explain_response->record.recordData_len = 0;
806 sr->u.explain_response->record.recordSchema = 0;
807 sr->u.explain_response->record.recordPosition = 0;
808 sr->u.explain_response->record.recordPacking =
809 Z_SRW_recordPacking_string;
810 sr->u.explain_response->diagnostics = 0;
811 sr->u.explain_response->num_diagnostics = 0;
812 sr->u.explain_response->extra_record = 0;
814 case Z_SRW_scan_request:
815 sr->u.scan_request = (Z_SRW_scanRequest *)
816 odr_malloc(o, sizeof(*sr->u.scan_request));
817 sr->u.scan_request->database = 0;
818 sr->u.scan_request->stylesheet = 0;
819 sr->u.scan_request->maximumTerms = 0;
820 sr->u.scan_request->responsePosition = 0;
821 sr->u.scan_request->queryType = "cql";
822 sr->u.scan_request->scanClause = 0;
824 case Z_SRW_scan_response:
825 sr->u.scan_response = (Z_SRW_scanResponse *)
826 odr_malloc(o, sizeof(*sr->u.scan_response));
827 sr->u.scan_response->terms = 0;
828 sr->u.scan_response->num_terms = 0;
829 sr->u.scan_response->diagnostics = 0;
830 sr->u.scan_response->num_diagnostics = 0;
832 case Z_SRW_update_request:
833 sr->u.update_request = (Z_SRW_updateRequest *)
834 odr_malloc(o, sizeof(*sr->u.update_request));
835 sr->u.update_request->database = 0;
836 sr->u.update_request->stylesheet = 0;
837 sr->u.update_request->record = 0;
838 sr->u.update_request->recordId = 0;
839 sr->u.update_request->recordVersions = 0;
840 sr->u.update_request->num_recordVersions = 0;
841 sr->u.update_request->extra_record = 0;
842 sr->u.update_request->extraRequestData_buf = 0;
843 sr->u.update_request->extraRequestData_len = 0;
844 sr->u.request->database = 0;
846 case Z_SRW_update_response:
847 sr->u.update_response = (Z_SRW_updateResponse *)
848 odr_malloc(o, sizeof(*sr->u.update_response));
849 sr->u.update_response->operationStatus = 0;
850 sr->u.update_response->recordId = 0;
851 sr->u.update_response->recordVersions = 0;
852 sr->u.update_response->num_recordVersions = 0;
853 sr->u.update_response->record = 0;
854 sr->u.update_response->extra_record = 0;
855 sr->u.update_response->extraResponseData_buf = 0;
856 sr->u.update_response->extraResponseData_len = 0;
857 sr->u.update_response->diagnostics = 0;
858 sr->u.update_response->num_diagnostics = 0;
863 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
864 char *a_name, Odr_int *val)
869 value[*i] = (char *) odr_malloc(o, 40);
870 sprintf(value[*i], ODR_INT_PRINTF, *val);
875 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
876 char *a_name, char *val)
886 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
887 char **name, char **value, int max_names)
889 int version2 = strcmp(srw_pdu->srw_version, "2.") > 0;
892 yaz_add_name_value_str(encode, name, value, &i, "version",
893 srw_pdu->srw_version);
894 name[i] = "operation";
895 switch (srw_pdu->which)
897 case Z_SRW_searchRetrieve_request:
898 value[i++] = "searchRetrieve";
899 queryType = srw_pdu->u.request->queryType;
902 if (queryType && strcmp(queryType, "cql"))
903 yaz_add_name_value_str(encode, name, value, &i, "queryType",
905 yaz_add_name_value_str(encode, name, value, &i, "query",
906 srw_pdu->u.request->query);
910 if (!strcmp(queryType, "cql"))
912 yaz_add_name_value_str(encode, name, value, &i, "query",
913 srw_pdu->u.request->query);
915 else if (!strcmp(queryType, "pqf"))
917 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
918 srw_pdu->u.request->query);
920 else if (!strcmp(queryType, "xcql"))
922 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
923 srw_pdu->u.request->query);
926 switch (srw_pdu->u.request->sort_type)
928 case Z_SRW_sort_type_none:
930 case Z_SRW_sort_type_sort:
931 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
932 srw_pdu->u.request->sort.sortKeys);
935 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
936 srw_pdu->u.request->startRecord);
937 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
938 srw_pdu->u.request->maximumRecords);
939 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
940 srw_pdu->u.request->recordSchema);
943 yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping",
944 srw_pdu->u.request->recordPacking);
945 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
946 srw_pdu->u.request->packing);
949 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
950 srw_pdu->u.request->recordPacking);
951 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
952 srw_pdu->u.request->recordXPath);
953 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
954 srw_pdu->u.request->stylesheet);
955 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
956 srw_pdu->u.request->resultSetTTL);
958 case Z_SRW_explain_request:
959 value[i++] = "explain";
963 yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping",
964 srw_pdu->u.explain_request->recordPacking);
965 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
966 srw_pdu->u.explain_request->packing);
969 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
970 srw_pdu->u.explain_request->recordPacking);
971 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
972 srw_pdu->u.explain_request->stylesheet);
974 case Z_SRW_scan_request:
976 queryType = srw_pdu->u.scan_request->queryType;
979 if (queryType && strcmp(queryType, "cql"))
980 yaz_add_name_value_str(encode, name, value, &i, "queryType",
982 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
983 srw_pdu->u.scan_request->scanClause);
987 if (!queryType || !strcmp(queryType, "cql"))
988 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
989 srw_pdu->u.scan_request->scanClause);
990 else if (!strcmp(queryType, "pqf"))
991 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
992 srw_pdu->u.scan_request->scanClause);
993 else if (!strcmp(queryType, "xcql"))
994 yaz_add_name_value_str(encode, name, value, &i,
996 srw_pdu->u.scan_request->scanClause);
998 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
999 srw_pdu->u.scan_request->responsePosition);
1000 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1001 srw_pdu->u.scan_request->maximumTerms);
1002 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1003 srw_pdu->u.scan_request->stylesheet);
1005 case Z_SRW_update_request:
1006 value[i++] = "update";
1011 if (srw_pdu->extra_args)
1013 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1014 for (; ea && i < max_names-1; ea = ea->next)
1017 value[i] = ea->value;
1026 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1027 ODR encode, const char *charset)
1029 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1033 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1034 srw_pdu->username, srw_pdu->password);
1035 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1037 yaz_array_to_uri(&uri_args, encode, name, value);
1039 hreq->method = "GET";
1042 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1044 sprintf(path, "%s?%s", hreq->path, uri_args);
1045 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1048 z_HTTP_header_add_content_type(encode, &hreq->headers,
1049 "text/xml", charset);
1053 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1054 ODR encode, const char *charset)
1056 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1059 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1060 srw_pdu->username, srw_pdu->password);
1061 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1064 yaz_array_to_uri(&uri_args, encode, name, value);
1066 hreq->method = "POST";
1068 hreq->content_buf = uri_args;
1069 hreq->content_len = strlen(uri_args);
1071 z_HTTP_header_add_content_type(encode, &hreq->headers,
1072 "application/x-www-form-urlencoded",
1077 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1078 ODR odr, const char *charset)
1080 Z_SOAP_Handler handlers[3] = {
1082 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1083 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1087 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1089 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1090 srw_pdu->username, srw_pdu->password);
1091 z_HTTP_header_add_content_type(odr,
1093 "text/xml", charset);
1095 z_HTTP_header_add(odr, &hreq->headers,
1096 "SOAPAction", "\"\"");
1097 p->which = Z_SOAP_generic;
1098 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1099 p->u.generic->no = 0;
1100 p->u.generic->ns = 0;
1101 p->u.generic->p = srw_pdu;
1102 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1105 if (srw_pdu->which == Z_SRW_update_request ||
1106 srw_pdu->which == Z_SRW_update_response)
1107 p->u.generic->no = 1; /* second handler */
1109 return z_soap_codec_enc(odr, &p,
1111 &hreq->content_len, handlers,
1115 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1117 Z_SRW_recordVersion *ver
1118 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1120 for (i = 0; i < num; ++i)
1122 ver[i].versionType = 0;
1123 ver[i].versionValue = 0;
1128 const char *yaz_srw_pack_to_str(int pack)
1132 case Z_SRW_recordPacking_string:
1134 case Z_SRW_recordPacking_XML:
1136 case Z_SRW_recordPacking_URL:
1142 int yaz_srw_str_to_pack(const char *str)
1144 if (!yaz_matchstr(str, "string"))
1145 return Z_SRW_recordPacking_string;
1146 if (!yaz_matchstr(str, "xml"))
1147 return Z_SRW_recordPacking_XML;
1148 if (!yaz_matchstr(str, "url"))
1149 return Z_SRW_recordPacking_URL;
1153 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1159 Z_SRW_extra_arg **ea = &sr->extra_args;
1160 yaz_uri_to_array(extra_args, odr, &name, &val);
1164 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1165 (*ea)->name = *name;
1166 (*ea)->value = *val;
1179 * c-file-style: "Stroustrup"
1180 * indent-tabs-mode: nil
1182 * vim: shiftwidth=4 tabstop=8 expandtab