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 if ((*soap_package)->u.generic->no == 3) /* SRU 2 ! */
300 (*soap_package)->u.generic->no = 0;
301 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
302 (*srw_pdu)->u.request->database == 0)
303 (*srw_pdu)->u.request->database = db;
305 if ((*srw_pdu)->which == Z_SRW_explain_request &&
306 (*srw_pdu)->u.explain_request->database == 0)
307 (*srw_pdu)->u.explain_request->database = db;
309 if ((*srw_pdu)->which == Z_SRW_scan_request &&
310 (*srw_pdu)->u.scan_request->database == 0)
311 (*srw_pdu)->u.scan_request->database = db;
313 if ((*srw_pdu)->which == Z_SRW_update_request &&
314 (*srw_pdu)->u.update_request->database == 0)
315 (*srw_pdu)->u.update_request->database = db;
326 static int yaz_sru_decode_integer(ODR odr, const char *pname,
327 const char *valstr, Odr_int **valp,
328 Z_SRW_diagnostic **diag, int *num_diag,
334 if (sscanf(valstr, "%d", &ival) != 1)
336 yaz_add_srw_diagnostic(odr, diag, num_diag,
337 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
340 if (min_value >= 0 && ival < min_value)
342 yaz_add_srw_diagnostic(odr, diag, num_diag,
343 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
346 *valp = odr_intdup(odr, ival);
352 http://www.loc.gov/z3950/agency/zing/srw/service.html
354 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
355 Z_SOAP **soap_package, ODR decode, char **charset,
356 Z_SRW_diagnostic **diag, int *num_diag)
359 static Z_SOAP_Handler soap_handlers[2] = {
360 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
364 const char *content_type = z_HTTP_header_lookup(hreq->headers,
368 SRU GET: ignore content type.
369 SRU POST: we support "application/x-www-form-urlencoded";
370 not "multipart/form-data" .
372 if (!strcmp(hreq->method, "GET")
374 (!strcmp(hreq->method, "POST") && content_type &&
375 !yaz_strcmp_del("application/x-www-form-urlencoded",
376 content_type, "; ")))
378 char *db = "Default";
379 const char *p0 = hreq->path, *p1;
381 const char *operation = 0;
384 char *queryType = "cql";
388 char *stylesheet = 0;
389 char *scanClause = 0;
390 char *recordXPath = 0;
391 char *recordSchema = 0;
392 char *recordXMLEscaping = 0;
393 char *recordPacking = 0;
394 char *maximumRecords = 0;
395 char *startRecord = 0;
396 char *maximumTerms = 0;
397 char *responsePosition = 0;
398 Z_SRW_extra_arg *extra_args = 0;
403 grab_charset(decode, content_type, charset);
404 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
409 p1 = strchr(p0, '?');
411 p1 = p0 + strlen(p0);
413 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
414 if (!strcmp(hreq->method, "POST"))
415 p1 = hreq->content_buf;
416 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
421 for (i = 0; uri_name[i]; i++)
423 char *n = uri_name[i];
424 char *v = uri_val[i];
425 if (!strcmp(n, "query"))
427 else if (!strcmp(n, "x-pquery"))
432 else if (!strcmp(n, "queryType"))
434 else if (!strcmp(n, "x-username"))
436 else if (!strcmp(n, "x-password"))
438 else if (!strcmp(n, "operation"))
440 else if (!strcmp(n, "stylesheet"))
442 else if (!strcmp(n, "sortKeys"))
444 else if (!strcmp(n, "recordXPath"))
446 else if (!strcmp(n, "recordSchema"))
448 else if (!strcmp(n, "recordPacking"))
450 else if (!strcmp(n, "recordXMLEscaping"))
451 recordXMLEscaping = v;
452 else if (!strcmp(n, "version"))
454 else if (!strcmp(n, "scanClause"))
456 else if (!strcmp(n, "x-pScanClause"))
461 else if (!strcmp(n, "maximumRecords"))
463 else if (!strcmp(n, "startRecord"))
465 else if (!strcmp(n, "maximumTerms"))
467 else if (!strcmp(n, "responsePosition"))
468 responsePosition = v;
469 else if (!strcmp(n, "extraRequestData"))
470 ; /* ignoring extraRequestData */
471 else if (n[0] == 'x' && n[1] == '-')
473 Z_SRW_extra_arg **l = &extra_args;
476 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
477 (*l)->name = odr_strdup(decode, n);
478 (*l)->value = odr_strdup(decode, v);
484 yaz_add_srw_diagnostic(decode, diag, num_diag,
485 YAZ_SRW_UNSUPP_PARAMETER, n);
489 if (!operation && query)
490 operation = "searchRetrieve";
491 version = yaz_negotiate_sru_version(version);
494 { /* negotiation failed. */
495 yaz_add_srw_diagnostic(decode, diag, num_diag,
496 YAZ_SRW_UNSUPP_VERSION, "2.0");
502 yaz_add_srw_diagnostic(
503 decode, diag, num_diag,
504 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
505 operation = "explain";
507 if (strcmp(version, "2.0"))
509 if (recordXMLEscaping)
511 yaz_add_srw_diagnostic(decode, diag, num_diag,
512 YAZ_SRW_UNSUPP_PARAMETER,
513 "recordXMLEscaping");
516 recordXMLEscaping = recordPacking;
517 recordPacking = "packed";
519 if (!recordXMLEscaping)
520 recordXMLEscaping = "xml";
521 if (!strcmp(operation, "searchRetrieve"))
523 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
525 sr->srw_version = version;
526 sr->extra_args = extra_args;
528 yaz_srw_decodeauth(sr, hreq, username, password, decode);
530 sr->u.request->queryType = queryType;
531 sr->u.request->query = query;
534 yaz_add_srw_diagnostic(
535 decode, diag, num_diag,
536 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
540 sr->u.request->sort_type = Z_SRW_sort_type_sort;
541 sr->u.request->sort.sortKeys = sortKeys;
543 sr->u.request->recordXPath = recordXPath;
544 sr->u.request->recordSchema = recordSchema;
545 sr->u.request->recordPacking = recordXMLEscaping;
546 sr->u.request->packing = recordPacking;
547 sr->u.request->stylesheet = stylesheet;
549 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
550 &sr->u.request->maximumRecords,
553 yaz_sru_decode_integer(decode, "startRecord", startRecord,
554 &sr->u.request->startRecord,
557 sr->u.request->database = db;
559 (*soap_package) = (Z_SOAP *)
560 odr_malloc(decode, sizeof(**soap_package));
561 (*soap_package)->which = Z_SOAP_generic;
563 (*soap_package)->u.generic = (Z_SOAP_Generic *)
564 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
566 (*soap_package)->u.generic->p = sr;
567 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
568 (*soap_package)->u.generic->no = 0;
570 (*soap_package)->ns = "SRU";
574 else if (!strcmp(operation, "explain"))
576 /* Transfer SRU explain parameters to common struct */
577 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
578 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
580 sr->srw_version = version;
581 sr->extra_args = extra_args;
582 yaz_srw_decodeauth(sr, hreq, username, password, decode);
584 sr->u.explain_request->recordPacking = recordXMLEscaping;
585 sr->u.explain_request->packing = recordPacking;
586 sr->u.explain_request->database = db;
588 sr->u.explain_request->stylesheet = stylesheet;
590 (*soap_package) = (Z_SOAP *)
591 odr_malloc(decode, sizeof(**soap_package));
592 (*soap_package)->which = Z_SOAP_generic;
594 (*soap_package)->u.generic = (Z_SOAP_Generic *)
595 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
597 (*soap_package)->u.generic->p = sr;
598 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
599 (*soap_package)->u.generic->no = 0;
601 (*soap_package)->ns = "SRU";
605 else if (!strcmp(operation, "scan"))
607 /* Transfer SRU scan parameters to common struct */
608 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
609 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
611 sr->srw_version = version;
612 sr->extra_args = extra_args;
614 yaz_srw_decodeauth(sr, hreq, username, password, decode);
616 sr->u.scan_request->queryType = queryType;
617 sr->u.scan_request->scanClause = scanClause;
620 yaz_add_srw_diagnostic(
621 decode, diag, num_diag,
622 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
623 sr->u.scan_request->database = db;
625 yaz_sru_decode_integer(decode, "maximumTerms",
627 &sr->u.scan_request->maximumTerms,
630 yaz_sru_decode_integer(decode, "responsePosition",
632 &sr->u.scan_request->responsePosition,
635 sr->u.scan_request->stylesheet = stylesheet;
637 (*soap_package) = (Z_SOAP *)
638 odr_malloc(decode, sizeof(**soap_package));
639 (*soap_package)->which = Z_SOAP_generic;
641 (*soap_package)->u.generic = (Z_SOAP_Generic *)
642 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
644 (*soap_package)->u.generic->p = sr;
645 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
646 (*soap_package)->u.generic->no = 0;
648 (*soap_package)->ns = "SRU";
654 /* unsupported operation ... */
655 /* Act as if we received a explain request and throw diagnostic. */
657 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
659 sr->srw_version = version;
661 sr->u.explain_request->recordPacking = recordPacking;
662 sr->u.explain_request->database = db;
664 sr->u.explain_request->stylesheet = stylesheet;
666 (*soap_package) = (Z_SOAP *)
667 odr_malloc(decode, sizeof(**soap_package));
668 (*soap_package)->which = Z_SOAP_generic;
670 (*soap_package)->u.generic = (Z_SOAP_Generic *)
671 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
673 (*soap_package)->u.generic->p = sr;
674 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
675 (*soap_package)->u.generic->no = 0;
677 (*soap_package)->ns = "SRU";
679 yaz_add_srw_diagnostic(decode, diag, num_diag,
680 YAZ_SRW_UNSUPP_OPERATION, operation);
690 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
692 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
693 odr_malloc(o, sizeof(*res));
695 res->extraRecordData_buf = 0;
696 res->extraRecordData_len = 0;
697 res->recordIdentifier = 0;
702 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
704 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
707 for (i = 0; i<n; i++)
709 res[i].recordSchema = 0;
710 res[i].recordPacking = Z_SRW_recordPacking_string;
711 res[i].recordData_buf = 0;
712 res[i].recordData_len = 0;
713 res[i].recordPosition = 0;
718 Z_SRW_record *yaz_srw_get_record(ODR o)
720 return yaz_srw_get_records(o, 1);
723 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
725 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
726 p->srw_version = odr_strdup(o, version);
730 p->extraResponseData_buf = 0;
731 p->extraResponseData_len = 0;
735 Z_SRW_PDU *yaz_srw_get_core_v_2_0(ODR o)
737 return yaz_srw_get_core_ver(o, "2.0");
740 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
742 return yaz_srw_get_pdu(o, which, "2.0");
745 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
747 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
752 case Z_SRW_searchRetrieve_request:
753 sr->u.request = (Z_SRW_searchRetrieveRequest *)
754 odr_malloc(o, sizeof(*sr->u.request));
755 sr->u.request->queryType = "cql";
756 sr->u.request->query = 0;
757 sr->u.request->sort_type = Z_SRW_sort_type_none;
758 sr->u.request->sort.none = 0;
759 sr->u.request->startRecord = 0;
760 sr->u.request->maximumRecords = 0;
761 sr->u.request->recordSchema = 0;
762 sr->u.request->recordPacking = 0;
763 sr->u.request->packing = 0;
764 sr->u.request->recordXPath = 0;
765 sr->u.request->database = 0;
766 sr->u.request->resultSetTTL = 0;
767 sr->u.request->stylesheet = 0;
768 sr->u.request->facetList = 0;
770 case Z_SRW_searchRetrieve_response:
771 sr->u.response = (Z_SRW_searchRetrieveResponse *)
772 odr_malloc(o, sizeof(*sr->u.response));
773 sr->u.response->numberOfRecords = 0;
774 sr->u.response->resultSetId = 0;
775 sr->u.response->resultSetIdleTime = 0;
776 sr->u.response->records = 0;
777 sr->u.response->num_records = 0;
778 sr->u.response->diagnostics = 0;
779 sr->u.response->num_diagnostics = 0;
780 sr->u.response->nextRecordPosition = 0;
781 sr->u.response->extra_records = 0;
782 sr->u.response->facetList = 0;
783 sr->u.response->suggestions = 0;
785 case Z_SRW_explain_request:
786 sr->u.explain_request = (Z_SRW_explainRequest *)
787 odr_malloc(o, sizeof(*sr->u.explain_request));
788 sr->u.explain_request->recordPacking = 0;
789 sr->u.explain_request->packing = 0;
790 sr->u.explain_request->database = 0;
791 sr->u.explain_request->stylesheet = 0;
793 case Z_SRW_explain_response:
794 sr->u.explain_response = (Z_SRW_explainResponse *)
795 odr_malloc(o, sizeof(*sr->u.explain_response));
796 sr->u.explain_response->record.recordData_buf = 0;
797 sr->u.explain_response->record.recordData_len = 0;
798 sr->u.explain_response->record.recordSchema = 0;
799 sr->u.explain_response->record.recordPosition = 0;
800 sr->u.explain_response->record.recordPacking =
801 Z_SRW_recordPacking_string;
802 sr->u.explain_response->diagnostics = 0;
803 sr->u.explain_response->num_diagnostics = 0;
804 sr->u.explain_response->extra_record = 0;
806 case Z_SRW_scan_request:
807 sr->u.scan_request = (Z_SRW_scanRequest *)
808 odr_malloc(o, sizeof(*sr->u.scan_request));
809 sr->u.scan_request->database = 0;
810 sr->u.scan_request->stylesheet = 0;
811 sr->u.scan_request->maximumTerms = 0;
812 sr->u.scan_request->responsePosition = 0;
813 sr->u.scan_request->queryType = "cql";
814 sr->u.scan_request->scanClause = 0;
816 case Z_SRW_scan_response:
817 sr->u.scan_response = (Z_SRW_scanResponse *)
818 odr_malloc(o, sizeof(*sr->u.scan_response));
819 sr->u.scan_response->terms = 0;
820 sr->u.scan_response->num_terms = 0;
821 sr->u.scan_response->diagnostics = 0;
822 sr->u.scan_response->num_diagnostics = 0;
824 case Z_SRW_update_request:
825 sr->u.update_request = (Z_SRW_updateRequest *)
826 odr_malloc(o, sizeof(*sr->u.update_request));
827 sr->u.update_request->database = 0;
828 sr->u.update_request->stylesheet = 0;
829 sr->u.update_request->record = 0;
830 sr->u.update_request->recordId = 0;
831 sr->u.update_request->recordVersions = 0;
832 sr->u.update_request->num_recordVersions = 0;
833 sr->u.update_request->extra_record = 0;
834 sr->u.update_request->extraRequestData_buf = 0;
835 sr->u.update_request->extraRequestData_len = 0;
836 sr->u.request->database = 0;
838 case Z_SRW_update_response:
839 sr->u.update_response = (Z_SRW_updateResponse *)
840 odr_malloc(o, sizeof(*sr->u.update_response));
841 sr->u.update_response->operationStatus = 0;
842 sr->u.update_response->recordId = 0;
843 sr->u.update_response->recordVersions = 0;
844 sr->u.update_response->num_recordVersions = 0;
845 sr->u.update_response->record = 0;
846 sr->u.update_response->extra_record = 0;
847 sr->u.update_response->extraResponseData_buf = 0;
848 sr->u.update_response->extraResponseData_len = 0;
849 sr->u.update_response->diagnostics = 0;
850 sr->u.update_response->num_diagnostics = 0;
855 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
856 char *a_name, Odr_int *val)
861 value[*i] = (char *) odr_malloc(o, 40);
862 sprintf(value[*i], ODR_INT_PRINTF, *val);
867 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
868 char *a_name, char *val)
878 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
879 char **name, char **value, int max_names)
881 int version2 = strcmp(srw_pdu->srw_version, "2.") > 0;
885 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
886 name[i] = "operation";
887 switch (srw_pdu->which)
889 case Z_SRW_searchRetrieve_request:
891 value[i++] = "searchRetrieve";
892 queryType = srw_pdu->u.request->queryType;
895 yaz_add_name_value_str(encode, name, value, &i, "queryType",
897 yaz_add_name_value_str(encode, name, value, &i, "query",
898 srw_pdu->u.request->query);
902 if (!strcmp(queryType, "cql"))
904 yaz_add_name_value_str(encode, name, value, &i, "query",
905 srw_pdu->u.request->query);
907 else if (!strcmp(queryType, "pqf"))
909 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
910 srw_pdu->u.request->query);
912 else if (!strcmp(queryType, "pqf"))
914 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
915 srw_pdu->u.request->query);
918 switch (srw_pdu->u.request->sort_type)
920 case Z_SRW_sort_type_none:
922 case Z_SRW_sort_type_sort:
923 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
924 srw_pdu->u.request->sort.sortKeys);
927 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
928 srw_pdu->u.request->startRecord);
929 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
930 srw_pdu->u.request->maximumRecords);
931 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
932 srw_pdu->u.request->recordSchema);
935 yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping",
936 srw_pdu->u.request->recordPacking);
937 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
938 srw_pdu->u.request->packing);
941 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
942 srw_pdu->u.request->recordPacking);
943 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
944 srw_pdu->u.request->recordXPath);
945 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
946 srw_pdu->u.request->stylesheet);
947 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
948 srw_pdu->u.request->resultSetTTL);
950 case Z_SRW_explain_request:
951 value[i++] = "explain";
955 yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping",
956 srw_pdu->u.explain_request->recordPacking);
957 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
958 srw_pdu->u.explain_request->packing);
961 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
962 srw_pdu->u.explain_request->recordPacking);
963 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
964 srw_pdu->u.explain_request->stylesheet);
966 case Z_SRW_scan_request:
968 queryType = srw_pdu->u.request->queryType;
971 if (queryType && strcmp(queryType, "cql"))
972 yaz_add_name_value_str(encode, name, value, &i, "queryType",
974 yaz_add_name_value_str(encode, name, value, &i, "query",
975 srw_pdu->u.request->query);
979 if (!queryType || !strcmp(queryType, "cql"))
980 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
981 srw_pdu->u.scan_request->scanClause);
982 else if (!strcmp(queryType, "pqf"))
983 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
984 srw_pdu->u.scan_request->scanClause);
985 else if (!strcmp(queryType, "xcql"))
986 yaz_add_name_value_str(encode, name, value, &i,
988 srw_pdu->u.scan_request->scanClause);
990 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
991 srw_pdu->u.scan_request->responsePosition);
992 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
993 srw_pdu->u.scan_request->maximumTerms);
994 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
995 srw_pdu->u.scan_request->stylesheet);
997 case Z_SRW_update_request:
998 value[i++] = "update";
1003 if (srw_pdu->extra_args)
1005 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1006 for (; ea && i < max_names-1; ea = ea->next)
1009 value[i] = ea->value;
1018 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1019 ODR encode, const char *charset)
1021 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1025 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1026 srw_pdu->username, srw_pdu->password);
1027 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1029 yaz_array_to_uri(&uri_args, encode, name, value);
1031 hreq->method = "GET";
1034 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1036 sprintf(path, "%s?%s", hreq->path, uri_args);
1037 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1040 z_HTTP_header_add_content_type(encode, &hreq->headers,
1041 "text/xml", charset);
1045 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1046 ODR encode, const char *charset)
1048 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1051 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1052 srw_pdu->username, srw_pdu->password);
1053 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1056 yaz_array_to_uri(&uri_args, encode, name, value);
1058 hreq->method = "POST";
1060 hreq->content_buf = uri_args;
1061 hreq->content_len = strlen(uri_args);
1063 z_HTTP_header_add_content_type(encode, &hreq->headers,
1064 "application/x-www-form-urlencoded",
1069 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1070 ODR odr, const char *charset)
1072 Z_SOAP_Handler handlers[3] = {
1074 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1075 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1079 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1081 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1082 srw_pdu->username, srw_pdu->password);
1083 z_HTTP_header_add_content_type(odr,
1085 "text/xml", charset);
1087 z_HTTP_header_add(odr, &hreq->headers,
1088 "SOAPAction", "\"\"");
1089 p->which = Z_SOAP_generic;
1090 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1091 p->u.generic->no = 0;
1092 p->u.generic->ns = 0;
1093 p->u.generic->p = srw_pdu;
1094 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1097 if (srw_pdu->which == Z_SRW_update_request ||
1098 srw_pdu->which == Z_SRW_update_response)
1099 p->u.generic->no = 1; /* second handler */
1101 return z_soap_codec_enc(odr, &p,
1103 &hreq->content_len, handlers,
1107 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1109 Z_SRW_recordVersion *ver
1110 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1112 for (i = 0; i < num; ++i)
1114 ver[i].versionType = 0;
1115 ver[i].versionValue = 0;
1120 const char *yaz_srw_pack_to_str(int pack)
1124 case Z_SRW_recordPacking_string:
1126 case Z_SRW_recordPacking_XML:
1128 case Z_SRW_recordPacking_URL:
1134 int yaz_srw_str_to_pack(const char *str)
1136 if (!yaz_matchstr(str, "string"))
1137 return Z_SRW_recordPacking_string;
1138 if (!yaz_matchstr(str, "xml"))
1139 return Z_SRW_recordPacking_XML;
1140 if (!yaz_matchstr(str, "url"))
1141 return Z_SRW_recordPacking_URL;
1145 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1151 Z_SRW_extra_arg **ea = &sr->extra_args;
1152 yaz_uri_to_array(extra_args, odr, &name, &val);
1156 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1157 (*ea)->name = *name;
1158 (*ea)->value = *val;
1171 * c-file-style: "Stroustrup"
1172 * indent-tabs-mode: nil
1174 * vim: shiftwidth=4 tabstop=8 expandtab