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 const char *facetLimit = 0;
401 Z_SRW_extra_arg *extra_args = 0;
406 grab_charset(decode, content_type, charset);
407 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
412 p1 = strchr(p0, '?');
414 p1 = p0 + strlen(p0);
416 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
417 if (!strcmp(hreq->method, "POST"))
418 p1 = hreq->content_buf;
419 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
424 for (i = 0; uri_name[i]; i++)
426 char *n = uri_name[i];
427 char *v = uri_val[i];
428 if (!strcmp(n, "query"))
430 else if (!strcmp(n, "x-pquery"))
435 else if (!strcmp(n, "queryType"))
437 else if (!strcmp(n, "x-username"))
439 else if (!strcmp(n, "x-password"))
441 else if (!strcmp(n, "operation"))
443 else if (!strcmp(n, "stylesheet"))
445 else if (!strcmp(n, "sortKeys"))
447 else if (!strcmp(n, "recordXPath"))
449 else if (!strcmp(n, "recordSchema"))
451 else if (!strcmp(n, "recordPacking"))
453 else if (!strcmp(n, "recordXMLEscaping"))
454 recordXMLEscaping = v;
455 else if (!strcmp(n, "version"))
457 else if (!strcmp(n, "scanClause"))
459 else if (!strcmp(n, "x-pScanClause"))
464 else if (!strcmp(n, "maximumRecords"))
466 else if (!strcmp(n, "startRecord"))
468 else if (!strcmp(n, "maximumTerms"))
470 else if (!strcmp(n, "responsePosition"))
471 responsePosition = v;
472 else if (!strcmp(n, "facetLimit"))
474 else if (!strcmp(n, "extraRequestData"))
475 ; /* ignoring extraRequestData */
476 else if (n[0] == 'x' && n[1] == '-')
478 Z_SRW_extra_arg **l = &extra_args;
481 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
482 (*l)->name = odr_strdup(decode, n);
483 (*l)->value = odr_strdup(decode, v);
489 yaz_add_srw_diagnostic(decode, diag, num_diag,
490 YAZ_SRW_UNSUPP_PARAMETER, n);
497 operation = "searchRetrieve";
501 version = yaz_negotiate_sru_version(version);
504 { /* negotiation failed. */
505 yaz_add_srw_diagnostic(decode, diag, num_diag,
506 YAZ_SRW_UNSUPP_VERSION, "2.0");
512 yaz_add_srw_diagnostic(
513 decode, diag, num_diag,
514 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
515 operation = "explain";
517 if (strcmp(version, "2.0"))
519 if (recordXMLEscaping)
521 yaz_add_srw_diagnostic(decode, diag, num_diag,
522 YAZ_SRW_UNSUPP_PARAMETER,
523 "recordXMLEscaping");
526 recordXMLEscaping = recordPacking;
527 recordPacking = "packed";
529 if (!recordXMLEscaping)
530 recordXMLEscaping = "xml";
531 if (!strcmp(operation, "searchRetrieve"))
533 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
535 sr->srw_version = version;
536 sr->extra_args = extra_args;
538 yaz_srw_decodeauth(sr, hreq, username, password, decode);
540 sr->u.request->queryType = queryType;
541 sr->u.request->query = query;
544 yaz_add_srw_diagnostic(
545 decode, diag, num_diag,
546 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
550 sr->u.request->sort_type = Z_SRW_sort_type_sort;
551 sr->u.request->sort.sortKeys = sortKeys;
553 sr->u.request->recordXPath = recordXPath;
554 sr->u.request->recordSchema = recordSchema;
555 sr->u.request->recordPacking = recordXMLEscaping;
556 sr->u.request->packing = recordPacking;
557 sr->u.request->stylesheet = stylesheet;
558 yaz_sru_facet_request(decode , &sr->u.request->facetList,
561 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
562 &sr->u.request->maximumRecords,
565 yaz_sru_decode_integer(decode, "startRecord", startRecord,
566 &sr->u.request->startRecord,
569 sr->u.request->database = db;
571 (*soap_package) = (Z_SOAP *)
572 odr_malloc(decode, sizeof(**soap_package));
573 (*soap_package)->which = Z_SOAP_generic;
575 (*soap_package)->u.generic = (Z_SOAP_Generic *)
576 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
578 (*soap_package)->u.generic->p = sr;
579 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
580 (*soap_package)->u.generic->no = 0;
582 (*soap_package)->ns = "SRU";
586 else if (!strcmp(operation, "explain"))
588 /* Transfer SRU explain parameters to common struct */
589 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
590 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
592 sr->srw_version = version;
593 sr->extra_args = extra_args;
594 yaz_srw_decodeauth(sr, hreq, username, password, decode);
596 sr->u.explain_request->recordPacking = recordXMLEscaping;
597 sr->u.explain_request->packing = recordPacking;
598 sr->u.explain_request->database = db;
600 sr->u.explain_request->stylesheet = stylesheet;
602 (*soap_package) = (Z_SOAP *)
603 odr_malloc(decode, sizeof(**soap_package));
604 (*soap_package)->which = Z_SOAP_generic;
606 (*soap_package)->u.generic = (Z_SOAP_Generic *)
607 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
609 (*soap_package)->u.generic->p = sr;
610 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
611 (*soap_package)->u.generic->no = 0;
613 (*soap_package)->ns = "SRU";
617 else if (!strcmp(operation, "scan"))
619 /* Transfer SRU scan parameters to common struct */
620 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
621 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
623 sr->srw_version = version;
624 sr->extra_args = extra_args;
626 yaz_srw_decodeauth(sr, hreq, username, password, decode);
628 sr->u.scan_request->queryType = queryType;
629 sr->u.scan_request->scanClause = scanClause;
632 yaz_add_srw_diagnostic(
633 decode, diag, num_diag,
634 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
635 sr->u.scan_request->database = db;
637 yaz_sru_decode_integer(decode, "maximumTerms",
639 &sr->u.scan_request->maximumTerms,
642 yaz_sru_decode_integer(decode, "responsePosition",
644 &sr->u.scan_request->responsePosition,
647 sr->u.scan_request->stylesheet = stylesheet;
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";
666 /* unsupported operation ... */
667 /* Act as if we received a explain request and throw diagnostic. */
669 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
671 sr->srw_version = version;
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";
691 yaz_add_srw_diagnostic(decode, diag, num_diag,
692 YAZ_SRW_UNSUPP_OPERATION, operation);
702 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
704 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
705 odr_malloc(o, sizeof(*res));
707 res->extraRecordData_buf = 0;
708 res->extraRecordData_len = 0;
709 res->recordIdentifier = 0;
714 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
716 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
719 for (i = 0; i<n; i++)
721 res[i].recordSchema = 0;
722 res[i].recordPacking = Z_SRW_recordPacking_string;
723 res[i].recordData_buf = 0;
724 res[i].recordData_len = 0;
725 res[i].recordPosition = 0;
730 Z_SRW_record *yaz_srw_get_record(ODR o)
732 return yaz_srw_get_records(o, 1);
735 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
737 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
738 p->srw_version = odr_strdup(o, version);
742 p->extraResponseData_buf = 0;
743 p->extraResponseData_len = 0;
747 Z_SRW_PDU *yaz_srw_get_core_v_2_0(ODR o)
749 return yaz_srw_get_core_ver(o, "2.0");
752 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
754 return yaz_srw_get_pdu(o, which, "2.0");
757 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
759 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
764 case Z_SRW_searchRetrieve_request:
765 sr->u.request = (Z_SRW_searchRetrieveRequest *)
766 odr_malloc(o, sizeof(*sr->u.request));
767 sr->u.request->queryType = "cql";
768 sr->u.request->query = 0;
769 sr->u.request->sort_type = Z_SRW_sort_type_none;
770 sr->u.request->sort.none = 0;
771 sr->u.request->startRecord = 0;
772 sr->u.request->maximumRecords = 0;
773 sr->u.request->recordSchema = 0;
774 sr->u.request->recordPacking = 0;
775 sr->u.request->packing = 0;
776 sr->u.request->recordXPath = 0;
777 sr->u.request->database = 0;
778 sr->u.request->resultSetTTL = 0;
779 sr->u.request->stylesheet = 0;
780 sr->u.request->facetList = 0;
782 case Z_SRW_searchRetrieve_response:
783 sr->u.response = (Z_SRW_searchRetrieveResponse *)
784 odr_malloc(o, sizeof(*sr->u.response));
785 sr->u.response->numberOfRecords = 0;
786 sr->u.response->resultCountPrecision = 0;
787 sr->u.response->resultSetId = 0;
788 sr->u.response->resultSetIdleTime = 0;
789 sr->u.response->records = 0;
790 sr->u.response->num_records = 0;
791 sr->u.response->diagnostics = 0;
792 sr->u.response->num_diagnostics = 0;
793 sr->u.response->nextRecordPosition = 0;
794 sr->u.response->extra_records = 0;
795 sr->u.response->facetList = 0;
796 sr->u.response->suggestions = 0;
798 case Z_SRW_explain_request:
799 sr->u.explain_request = (Z_SRW_explainRequest *)
800 odr_malloc(o, sizeof(*sr->u.explain_request));
801 sr->u.explain_request->recordPacking = 0;
802 sr->u.explain_request->packing = 0;
803 sr->u.explain_request->database = 0;
804 sr->u.explain_request->stylesheet = 0;
806 case Z_SRW_explain_response:
807 sr->u.explain_response = (Z_SRW_explainResponse *)
808 odr_malloc(o, sizeof(*sr->u.explain_response));
809 sr->u.explain_response->record.recordData_buf = 0;
810 sr->u.explain_response->record.recordData_len = 0;
811 sr->u.explain_response->record.recordSchema = 0;
812 sr->u.explain_response->record.recordPosition = 0;
813 sr->u.explain_response->record.recordPacking =
814 Z_SRW_recordPacking_string;
815 sr->u.explain_response->diagnostics = 0;
816 sr->u.explain_response->num_diagnostics = 0;
817 sr->u.explain_response->extra_record = 0;
819 case Z_SRW_scan_request:
820 sr->u.scan_request = (Z_SRW_scanRequest *)
821 odr_malloc(o, sizeof(*sr->u.scan_request));
822 sr->u.scan_request->database = 0;
823 sr->u.scan_request->stylesheet = 0;
824 sr->u.scan_request->maximumTerms = 0;
825 sr->u.scan_request->responsePosition = 0;
826 sr->u.scan_request->queryType = "cql";
827 sr->u.scan_request->scanClause = 0;
829 case Z_SRW_scan_response:
830 sr->u.scan_response = (Z_SRW_scanResponse *)
831 odr_malloc(o, sizeof(*sr->u.scan_response));
832 sr->u.scan_response->terms = 0;
833 sr->u.scan_response->num_terms = 0;
834 sr->u.scan_response->diagnostics = 0;
835 sr->u.scan_response->num_diagnostics = 0;
837 case Z_SRW_update_request:
838 sr->u.update_request = (Z_SRW_updateRequest *)
839 odr_malloc(o, sizeof(*sr->u.update_request));
840 sr->u.update_request->database = 0;
841 sr->u.update_request->stylesheet = 0;
842 sr->u.update_request->record = 0;
843 sr->u.update_request->recordId = 0;
844 sr->u.update_request->recordVersions = 0;
845 sr->u.update_request->num_recordVersions = 0;
846 sr->u.update_request->extra_record = 0;
847 sr->u.update_request->extraRequestData_buf = 0;
848 sr->u.update_request->extraRequestData_len = 0;
849 sr->u.request->database = 0;
851 case Z_SRW_update_response:
852 sr->u.update_response = (Z_SRW_updateResponse *)
853 odr_malloc(o, sizeof(*sr->u.update_response));
854 sr->u.update_response->operationStatus = 0;
855 sr->u.update_response->recordId = 0;
856 sr->u.update_response->recordVersions = 0;
857 sr->u.update_response->num_recordVersions = 0;
858 sr->u.update_response->record = 0;
859 sr->u.update_response->extra_record = 0;
860 sr->u.update_response->extraResponseData_buf = 0;
861 sr->u.update_response->extraResponseData_len = 0;
862 sr->u.update_response->diagnostics = 0;
863 sr->u.update_response->num_diagnostics = 0;
868 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
869 char *a_name, Odr_int *val)
874 value[*i] = (char *) odr_malloc(o, 40);
875 sprintf(value[*i], ODR_INT_PRINTF, *val);
880 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
881 char *a_name, char *val)
891 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
892 char **name, char **value, int max_names)
894 int version2 = strcmp(srw_pdu->srw_version, "2.") > 0;
897 yaz_add_name_value_str(encode, name, value, &i, "version",
898 srw_pdu->srw_version);
899 name[i] = "operation";
900 switch (srw_pdu->which)
902 case Z_SRW_searchRetrieve_request:
903 value[i++] = "searchRetrieve";
904 queryType = srw_pdu->u.request->queryType;
907 if (queryType && strcmp(queryType, "cql"))
908 yaz_add_name_value_str(encode, name, value, &i, "queryType",
910 yaz_add_name_value_str(encode, name, value, &i, "query",
911 srw_pdu->u.request->query);
915 if (!strcmp(queryType, "cql"))
917 yaz_add_name_value_str(encode, name, value, &i, "query",
918 srw_pdu->u.request->query);
920 else if (!strcmp(queryType, "pqf"))
922 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
923 srw_pdu->u.request->query);
925 else if (!strcmp(queryType, "xcql"))
927 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
928 srw_pdu->u.request->query);
931 switch (srw_pdu->u.request->sort_type)
933 case Z_SRW_sort_type_none:
935 case Z_SRW_sort_type_sort:
936 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
937 srw_pdu->u.request->sort.sortKeys);
940 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
941 srw_pdu->u.request->startRecord);
942 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
943 srw_pdu->u.request->maximumRecords);
944 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
945 srw_pdu->u.request->recordSchema);
948 yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping",
949 srw_pdu->u.request->recordPacking);
950 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
951 srw_pdu->u.request->packing);
954 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
955 srw_pdu->u.request->recordPacking);
956 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
957 srw_pdu->u.request->recordXPath);
958 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
959 srw_pdu->u.request->stylesheet);
960 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
961 srw_pdu->u.request->resultSetTTL);
963 const char *facetLimit = 0;
964 yaz_sru_facet_request(encode, &srw_pdu->u.request->facetList,
966 yaz_add_name_value_str(encode, name, value, &i, "facetLimit",
967 (char *) facetLimit);
970 case Z_SRW_explain_request:
971 value[i++] = "explain";
975 yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping",
976 srw_pdu->u.explain_request->recordPacking);
977 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
978 srw_pdu->u.explain_request->packing);
981 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
982 srw_pdu->u.explain_request->recordPacking);
983 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
984 srw_pdu->u.explain_request->stylesheet);
986 case Z_SRW_scan_request:
988 queryType = srw_pdu->u.scan_request->queryType;
991 if (queryType && strcmp(queryType, "cql"))
992 yaz_add_name_value_str(encode, name, value, &i, "queryType",
994 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
995 srw_pdu->u.scan_request->scanClause);
999 if (!queryType || !strcmp(queryType, "cql"))
1000 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1001 srw_pdu->u.scan_request->scanClause);
1002 else if (!strcmp(queryType, "pqf"))
1003 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1004 srw_pdu->u.scan_request->scanClause);
1005 else if (!strcmp(queryType, "xcql"))
1006 yaz_add_name_value_str(encode, name, value, &i,
1008 srw_pdu->u.scan_request->scanClause);
1010 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1011 srw_pdu->u.scan_request->responsePosition);
1012 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1013 srw_pdu->u.scan_request->maximumTerms);
1014 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1015 srw_pdu->u.scan_request->stylesheet);
1017 case Z_SRW_update_request:
1018 value[i++] = "update";
1023 if (srw_pdu->extra_args)
1025 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1026 for (; ea && i < max_names-1; ea = ea->next)
1029 value[i] = ea->value;
1038 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1039 ODR encode, const char *charset)
1041 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1045 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1046 srw_pdu->username, srw_pdu->password);
1047 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1049 yaz_array_to_uri(&uri_args, encode, name, value);
1051 hreq->method = "GET";
1054 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1056 sprintf(path, "%s?%s", hreq->path, uri_args);
1059 z_HTTP_header_add_content_type(encode, &hreq->headers,
1060 "text/xml", charset);
1064 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1065 ODR encode, const char *charset)
1067 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1070 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1071 srw_pdu->username, srw_pdu->password);
1072 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1075 yaz_array_to_uri(&uri_args, encode, name, value);
1077 hreq->method = "POST";
1079 hreq->content_buf = uri_args;
1080 hreq->content_len = strlen(uri_args);
1082 z_HTTP_header_add_content_type(encode, &hreq->headers,
1083 "application/x-www-form-urlencoded",
1088 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1089 ODR odr, const char *charset)
1091 Z_SOAP_Handler handlers[3] = {
1093 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1094 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1098 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1100 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1101 srw_pdu->username, srw_pdu->password);
1102 z_HTTP_header_add_content_type(odr,
1104 "text/xml", charset);
1106 z_HTTP_header_add(odr, &hreq->headers,
1107 "SOAPAction", "\"\"");
1108 p->which = Z_SOAP_generic;
1109 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1110 p->u.generic->no = 0;
1111 p->u.generic->ns = 0;
1112 p->u.generic->p = srw_pdu;
1113 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1116 if (srw_pdu->which == Z_SRW_update_request ||
1117 srw_pdu->which == Z_SRW_update_response)
1118 p->u.generic->no = 1; /* second handler */
1120 return z_soap_codec_enc(odr, &p,
1122 &hreq->content_len, handlers,
1126 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1128 Z_SRW_recordVersion *ver
1129 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1131 for (i = 0; i < num; ++i)
1133 ver[i].versionType = 0;
1134 ver[i].versionValue = 0;
1139 const char *yaz_srw_pack_to_str(int pack)
1143 case Z_SRW_recordPacking_string:
1145 case Z_SRW_recordPacking_XML:
1147 case Z_SRW_recordPacking_URL:
1153 int yaz_srw_str_to_pack(const char *str)
1155 if (!yaz_matchstr(str, "string"))
1156 return Z_SRW_recordPacking_string;
1157 if (!yaz_matchstr(str, "xml"))
1158 return Z_SRW_recordPacking_XML;
1159 if (!yaz_matchstr(str, "url"))
1160 return Z_SRW_recordPacking_URL;
1164 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1170 Z_SRW_extra_arg **ea = &sr->extra_args;
1171 yaz_uri_to_array(extra_args, odr, &name, &val);
1175 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1176 (*ea)->name = *name;
1177 (*ea)->value = *val;
1190 * c-file-style: "Stroustrup"
1191 * indent-tabs-mode: nil
1193 * vim: shiftwidth=4 tabstop=8 expandtab