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);
491 if (!operation && query)
492 operation = "searchRetrieve";
493 version = yaz_negotiate_sru_version(version);
496 { /* negotiation failed. */
497 yaz_add_srw_diagnostic(decode, diag, num_diag,
498 YAZ_SRW_UNSUPP_VERSION, "2.0");
504 yaz_add_srw_diagnostic(
505 decode, diag, num_diag,
506 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
507 operation = "explain";
509 if (strcmp(version, "2.0"))
511 if (recordXMLEscaping)
513 yaz_add_srw_diagnostic(decode, diag, num_diag,
514 YAZ_SRW_UNSUPP_PARAMETER,
515 "recordXMLEscaping");
518 recordXMLEscaping = recordPacking;
519 recordPacking = "packed";
521 if (!recordXMLEscaping)
522 recordXMLEscaping = "xml";
523 if (!strcmp(operation, "searchRetrieve"))
525 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
527 sr->srw_version = version;
528 sr->extra_args = extra_args;
530 yaz_srw_decodeauth(sr, hreq, username, password, decode);
532 sr->u.request->queryType = queryType;
533 sr->u.request->query = query;
536 yaz_add_srw_diagnostic(
537 decode, diag, num_diag,
538 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
542 sr->u.request->sort_type = Z_SRW_sort_type_sort;
543 sr->u.request->sort.sortKeys = sortKeys;
545 sr->u.request->recordXPath = recordXPath;
546 sr->u.request->recordSchema = recordSchema;
547 sr->u.request->recordPacking = recordXMLEscaping;
548 sr->u.request->packing = recordPacking;
549 sr->u.request->stylesheet = stylesheet;
551 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
552 &sr->u.request->maximumRecords,
555 yaz_sru_decode_integer(decode, "startRecord", startRecord,
556 &sr->u.request->startRecord,
559 sr->u.request->database = db;
561 (*soap_package) = (Z_SOAP *)
562 odr_malloc(decode, sizeof(**soap_package));
563 (*soap_package)->which = Z_SOAP_generic;
565 (*soap_package)->u.generic = (Z_SOAP_Generic *)
566 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
568 (*soap_package)->u.generic->p = sr;
569 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
570 (*soap_package)->u.generic->no = 0;
572 (*soap_package)->ns = "SRU";
576 else if (!strcmp(operation, "explain"))
578 /* Transfer SRU explain parameters to common struct */
579 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
580 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
582 sr->srw_version = version;
583 sr->extra_args = extra_args;
584 yaz_srw_decodeauth(sr, hreq, username, password, decode);
586 sr->u.explain_request->recordPacking = recordXMLEscaping;
587 sr->u.explain_request->packing = recordPacking;
588 sr->u.explain_request->database = db;
590 sr->u.explain_request->stylesheet = stylesheet;
592 (*soap_package) = (Z_SOAP *)
593 odr_malloc(decode, sizeof(**soap_package));
594 (*soap_package)->which = Z_SOAP_generic;
596 (*soap_package)->u.generic = (Z_SOAP_Generic *)
597 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
599 (*soap_package)->u.generic->p = sr;
600 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
601 (*soap_package)->u.generic->no = 0;
603 (*soap_package)->ns = "SRU";
607 else if (!strcmp(operation, "scan"))
609 /* Transfer SRU scan parameters to common struct */
610 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
611 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
613 sr->srw_version = version;
614 sr->extra_args = extra_args;
616 yaz_srw_decodeauth(sr, hreq, username, password, decode);
618 sr->u.scan_request->queryType = queryType;
619 sr->u.scan_request->scanClause = scanClause;
622 yaz_add_srw_diagnostic(
623 decode, diag, num_diag,
624 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
625 sr->u.scan_request->database = db;
627 yaz_sru_decode_integer(decode, "maximumTerms",
629 &sr->u.scan_request->maximumTerms,
632 yaz_sru_decode_integer(decode, "responsePosition",
634 &sr->u.scan_request->responsePosition,
637 sr->u.scan_request->stylesheet = stylesheet;
639 (*soap_package) = (Z_SOAP *)
640 odr_malloc(decode, sizeof(**soap_package));
641 (*soap_package)->which = Z_SOAP_generic;
643 (*soap_package)->u.generic = (Z_SOAP_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";
656 /* unsupported operation ... */
657 /* Act as if we received a explain request and throw diagnostic. */
659 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
661 sr->srw_version = version;
663 sr->u.explain_request->recordPacking = recordPacking;
664 sr->u.explain_request->database = db;
666 sr->u.explain_request->stylesheet = stylesheet;
668 (*soap_package) = (Z_SOAP *)
669 odr_malloc(decode, sizeof(**soap_package));
670 (*soap_package)->which = Z_SOAP_generic;
672 (*soap_package)->u.generic = (Z_SOAP_Generic *)
673 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
675 (*soap_package)->u.generic->p = sr;
676 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
677 (*soap_package)->u.generic->no = 0;
679 (*soap_package)->ns = "SRU";
681 yaz_add_srw_diagnostic(decode, diag, num_diag,
682 YAZ_SRW_UNSUPP_OPERATION, operation);
692 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
694 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
695 odr_malloc(o, sizeof(*res));
697 res->extraRecordData_buf = 0;
698 res->extraRecordData_len = 0;
699 res->recordIdentifier = 0;
704 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
706 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
709 for (i = 0; i<n; i++)
711 res[i].recordSchema = 0;
712 res[i].recordPacking = Z_SRW_recordPacking_string;
713 res[i].recordData_buf = 0;
714 res[i].recordData_len = 0;
715 res[i].recordPosition = 0;
720 Z_SRW_record *yaz_srw_get_record(ODR o)
722 return yaz_srw_get_records(o, 1);
725 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
727 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
728 p->srw_version = odr_strdup(o, version);
732 p->extraResponseData_buf = 0;
733 p->extraResponseData_len = 0;
737 Z_SRW_PDU *yaz_srw_get_core_v_2_0(ODR o)
739 return yaz_srw_get_core_ver(o, "2.0");
742 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
744 return yaz_srw_get_pdu(o, which, "2.0");
747 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
749 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
754 case Z_SRW_searchRetrieve_request:
755 sr->u.request = (Z_SRW_searchRetrieveRequest *)
756 odr_malloc(o, sizeof(*sr->u.request));
757 sr->u.request->queryType = "cql";
758 sr->u.request->query = 0;
759 sr->u.request->sort_type = Z_SRW_sort_type_none;
760 sr->u.request->sort.none = 0;
761 sr->u.request->startRecord = 0;
762 sr->u.request->maximumRecords = 0;
763 sr->u.request->recordSchema = 0;
764 sr->u.request->recordPacking = 0;
765 sr->u.request->packing = 0;
766 sr->u.request->recordXPath = 0;
767 sr->u.request->database = 0;
768 sr->u.request->resultSetTTL = 0;
769 sr->u.request->stylesheet = 0;
770 sr->u.request->facetList = 0;
772 case Z_SRW_searchRetrieve_response:
773 sr->u.response = (Z_SRW_searchRetrieveResponse *)
774 odr_malloc(o, sizeof(*sr->u.response));
775 sr->u.response->numberOfRecords = 0;
776 sr->u.response->resultCountPrecision = 0;
777 sr->u.response->resultSetId = 0;
778 sr->u.response->resultSetIdleTime = 0;
779 sr->u.response->records = 0;
780 sr->u.response->num_records = 0;
781 sr->u.response->diagnostics = 0;
782 sr->u.response->num_diagnostics = 0;
783 sr->u.response->nextRecordPosition = 0;
784 sr->u.response->extra_records = 0;
785 sr->u.response->facetList = 0;
786 sr->u.response->suggestions = 0;
788 case Z_SRW_explain_request:
789 sr->u.explain_request = (Z_SRW_explainRequest *)
790 odr_malloc(o, sizeof(*sr->u.explain_request));
791 sr->u.explain_request->recordPacking = 0;
792 sr->u.explain_request->packing = 0;
793 sr->u.explain_request->database = 0;
794 sr->u.explain_request->stylesheet = 0;
796 case Z_SRW_explain_response:
797 sr->u.explain_response = (Z_SRW_explainResponse *)
798 odr_malloc(o, sizeof(*sr->u.explain_response));
799 sr->u.explain_response->record.recordData_buf = 0;
800 sr->u.explain_response->record.recordData_len = 0;
801 sr->u.explain_response->record.recordSchema = 0;
802 sr->u.explain_response->record.recordPosition = 0;
803 sr->u.explain_response->record.recordPacking =
804 Z_SRW_recordPacking_string;
805 sr->u.explain_response->diagnostics = 0;
806 sr->u.explain_response->num_diagnostics = 0;
807 sr->u.explain_response->extra_record = 0;
809 case Z_SRW_scan_request:
810 sr->u.scan_request = (Z_SRW_scanRequest *)
811 odr_malloc(o, sizeof(*sr->u.scan_request));
812 sr->u.scan_request->database = 0;
813 sr->u.scan_request->stylesheet = 0;
814 sr->u.scan_request->maximumTerms = 0;
815 sr->u.scan_request->responsePosition = 0;
816 sr->u.scan_request->queryType = "cql";
817 sr->u.scan_request->scanClause = 0;
819 case Z_SRW_scan_response:
820 sr->u.scan_response = (Z_SRW_scanResponse *)
821 odr_malloc(o, sizeof(*sr->u.scan_response));
822 sr->u.scan_response->terms = 0;
823 sr->u.scan_response->num_terms = 0;
824 sr->u.scan_response->diagnostics = 0;
825 sr->u.scan_response->num_diagnostics = 0;
827 case Z_SRW_update_request:
828 sr->u.update_request = (Z_SRW_updateRequest *)
829 odr_malloc(o, sizeof(*sr->u.update_request));
830 sr->u.update_request->database = 0;
831 sr->u.update_request->stylesheet = 0;
832 sr->u.update_request->record = 0;
833 sr->u.update_request->recordId = 0;
834 sr->u.update_request->recordVersions = 0;
835 sr->u.update_request->num_recordVersions = 0;
836 sr->u.update_request->extra_record = 0;
837 sr->u.update_request->extraRequestData_buf = 0;
838 sr->u.update_request->extraRequestData_len = 0;
839 sr->u.request->database = 0;
841 case Z_SRW_update_response:
842 sr->u.update_response = (Z_SRW_updateResponse *)
843 odr_malloc(o, sizeof(*sr->u.update_response));
844 sr->u.update_response->operationStatus = 0;
845 sr->u.update_response->recordId = 0;
846 sr->u.update_response->recordVersions = 0;
847 sr->u.update_response->num_recordVersions = 0;
848 sr->u.update_response->record = 0;
849 sr->u.update_response->extra_record = 0;
850 sr->u.update_response->extraResponseData_buf = 0;
851 sr->u.update_response->extraResponseData_len = 0;
852 sr->u.update_response->diagnostics = 0;
853 sr->u.update_response->num_diagnostics = 0;
858 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
859 char *a_name, Odr_int *val)
864 value[*i] = (char *) odr_malloc(o, 40);
865 sprintf(value[*i], ODR_INT_PRINTF, *val);
870 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
871 char *a_name, char *val)
881 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
882 char **name, char **value, int max_names)
884 int version2 = strcmp(srw_pdu->srw_version, "2.") > 0;
888 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
889 name[i] = "operation";
890 switch (srw_pdu->which)
892 case Z_SRW_searchRetrieve_request:
894 value[i++] = "searchRetrieve";
895 queryType = srw_pdu->u.request->queryType;
898 yaz_add_name_value_str(encode, name, value, &i, "queryType",
900 yaz_add_name_value_str(encode, name, value, &i, "query",
901 srw_pdu->u.request->query);
905 if (!strcmp(queryType, "cql"))
907 yaz_add_name_value_str(encode, name, value, &i, "query",
908 srw_pdu->u.request->query);
910 else if (!strcmp(queryType, "pqf"))
912 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
913 srw_pdu->u.request->query);
915 else if (!strcmp(queryType, "xcql"))
917 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
918 srw_pdu->u.request->query);
921 switch (srw_pdu->u.request->sort_type)
923 case Z_SRW_sort_type_none:
925 case Z_SRW_sort_type_sort:
926 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
927 srw_pdu->u.request->sort.sortKeys);
930 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
931 srw_pdu->u.request->startRecord);
932 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
933 srw_pdu->u.request->maximumRecords);
934 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
935 srw_pdu->u.request->recordSchema);
938 yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping",
939 srw_pdu->u.request->recordPacking);
940 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
941 srw_pdu->u.request->packing);
944 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
945 srw_pdu->u.request->recordPacking);
946 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
947 srw_pdu->u.request->recordXPath);
948 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
949 srw_pdu->u.request->stylesheet);
950 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
951 srw_pdu->u.request->resultSetTTL);
953 case Z_SRW_explain_request:
954 value[i++] = "explain";
958 yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping",
959 srw_pdu->u.explain_request->recordPacking);
960 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
961 srw_pdu->u.explain_request->packing);
964 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
965 srw_pdu->u.explain_request->recordPacking);
966 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
967 srw_pdu->u.explain_request->stylesheet);
969 case Z_SRW_scan_request:
971 queryType = srw_pdu->u.scan_request->queryType;
974 if (queryType && strcmp(queryType, "cql"))
975 yaz_add_name_value_str(encode, name, value, &i, "queryType",
977 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
978 srw_pdu->u.scan_request->scanClause);
982 if (!queryType || !strcmp(queryType, "cql"))
983 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
984 srw_pdu->u.scan_request->scanClause);
985 else if (!strcmp(queryType, "pqf"))
986 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
987 srw_pdu->u.scan_request->scanClause);
988 else if (!strcmp(queryType, "xcql"))
989 yaz_add_name_value_str(encode, name, value, &i,
991 srw_pdu->u.scan_request->scanClause);
993 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
994 srw_pdu->u.scan_request->responsePosition);
995 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
996 srw_pdu->u.scan_request->maximumTerms);
997 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
998 srw_pdu->u.scan_request->stylesheet);
1000 case Z_SRW_update_request:
1001 value[i++] = "update";
1006 if (srw_pdu->extra_args)
1008 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1009 for (; ea && i < max_names-1; ea = ea->next)
1012 value[i] = ea->value;
1021 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1022 ODR encode, const char *charset)
1024 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1028 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1029 srw_pdu->username, srw_pdu->password);
1030 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1032 yaz_array_to_uri(&uri_args, encode, name, value);
1034 hreq->method = "GET";
1037 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1039 sprintf(path, "%s?%s", hreq->path, uri_args);
1040 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1043 z_HTTP_header_add_content_type(encode, &hreq->headers,
1044 "text/xml", charset);
1048 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1049 ODR encode, const char *charset)
1051 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1054 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1055 srw_pdu->username, srw_pdu->password);
1056 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1059 yaz_array_to_uri(&uri_args, encode, name, value);
1061 hreq->method = "POST";
1063 hreq->content_buf = uri_args;
1064 hreq->content_len = strlen(uri_args);
1066 z_HTTP_header_add_content_type(encode, &hreq->headers,
1067 "application/x-www-form-urlencoded",
1072 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1073 ODR odr, const char *charset)
1075 Z_SOAP_Handler handlers[3] = {
1077 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1078 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1082 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1084 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1085 srw_pdu->username, srw_pdu->password);
1086 z_HTTP_header_add_content_type(odr,
1088 "text/xml", charset);
1090 z_HTTP_header_add(odr, &hreq->headers,
1091 "SOAPAction", "\"\"");
1092 p->which = Z_SOAP_generic;
1093 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1094 p->u.generic->no = 0;
1095 p->u.generic->ns = 0;
1096 p->u.generic->p = srw_pdu;
1097 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1100 if (srw_pdu->which == Z_SRW_update_request ||
1101 srw_pdu->which == Z_SRW_update_response)
1102 p->u.generic->no = 1; /* second handler */
1104 return z_soap_codec_enc(odr, &p,
1106 &hreq->content_len, handlers,
1110 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1112 Z_SRW_recordVersion *ver
1113 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1115 for (i = 0; i < num; ++i)
1117 ver[i].versionType = 0;
1118 ver[i].versionValue = 0;
1123 const char *yaz_srw_pack_to_str(int pack)
1127 case Z_SRW_recordPacking_string:
1129 case Z_SRW_recordPacking_XML:
1131 case Z_SRW_recordPacking_URL:
1137 int yaz_srw_str_to_pack(const char *str)
1139 if (!yaz_matchstr(str, "string"))
1140 return Z_SRW_recordPacking_string;
1141 if (!yaz_matchstr(str, "xml"))
1142 return Z_SRW_recordPacking_XML;
1143 if (!yaz_matchstr(str, "url"))
1144 return Z_SRW_recordPacking_URL;
1148 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1154 Z_SRW_extra_arg **ea = &sr->extra_args;
1155 yaz_uri_to_array(extra_args, odr, &name, &val);
1159 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1160 (*ea)->name = *name;
1161 (*ea)->value = *val;
1174 * c-file-style: "Stroustrup"
1175 * indent-tabs-mode: nil
1177 * vim: shiftwidth=4 tabstop=8 expandtab