1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2011 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SRW/SRU utilities.
16 #include <yaz/matchstr.h>
17 #include <yaz/yaz-iconv.h>
20 #define MAX_SRU_PARAMETERS 30
22 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
24 return odr_strdupn(n, uri, len);
27 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
34 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
36 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
37 yaz_encode_sru_dbpath_buf(dst, db);
41 Z_AttributeList *yaz_use_attribute_create(ODR o, const char *name)
43 Z_AttributeList *attributes= (Z_AttributeList *)
44 odr_malloc(o, sizeof(*attributes));
45 Z_AttributeElement ** elements;
46 attributes->num_attributes = 1;
47 elements = (Z_AttributeElement**)
48 odr_malloc (o, attributes->num_attributes * sizeof(*elements));
49 elements[0] = (Z_AttributeElement*) odr_malloc(o,sizeof(**elements));
50 elements[0]->attributeType = odr_intdup(o, 1);
51 elements[0]->attributeSet = odr_nullval();
52 elements[0]->which = Z_AttributeValue_complex;
53 elements[0]->value.complex = (Z_ComplexAttribute *)
54 odr_malloc(o, sizeof(Z_ComplexAttribute));
55 elements[0]->value.complex->num_list = 1;
56 elements[0]->value.complex->list = (Z_StringOrNumeric **)
57 odr_malloc(o, 1 * sizeof(Z_StringOrNumeric *));
58 elements[0]->value.complex->list[0] = (Z_StringOrNumeric *)
59 odr_malloc(o, sizeof(Z_StringOrNumeric));
60 elements[0]->value.complex->list[0]->which = Z_StringOrNumeric_string;
61 elements[0]->value.complex->list[0]->u.string = odr_strdup(o, name);
62 elements[0]->value.complex->semanticAction = 0;
63 elements[0]->value.complex->num_semanticAction = 0;
64 attributes->attributes = elements;
69 const char *yaz_element_attribute_value_get(xmlNodePtr ptr,
70 const char *node_name,
71 const char *attribute_name)
73 struct _xmlAttr *attr;
74 // check if the node name matches
75 if (strcmp((const char*) ptr->name, node_name))
77 // check if the attribute name and return the value
78 for (attr = ptr->properties; attr; attr = attr->next)
79 if (attr->children && attr->children->type == XML_TEXT_NODE)
81 if (!strcmp((const char *) attr->name, attribute_name))
82 return (const char *) attr->children->content;
88 static int yaz_base64decode(const char *in, char *out)
90 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
91 "abcdefghijklmnopqrstuvwxyz0123456789+/";
100 if (!(p = strchr(map, in[0])))
104 if (!(p = strchr(map, in[1])))
108 *(out++) = i0 << 2 | i1 >> 4;
112 if (!(p = strchr(map, in[2])))
116 *(out++) = i1 << 4 | i2 >> 2;
120 if (!(p = strchr(map, in[3])))
124 *(out++) = i2 << 6 | i3;
134 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
136 const char *content_type = z_HTTP_header_lookup(hres->headers,
140 if (!yaz_strcmp_del("text/xml", content_type, "; "))
142 if (!yaz_strcmp_del("application/xml", content_type, "; "))
149 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
150 * parameters. Added by SH.
152 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
153 char *username, char *password, ODR decode)
155 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
158 sr->username = username;
160 sr->password = password;
166 char ubuf[256] = "", pbuf[256] = "", *p;
167 if (strncmp(basic, "Basic ", 6))
171 if (!len || len > 256)
173 olen = yaz_base64decode(basic, out);
174 /* Format of out should be username:password at this point */
176 if ((p = strchr(ubuf, ':')))
183 sr->username = odr_strdup(decode, ubuf);
185 sr->password = odr_strdup(decode, pbuf);
189 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
191 const char *v = yaz_uri_val(path, name, o);
193 *intp = odr_intdup(o, atoi(v));
196 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
197 const char *uri, const char *message,
200 d->uri = odr_strdup(o, uri);
202 d->message = odr_strdup(o, message);
206 d->details = odr_strdup(o, details);
211 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
212 int code, const char *details)
216 sprintf(uri, "info:srw/diagnostic/1/%d", code);
217 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
220 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
221 int *num, const char *uri,
222 const char *message, const char *details)
224 Z_SRW_diagnostic *d_new;
225 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
227 memcpy (d_new, *d, *num *sizeof(**d));
230 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
234 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
235 int *num, int code, const char *addinfo)
239 sprintf(uri, "info:srw/diagnostic/1/%d", code);
240 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
244 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
245 int *num, int code, const char *addinfo)
249 sprintf(uri, "info:srw/diagnostic/12/%d", code);
250 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
254 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
255 int code, const char *details)
257 const char *message = yaz_diag_srw_str(code);
260 len += strlen(message);
262 len += strlen(details);
264 record->recordData_buf = (char *) odr_malloc(o, len);
266 sprintf(record->recordData_buf, "<diagnostic "
267 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
268 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
270 sprintf(record->recordData_buf + strlen(record->recordData_buf),
271 " <details>%s</details>\n", details);
273 sprintf(record->recordData_buf + strlen(record->recordData_buf),
274 " <message>%s</message>\n", message);
275 sprintf(record->recordData_buf + strlen(record->recordData_buf),
277 record->recordData_len = strlen(record->recordData_buf);
278 record->recordPosition = odr_intdup(o, pos);
279 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
282 static void grab_charset(ODR o, const char *content_type, char **charset)
286 const char *charset_p = 0;
287 if (content_type && (charset_p = strstr(content_type, "; charset=")))
291 while (i < 20 && charset_p[i] &&
292 !strchr("; \n\r", charset_p[i]))
294 *charset = (char*) odr_malloc(o, i+1);
295 memcpy(*charset, charset_p, i);
296 (*charset)[i] = '\0';
301 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
302 Z_SOAP **soap_package, ODR decode, char **charset)
304 if (!strcmp(hreq->method, "POST"))
306 const char *content_type = z_HTTP_header_lookup(hreq->headers,
309 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
310 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
311 !yaz_strcmp_del("text/plain", content_type, "; ")))
313 char *db = "Default";
314 const char *p0 = hreq->path, *p1;
317 static Z_SOAP_Handler soap_handlers[4] = {
319 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
320 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
321 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
328 p1 = strchr(p0, '?');
330 p1 = p0 + strlen(p0);
332 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
333 grab_charset(decode, content_type, charset);
335 ret = z_soap_codec(decode, soap_package,
336 &hreq->content_buf, &hreq->content_len,
338 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
340 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
341 yaz_srw_decodeauth(*srw_pdu, hreq, 0, 0, decode);
343 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
344 (*srw_pdu)->u.request->database == 0)
345 (*srw_pdu)->u.request->database = db;
347 if ((*srw_pdu)->which == Z_SRW_explain_request &&
348 (*srw_pdu)->u.explain_request->database == 0)
349 (*srw_pdu)->u.explain_request->database = db;
351 if ((*srw_pdu)->which == Z_SRW_scan_request &&
352 (*srw_pdu)->u.scan_request->database == 0)
353 (*srw_pdu)->u.scan_request->database = db;
355 if ((*srw_pdu)->which == Z_SRW_update_request &&
356 (*srw_pdu)->u.update_request->database == 0)
357 (*srw_pdu)->u.update_request->database = db;
368 static int yaz_sru_decode_integer(ODR odr, const char *pname,
369 const char *valstr, Odr_int **valp,
370 Z_SRW_diagnostic **diag, int *num_diag,
376 if (sscanf(valstr, "%d", &ival) != 1)
378 yaz_add_srw_diagnostic(odr, diag, num_diag,
379 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
382 if (min_value >= 0 && ival < min_value)
384 yaz_add_srw_diagnostic(odr, diag, num_diag,
385 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
388 *valp = odr_intdup(odr, ival);
394 http://www.loc.gov/z3950/agency/zing/srw/service.html
396 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
397 Z_SOAP **soap_package, ODR decode, char **charset,
398 Z_SRW_diagnostic **diag, int *num_diag)
401 static Z_SOAP_Handler soap_handlers[2] = {
402 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
406 const char *content_type = z_HTTP_header_lookup(hreq->headers,
410 SRU GET: ignore content type.
411 SRU POST: we support "application/x-www-form-urlencoded";
412 not "multipart/form-data" .
414 if (!strcmp(hreq->method, "GET")
416 (!strcmp(hreq->method, "POST") && content_type &&
417 !yaz_strcmp_del("application/x-www-form-urlencoded",
418 content_type, "; ")))
420 char *db = "Default";
421 const char *p0 = hreq->path, *p1;
423 const char *operation = 0;
430 char *stylesheet = 0;
431 char *scanClause = 0;
432 char *pScanClause = 0;
433 char *recordXPath = 0;
434 char *recordSchema = 0;
435 char *recordPacking = "xml"; /* xml packing is default for SRU */
436 char *maximumRecords = 0;
437 char *startRecord = 0;
438 char *maximumTerms = 0;
439 char *responsePosition = 0;
440 char *extraRequestData = 0;
441 Z_SRW_extra_arg *extra_args = 0;
446 grab_charset(decode, content_type, charset);
447 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
452 p1 = strchr(p0, '?');
454 p1 = p0 + strlen(p0);
456 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
457 if (!strcmp(hreq->method, "POST"))
458 p1 = hreq->content_buf;
459 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
464 for (i = 0; uri_name[i]; i++)
466 char *n = uri_name[i];
467 char *v = uri_val[i];
468 if (!strcmp(n, "query"))
470 else if (!strcmp(n, "x-pquery"))
472 else if (!strcmp(n, "x-username"))
474 else if (!strcmp(n, "x-password"))
476 else if (!strcmp(n, "operation"))
478 else if (!strcmp(n, "stylesheet"))
480 else if (!strcmp(n, "sortKeys"))
482 else if (!strcmp(n, "recordXPath"))
484 else if (!strcmp(n, "recordSchema"))
486 else if (!strcmp(n, "recordPacking"))
488 else if (!strcmp(n, "version"))
490 else if (!strcmp(n, "scanClause"))
492 else if (!strcmp(n, "x-pScanClause"))
494 else if (!strcmp(n, "maximumRecords"))
496 else if (!strcmp(n, "startRecord"))
498 else if (!strcmp(n, "maximumTerms"))
500 else if (!strcmp(n, "responsePosition"))
501 responsePosition = v;
502 else if (!strcmp(n, "extraRequestData"))
503 extraRequestData = v;
504 else if (n[0] == 'x' && n[1] == '-')
506 Z_SRW_extra_arg **l = &extra_args;
509 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
510 (*l)->name = odr_strdup(decode, n);
511 (*l)->value = odr_strdup(decode, v);
515 yaz_add_srw_diagnostic(decode, diag, num_diag,
516 YAZ_SRW_UNSUPP_PARAMETER, n);
522 yaz_add_srw_diagnostic(
523 decode, diag, num_diag,
524 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
528 version = yaz_negotiate_sru_version(version);
531 { /* negotiation failed. */
532 yaz_add_srw_diagnostic(decode, diag, num_diag,
533 YAZ_SRW_UNSUPP_VERSION, "1.2");
540 yaz_add_srw_diagnostic(
541 decode, diag, num_diag,
542 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
543 operation = "explain";
545 if (!strcmp(operation, "searchRetrieve"))
547 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
549 sr->srw_version = version;
550 sr->extra_args = extra_args;
552 yaz_srw_decodeauth(sr, hreq, username, password, decode);
555 sr->u.request->query_type = Z_SRW_query_type_cql;
556 sr->u.request->query.cql = query;
560 sr->u.request->query_type = Z_SRW_query_type_pqf;
561 sr->u.request->query.pqf = pQuery;
564 yaz_add_srw_diagnostic(
565 decode, diag, num_diag,
566 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
570 sr->u.request->sort_type = Z_SRW_sort_type_sort;
571 sr->u.request->sort.sortKeys = sortKeys;
573 sr->u.request->recordXPath = recordXPath;
574 sr->u.request->recordSchema = recordSchema;
575 sr->u.request->recordPacking = recordPacking;
576 sr->u.request->stylesheet = stylesheet;
578 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
579 &sr->u.request->maximumRecords,
582 yaz_sru_decode_integer(decode, "startRecord", startRecord,
583 &sr->u.request->startRecord,
586 sr->u.request->database = db;
588 (*soap_package) = (Z_SOAP *)
589 odr_malloc(decode, sizeof(**soap_package));
590 (*soap_package)->which = Z_SOAP_generic;
592 (*soap_package)->u.generic = (Z_SOAP_Generic *)
593 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
595 (*soap_package)->u.generic->p = sr;
596 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
597 (*soap_package)->u.generic->no = 0;
599 (*soap_package)->ns = "SRU";
603 else if (!strcmp(operation, "explain"))
605 /* Transfer SRU explain parameters to common struct */
606 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
607 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
609 sr->srw_version = version;
610 sr->extra_args = extra_args;
611 yaz_srw_decodeauth(sr, hreq, username, password, decode);
613 sr->u.explain_request->recordPacking = recordPacking;
614 sr->u.explain_request->database = db;
616 sr->u.explain_request->stylesheet = stylesheet;
618 (*soap_package) = (Z_SOAP *)
619 odr_malloc(decode, sizeof(**soap_package));
620 (*soap_package)->which = Z_SOAP_generic;
622 (*soap_package)->u.generic = (Z_SOAP_Generic *)
623 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
625 (*soap_package)->u.generic->p = sr;
626 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
627 (*soap_package)->u.generic->no = 0;
629 (*soap_package)->ns = "SRU";
633 else if (!strcmp(operation, "scan"))
635 /* Transfer SRU scan parameters to common struct */
636 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
637 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
639 sr->srw_version = version;
640 sr->extra_args = extra_args;
642 yaz_srw_decodeauth(sr, hreq, username, password, decode);
646 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
647 sr->u.scan_request->scanClause.cql = scanClause;
649 else if (pScanClause)
651 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
652 sr->u.scan_request->scanClause.pqf = pScanClause;
655 yaz_add_srw_diagnostic(
656 decode, diag, num_diag,
657 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
658 sr->u.scan_request->database = db;
660 yaz_sru_decode_integer(decode, "maximumTerms",
662 &sr->u.scan_request->maximumTerms,
665 yaz_sru_decode_integer(decode, "responsePosition",
667 &sr->u.scan_request->responsePosition,
670 sr->u.scan_request->stylesheet = stylesheet;
672 (*soap_package) = (Z_SOAP *)
673 odr_malloc(decode, sizeof(**soap_package));
674 (*soap_package)->which = Z_SOAP_generic;
676 (*soap_package)->u.generic = (Z_SOAP_Generic *)
677 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
679 (*soap_package)->u.generic->p = sr;
680 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
681 (*soap_package)->u.generic->no = 0;
683 (*soap_package)->ns = "SRU";
689 /* unsupported operation ... */
690 /* Act as if we received a explain request and throw diagnostic. */
692 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
694 sr->srw_version = version;
696 sr->u.explain_request->recordPacking = recordPacking;
697 sr->u.explain_request->database = db;
699 sr->u.explain_request->stylesheet = stylesheet;
701 (*soap_package) = (Z_SOAP *)
702 odr_malloc(decode, sizeof(**soap_package));
703 (*soap_package)->which = Z_SOAP_generic;
705 (*soap_package)->u.generic = (Z_SOAP_Generic *)
706 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
708 (*soap_package)->u.generic->p = sr;
709 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
710 (*soap_package)->u.generic->no = 0;
712 (*soap_package)->ns = "SRU";
714 yaz_add_srw_diagnostic(decode, diag, num_diag,
715 YAZ_SRW_UNSUPP_OPERATION, operation);
724 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
726 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
727 odr_malloc(o, sizeof(*res));
729 res->extraRecordData_buf = 0;
730 res->extraRecordData_len = 0;
731 res->recordIdentifier = 0;
736 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
738 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
741 for (i = 0; i<n; i++)
743 res[i].recordSchema = 0;
744 res[i].recordPacking = Z_SRW_recordPacking_string;
745 res[i].recordData_buf = 0;
746 res[i].recordData_len = 0;
747 res[i].recordPosition = 0;
752 Z_SRW_record *yaz_srw_get_record(ODR o)
754 return yaz_srw_get_records(o, 1);
757 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
759 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
760 p->srw_version = odr_strdup(o, version);
764 p->extraResponseData_buf = 0;
765 p->extraResponseData_len = 0;
769 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
771 return yaz_srw_get_core_ver(o, "1.1");
774 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
776 return yaz_srw_get_pdu(o, which, "1.1");
779 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
781 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
786 case Z_SRW_searchRetrieve_request:
787 sr->u.request = (Z_SRW_searchRetrieveRequest *)
788 odr_malloc(o, sizeof(*sr->u.request));
789 sr->u.request->query_type = Z_SRW_query_type_cql;
790 sr->u.request->query.cql = 0;
791 sr->u.request->sort_type = Z_SRW_sort_type_none;
792 sr->u.request->sort.none = 0;
793 sr->u.request->startRecord = 0;
794 sr->u.request->maximumRecords = 0;
795 sr->u.request->recordSchema = 0;
796 sr->u.request->recordPacking = 0;
797 sr->u.request->recordXPath = 0;
798 sr->u.request->database = 0;
799 sr->u.request->resultSetTTL = 0;
800 sr->u.request->stylesheet = 0;
801 sr->u.request->facetList = 0;
803 case Z_SRW_searchRetrieve_response:
804 sr->u.response = (Z_SRW_searchRetrieveResponse *)
805 odr_malloc(o, sizeof(*sr->u.response));
806 sr->u.response->numberOfRecords = 0;
807 sr->u.response->resultSetId = 0;
808 sr->u.response->resultSetIdleTime = 0;
809 sr->u.response->records = 0;
810 sr->u.response->num_records = 0;
811 sr->u.response->diagnostics = 0;
812 sr->u.response->num_diagnostics = 0;
813 sr->u.response->nextRecordPosition = 0;
814 sr->u.response->extra_records = 0;
815 sr->u.response->facetList = 0;
817 case Z_SRW_explain_request:
818 sr->u.explain_request = (Z_SRW_explainRequest *)
819 odr_malloc(o, sizeof(*sr->u.explain_request));
820 sr->u.explain_request->recordPacking = 0;
821 sr->u.explain_request->database = 0;
822 sr->u.explain_request->stylesheet = 0;
824 case Z_SRW_explain_response:
825 sr->u.explain_response = (Z_SRW_explainResponse *)
826 odr_malloc(o, sizeof(*sr->u.explain_response));
827 sr->u.explain_response->record.recordData_buf = 0;
828 sr->u.explain_response->record.recordData_len = 0;
829 sr->u.explain_response->record.recordSchema = 0;
830 sr->u.explain_response->record.recordPosition = 0;
831 sr->u.explain_response->record.recordPacking =
832 Z_SRW_recordPacking_string;
833 sr->u.explain_response->diagnostics = 0;
834 sr->u.explain_response->num_diagnostics = 0;
835 sr->u.explain_response->extra_record = 0;
837 case Z_SRW_scan_request:
838 sr->u.scan_request = (Z_SRW_scanRequest *)
839 odr_malloc(o, sizeof(*sr->u.scan_request));
840 sr->u.scan_request->database = 0;
841 sr->u.scan_request->stylesheet = 0;
842 sr->u.scan_request->maximumTerms = 0;
843 sr->u.scan_request->responsePosition = 0;
844 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
845 sr->u.scan_request->scanClause.cql = 0;
847 case Z_SRW_scan_response:
848 sr->u.scan_response = (Z_SRW_scanResponse *)
849 odr_malloc(o, sizeof(*sr->u.scan_response));
850 sr->u.scan_response->terms = 0;
851 sr->u.scan_response->num_terms = 0;
852 sr->u.scan_response->diagnostics = 0;
853 sr->u.scan_response->num_diagnostics = 0;
855 case Z_SRW_update_request:
856 sr->u.update_request = (Z_SRW_updateRequest *)
857 odr_malloc(o, sizeof(*sr->u.update_request));
858 sr->u.update_request->database = 0;
859 sr->u.update_request->stylesheet = 0;
860 sr->u.update_request->record = 0;
861 sr->u.update_request->recordId = 0;
862 sr->u.update_request->recordVersions = 0;
863 sr->u.update_request->num_recordVersions = 0;
864 sr->u.update_request->extra_record = 0;
865 sr->u.update_request->extraRequestData_buf = 0;
866 sr->u.update_request->extraRequestData_len = 0;
867 sr->u.request->database = 0;
869 case Z_SRW_update_response:
870 sr->u.update_response = (Z_SRW_updateResponse *)
871 odr_malloc(o, sizeof(*sr->u.update_response));
872 sr->u.update_response->operationStatus = 0;
873 sr->u.update_response->recordId = 0;
874 sr->u.update_response->recordVersions = 0;
875 sr->u.update_response->num_recordVersions = 0;
876 sr->u.update_response->record = 0;
877 sr->u.update_response->extra_record = 0;
878 sr->u.update_response->extraResponseData_buf = 0;
879 sr->u.update_response->extraResponseData_len = 0;
880 sr->u.update_response->diagnostics = 0;
881 sr->u.update_response->num_diagnostics = 0;
887 static int bib1_srw_map[] = {
897 108, 10, /* Malformed query : Syntax error */
927 100, 1, /* bad map */
975 205, 1, /* bad map */
976 206, 1, /* bad map */
978 208, 1, /* bad map */
989 218, 1, /* bad map */
990 219, 1, /* bad map */
991 220, 1, /* bad map */
992 221, 1, /* bad map */
994 223, 1, /* bad map */
995 224, 1, /* bad map */
996 225, 1, /* bad map */
997 226, 1, /* bad map */
999 228, 1, /* bad map */
1004 233, 1, /* bad map */
1005 234, 1, /* bad map */
1011 240, 1, /* bad map */
1012 241, 1, /* bad map */
1014 243, 1, /* bad map */
1019 1001, 1, /* bad map */
1020 1002, 1, /* bad map */
1021 1003, 1, /* bad map */
1022 1004, 1, /* bad map */
1023 1005, 1, /* bad map */
1024 1006, 1, /* bad map */
1057 * This array contains overrides for when the first occurrence of a
1058 * particular SRW error in the array above does not correspond with
1059 * the best back-translation of that SRW error.
1061 static int srw_bib1_map[] = {
1063 /* No doubt there are many more */
1068 int yaz_diag_bib1_to_srw (int code)
1070 const int *p = bib1_srw_map;
1080 int yaz_diag_srw_to_bib1(int code)
1082 /* Check explicit reverse-map first */
1083 const int *p = srw_bib1_map;
1091 /* Fall back on reverse lookup in main map */
1102 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1103 char *a_name, Odr_int *val)
1108 value[*i] = (char *) odr_malloc(o, 40);
1109 sprintf(value[*i], ODR_INT_PRINTF, *val);
1114 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1115 char *a_name, char *val)
1125 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1126 char **name, char **value, int max_names)
1129 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1130 name[i] = "operation";
1131 switch(srw_pdu->which)
1133 case Z_SRW_searchRetrieve_request:
1134 value[i++] = "searchRetrieve";
1135 switch(srw_pdu->u.request->query_type)
1137 case Z_SRW_query_type_cql:
1138 yaz_add_name_value_str(encode, name, value, &i, "query",
1139 srw_pdu->u.request->query.cql);
1141 case Z_SRW_query_type_pqf:
1142 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1143 srw_pdu->u.request->query.pqf);
1145 case Z_SRW_query_type_xcql:
1146 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1147 srw_pdu->u.request->query.xcql);
1150 switch(srw_pdu->u.request->sort_type)
1152 case Z_SRW_sort_type_none:
1154 case Z_SRW_sort_type_sort:
1155 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1156 srw_pdu->u.request->sort.sortKeys);
1159 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1160 srw_pdu->u.request->startRecord);
1161 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1162 srw_pdu->u.request->maximumRecords);
1163 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1164 srw_pdu->u.request->recordSchema);
1165 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1166 srw_pdu->u.request->recordPacking);
1167 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1168 srw_pdu->u.request->recordXPath);
1169 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1170 srw_pdu->u.request->stylesheet);
1171 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1172 srw_pdu->u.request->resultSetTTL);
1174 case Z_SRW_explain_request:
1175 value[i++] = "explain";
1176 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1177 srw_pdu->u.explain_request->stylesheet);
1179 case Z_SRW_scan_request:
1180 value[i++] = "scan";
1182 switch(srw_pdu->u.scan_request->query_type)
1184 case Z_SRW_query_type_cql:
1185 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1186 srw_pdu->u.scan_request->scanClause.cql);
1188 case Z_SRW_query_type_pqf:
1189 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1190 srw_pdu->u.scan_request->scanClause.pqf);
1192 case Z_SRW_query_type_xcql:
1193 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1194 srw_pdu->u.scan_request->scanClause.xcql);
1197 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1198 srw_pdu->u.scan_request->responsePosition);
1199 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1200 srw_pdu->u.scan_request->maximumTerms);
1201 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1202 srw_pdu->u.scan_request->stylesheet);
1204 case Z_SRW_update_request:
1205 value[i++] = "update";
1210 if (srw_pdu->extra_args)
1212 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1213 for (; ea && i < max_names-1; ea = ea->next)
1216 value[i] = ea->value;
1225 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1226 ODR encode, const char *charset)
1228 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1232 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1233 srw_pdu->username, srw_pdu->password);
1234 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1236 yaz_array_to_uri(&uri_args, encode, name, value);
1238 hreq->method = "GET";
1241 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1243 sprintf(path, "%s?%s", hreq->path, uri_args);
1244 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1247 z_HTTP_header_add_content_type(encode, &hreq->headers,
1248 "text/xml", charset);
1252 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1253 ODR encode, const char *charset)
1255 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1258 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1259 srw_pdu->username, srw_pdu->password);
1260 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1263 yaz_array_to_uri(&uri_args, encode, name, value);
1265 hreq->method = "POST";
1267 hreq->content_buf = uri_args;
1268 hreq->content_len = strlen(uri_args);
1270 z_HTTP_header_add_content_type(encode, &hreq->headers,
1271 "application/x-www-form-urlencoded",
1276 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1277 ODR odr, const char *charset)
1279 Z_SOAP_Handler handlers[3] = {
1281 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1282 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1286 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1288 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1289 srw_pdu->username, srw_pdu->password);
1290 z_HTTP_header_add_content_type(odr,
1292 "text/xml", charset);
1294 z_HTTP_header_add(odr, &hreq->headers,
1295 "SOAPAction", "\"\"");
1296 p->which = Z_SOAP_generic;
1297 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1298 p->u.generic->no = 0;
1299 p->u.generic->ns = 0;
1300 p->u.generic->p = srw_pdu;
1301 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1304 if (srw_pdu->which == Z_SRW_update_request ||
1305 srw_pdu->which == Z_SRW_update_response)
1306 p->u.generic->no = 1; /* second handler */
1308 return z_soap_codec_enc(odr, &p,
1310 &hreq->content_len, handlers,
1314 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1316 Z_SRW_recordVersion *ver
1317 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1319 for (i = 0; i < num; ++i)
1321 ver[i].versionType = 0;
1322 ver[i].versionValue = 0;
1327 const char *yaz_srw_pack_to_str(int pack)
1331 case Z_SRW_recordPacking_string:
1333 case Z_SRW_recordPacking_XML:
1335 case Z_SRW_recordPacking_URL:
1341 int yaz_srw_str_to_pack(const char *str)
1343 if (!yaz_matchstr(str, "string"))
1344 return Z_SRW_recordPacking_string;
1345 if (!yaz_matchstr(str, "xml"))
1346 return Z_SRW_recordPacking_XML;
1347 if (!yaz_matchstr(str, "url"))
1348 return Z_SRW_recordPacking_URL;
1352 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1358 Z_SRW_extra_arg **ea = &sr->extra_args;
1359 yaz_uri_to_array(extra_args, odr, &name, &val);
1363 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1364 (*ea)->name = *name;
1365 (*ea)->value = *val;
1378 * c-file-style: "Stroustrup"
1379 * indent-tabs-mode: nil
1381 * vim: shiftwidth=4 tabstop=8 expandtab