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 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 Z_SRW_extra_arg *extra_args = 0;
445 grab_charset(decode, content_type, charset);
446 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
451 p1 = strchr(p0, '?');
453 p1 = p0 + strlen(p0);
455 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
456 if (!strcmp(hreq->method, "POST"))
457 p1 = hreq->content_buf;
458 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
463 for (i = 0; uri_name[i]; i++)
465 char *n = uri_name[i];
466 char *v = uri_val[i];
467 if (!strcmp(n, "query"))
469 else if (!strcmp(n, "x-pquery"))
471 else if (!strcmp(n, "x-username"))
473 else if (!strcmp(n, "x-password"))
475 else if (!strcmp(n, "operation"))
477 else if (!strcmp(n, "stylesheet"))
479 else if (!strcmp(n, "sortKeys"))
481 else if (!strcmp(n, "recordXPath"))
483 else if (!strcmp(n, "recordSchema"))
485 else if (!strcmp(n, "recordPacking"))
487 else if (!strcmp(n, "version"))
489 else if (!strcmp(n, "scanClause"))
491 else if (!strcmp(n, "x-pScanClause"))
493 else if (!strcmp(n, "maximumRecords"))
495 else if (!strcmp(n, "startRecord"))
497 else if (!strcmp(n, "maximumTerms"))
499 else if (!strcmp(n, "responsePosition"))
500 responsePosition = v;
501 else if (!strcmp(n, "extraRequestData"))
502 ; /* ignoring extraRequestData */
503 else if (n[0] == 'x' && n[1] == '-')
505 Z_SRW_extra_arg **l = &extra_args;
508 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
509 (*l)->name = odr_strdup(decode, n);
510 (*l)->value = odr_strdup(decode, v);
514 yaz_add_srw_diagnostic(decode, diag, num_diag,
515 YAZ_SRW_UNSUPP_PARAMETER, n);
521 yaz_add_srw_diagnostic(
522 decode, diag, num_diag,
523 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
527 version = yaz_negotiate_sru_version(version);
530 { /* negotiation failed. */
531 yaz_add_srw_diagnostic(decode, diag, num_diag,
532 YAZ_SRW_UNSUPP_VERSION, "1.2");
539 yaz_add_srw_diagnostic(
540 decode, diag, num_diag,
541 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
542 operation = "explain";
544 if (!strcmp(operation, "searchRetrieve"))
546 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
548 sr->srw_version = version;
549 sr->extra_args = extra_args;
551 yaz_srw_decodeauth(sr, hreq, username, password, decode);
554 sr->u.request->query_type = Z_SRW_query_type_cql;
555 sr->u.request->query.cql = query;
559 sr->u.request->query_type = Z_SRW_query_type_pqf;
560 sr->u.request->query.pqf = pQuery;
563 yaz_add_srw_diagnostic(
564 decode, diag, num_diag,
565 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
569 sr->u.request->sort_type = Z_SRW_sort_type_sort;
570 sr->u.request->sort.sortKeys = sortKeys;
572 sr->u.request->recordXPath = recordXPath;
573 sr->u.request->recordSchema = recordSchema;
574 sr->u.request->recordPacking = recordPacking;
575 sr->u.request->stylesheet = stylesheet;
577 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
578 &sr->u.request->maximumRecords,
581 yaz_sru_decode_integer(decode, "startRecord", startRecord,
582 &sr->u.request->startRecord,
585 sr->u.request->database = db;
587 (*soap_package) = (Z_SOAP *)
588 odr_malloc(decode, sizeof(**soap_package));
589 (*soap_package)->which = Z_SOAP_generic;
591 (*soap_package)->u.generic = (Z_SOAP_Generic *)
592 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
594 (*soap_package)->u.generic->p = sr;
595 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
596 (*soap_package)->u.generic->no = 0;
598 (*soap_package)->ns = "SRU";
602 else if (!strcmp(operation, "explain"))
604 /* Transfer SRU explain parameters to common struct */
605 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
606 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
608 sr->srw_version = version;
609 sr->extra_args = extra_args;
610 yaz_srw_decodeauth(sr, hreq, username, password, decode);
612 sr->u.explain_request->recordPacking = recordPacking;
613 sr->u.explain_request->database = db;
615 sr->u.explain_request->stylesheet = stylesheet;
617 (*soap_package) = (Z_SOAP *)
618 odr_malloc(decode, sizeof(**soap_package));
619 (*soap_package)->which = Z_SOAP_generic;
621 (*soap_package)->u.generic = (Z_SOAP_Generic *)
622 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
624 (*soap_package)->u.generic->p = sr;
625 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
626 (*soap_package)->u.generic->no = 0;
628 (*soap_package)->ns = "SRU";
632 else if (!strcmp(operation, "scan"))
634 /* Transfer SRU scan parameters to common struct */
635 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
636 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
638 sr->srw_version = version;
639 sr->extra_args = extra_args;
641 yaz_srw_decodeauth(sr, hreq, username, password, decode);
645 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
646 sr->u.scan_request->scanClause.cql = scanClause;
648 else if (pScanClause)
650 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
651 sr->u.scan_request->scanClause.pqf = pScanClause;
654 yaz_add_srw_diagnostic(
655 decode, diag, num_diag,
656 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
657 sr->u.scan_request->database = db;
659 yaz_sru_decode_integer(decode, "maximumTerms",
661 &sr->u.scan_request->maximumTerms,
664 yaz_sru_decode_integer(decode, "responsePosition",
666 &sr->u.scan_request->responsePosition,
669 sr->u.scan_request->stylesheet = stylesheet;
671 (*soap_package) = (Z_SOAP *)
672 odr_malloc(decode, sizeof(**soap_package));
673 (*soap_package)->which = Z_SOAP_generic;
675 (*soap_package)->u.generic = (Z_SOAP_Generic *)
676 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
678 (*soap_package)->u.generic->p = sr;
679 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
680 (*soap_package)->u.generic->no = 0;
682 (*soap_package)->ns = "SRU";
688 /* unsupported operation ... */
689 /* Act as if we received a explain request and throw diagnostic. */
691 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
693 sr->srw_version = version;
695 sr->u.explain_request->recordPacking = recordPacking;
696 sr->u.explain_request->database = db;
698 sr->u.explain_request->stylesheet = stylesheet;
700 (*soap_package) = (Z_SOAP *)
701 odr_malloc(decode, sizeof(**soap_package));
702 (*soap_package)->which = Z_SOAP_generic;
704 (*soap_package)->u.generic = (Z_SOAP_Generic *)
705 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
707 (*soap_package)->u.generic->p = sr;
708 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
709 (*soap_package)->u.generic->no = 0;
711 (*soap_package)->ns = "SRU";
713 yaz_add_srw_diagnostic(decode, diag, num_diag,
714 YAZ_SRW_UNSUPP_OPERATION, operation);
723 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
725 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
726 odr_malloc(o, sizeof(*res));
728 res->extraRecordData_buf = 0;
729 res->extraRecordData_len = 0;
730 res->recordIdentifier = 0;
735 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
737 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
740 for (i = 0; i<n; i++)
742 res[i].recordSchema = 0;
743 res[i].recordPacking = Z_SRW_recordPacking_string;
744 res[i].recordData_buf = 0;
745 res[i].recordData_len = 0;
746 res[i].recordPosition = 0;
751 Z_SRW_record *yaz_srw_get_record(ODR o)
753 return yaz_srw_get_records(o, 1);
756 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
758 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
759 p->srw_version = odr_strdup(o, version);
763 p->extraResponseData_buf = 0;
764 p->extraResponseData_len = 0;
768 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
770 return yaz_srw_get_core_ver(o, "1.1");
773 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
775 return yaz_srw_get_pdu(o, which, "1.1");
778 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
780 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
785 case Z_SRW_searchRetrieve_request:
786 sr->u.request = (Z_SRW_searchRetrieveRequest *)
787 odr_malloc(o, sizeof(*sr->u.request));
788 sr->u.request->query_type = Z_SRW_query_type_cql;
789 sr->u.request->query.cql = 0;
790 sr->u.request->sort_type = Z_SRW_sort_type_none;
791 sr->u.request->sort.none = 0;
792 sr->u.request->startRecord = 0;
793 sr->u.request->maximumRecords = 0;
794 sr->u.request->recordSchema = 0;
795 sr->u.request->recordPacking = 0;
796 sr->u.request->recordXPath = 0;
797 sr->u.request->database = 0;
798 sr->u.request->resultSetTTL = 0;
799 sr->u.request->stylesheet = 0;
800 sr->u.request->facetList = 0;
802 case Z_SRW_searchRetrieve_response:
803 sr->u.response = (Z_SRW_searchRetrieveResponse *)
804 odr_malloc(o, sizeof(*sr->u.response));
805 sr->u.response->numberOfRecords = 0;
806 sr->u.response->resultSetId = 0;
807 sr->u.response->resultSetIdleTime = 0;
808 sr->u.response->records = 0;
809 sr->u.response->num_records = 0;
810 sr->u.response->diagnostics = 0;
811 sr->u.response->num_diagnostics = 0;
812 sr->u.response->nextRecordPosition = 0;
813 sr->u.response->extra_records = 0;
814 sr->u.response->facetList = 0;
816 case Z_SRW_explain_request:
817 sr->u.explain_request = (Z_SRW_explainRequest *)
818 odr_malloc(o, sizeof(*sr->u.explain_request));
819 sr->u.explain_request->recordPacking = 0;
820 sr->u.explain_request->database = 0;
821 sr->u.explain_request->stylesheet = 0;
823 case Z_SRW_explain_response:
824 sr->u.explain_response = (Z_SRW_explainResponse *)
825 odr_malloc(o, sizeof(*sr->u.explain_response));
826 sr->u.explain_response->record.recordData_buf = 0;
827 sr->u.explain_response->record.recordData_len = 0;
828 sr->u.explain_response->record.recordSchema = 0;
829 sr->u.explain_response->record.recordPosition = 0;
830 sr->u.explain_response->record.recordPacking =
831 Z_SRW_recordPacking_string;
832 sr->u.explain_response->diagnostics = 0;
833 sr->u.explain_response->num_diagnostics = 0;
834 sr->u.explain_response->extra_record = 0;
836 case Z_SRW_scan_request:
837 sr->u.scan_request = (Z_SRW_scanRequest *)
838 odr_malloc(o, sizeof(*sr->u.scan_request));
839 sr->u.scan_request->database = 0;
840 sr->u.scan_request->stylesheet = 0;
841 sr->u.scan_request->maximumTerms = 0;
842 sr->u.scan_request->responsePosition = 0;
843 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
844 sr->u.scan_request->scanClause.cql = 0;
846 case Z_SRW_scan_response:
847 sr->u.scan_response = (Z_SRW_scanResponse *)
848 odr_malloc(o, sizeof(*sr->u.scan_response));
849 sr->u.scan_response->terms = 0;
850 sr->u.scan_response->num_terms = 0;
851 sr->u.scan_response->diagnostics = 0;
852 sr->u.scan_response->num_diagnostics = 0;
854 case Z_SRW_update_request:
855 sr->u.update_request = (Z_SRW_updateRequest *)
856 odr_malloc(o, sizeof(*sr->u.update_request));
857 sr->u.update_request->database = 0;
858 sr->u.update_request->stylesheet = 0;
859 sr->u.update_request->record = 0;
860 sr->u.update_request->recordId = 0;
861 sr->u.update_request->recordVersions = 0;
862 sr->u.update_request->num_recordVersions = 0;
863 sr->u.update_request->extra_record = 0;
864 sr->u.update_request->extraRequestData_buf = 0;
865 sr->u.update_request->extraRequestData_len = 0;
866 sr->u.request->database = 0;
868 case Z_SRW_update_response:
869 sr->u.update_response = (Z_SRW_updateResponse *)
870 odr_malloc(o, sizeof(*sr->u.update_response));
871 sr->u.update_response->operationStatus = 0;
872 sr->u.update_response->recordId = 0;
873 sr->u.update_response->recordVersions = 0;
874 sr->u.update_response->num_recordVersions = 0;
875 sr->u.update_response->record = 0;
876 sr->u.update_response->extra_record = 0;
877 sr->u.update_response->extraResponseData_buf = 0;
878 sr->u.update_response->extraResponseData_len = 0;
879 sr->u.update_response->diagnostics = 0;
880 sr->u.update_response->num_diagnostics = 0;
886 static int bib1_srw_map[] = {
896 108, 10, /* Malformed query : Syntax error */
926 100, 1, /* bad map */
974 205, 1, /* bad map */
975 206, 1, /* bad map */
977 208, 1, /* bad map */
988 218, 1, /* bad map */
989 219, 1, /* bad map */
990 220, 1, /* bad map */
991 221, 1, /* bad map */
993 223, 1, /* bad map */
994 224, 1, /* bad map */
995 225, 1, /* bad map */
996 226, 1, /* bad map */
998 228, 1, /* bad map */
1003 233, 1, /* bad map */
1004 234, 1, /* bad map */
1010 240, 1, /* bad map */
1011 241, 1, /* bad map */
1013 243, 1, /* bad map */
1018 1001, 1, /* bad map */
1019 1002, 1, /* bad map */
1020 1003, 1, /* bad map */
1021 1004, 1, /* bad map */
1022 1005, 1, /* bad map */
1023 1006, 1, /* bad map */
1056 * This array contains overrides for when the first occurrence of a
1057 * particular SRW error in the array above does not correspond with
1058 * the best back-translation of that SRW error.
1060 static int srw_bib1_map[] = {
1062 /* No doubt there are many more */
1067 int yaz_diag_bib1_to_srw (int code)
1069 const int *p = bib1_srw_map;
1079 int yaz_diag_srw_to_bib1(int code)
1081 /* Check explicit reverse-map first */
1082 const int *p = srw_bib1_map;
1090 /* Fall back on reverse lookup in main map */
1101 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1102 char *a_name, Odr_int *val)
1107 value[*i] = (char *) odr_malloc(o, 40);
1108 sprintf(value[*i], ODR_INT_PRINTF, *val);
1113 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1114 char *a_name, char *val)
1124 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1125 char **name, char **value, int max_names)
1128 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1129 name[i] = "operation";
1130 switch(srw_pdu->which)
1132 case Z_SRW_searchRetrieve_request:
1133 value[i++] = "searchRetrieve";
1134 switch(srw_pdu->u.request->query_type)
1136 case Z_SRW_query_type_cql:
1137 yaz_add_name_value_str(encode, name, value, &i, "query",
1138 srw_pdu->u.request->query.cql);
1140 case Z_SRW_query_type_pqf:
1141 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1142 srw_pdu->u.request->query.pqf);
1144 case Z_SRW_query_type_xcql:
1145 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1146 srw_pdu->u.request->query.xcql);
1149 switch(srw_pdu->u.request->sort_type)
1151 case Z_SRW_sort_type_none:
1153 case Z_SRW_sort_type_sort:
1154 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1155 srw_pdu->u.request->sort.sortKeys);
1158 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1159 srw_pdu->u.request->startRecord);
1160 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1161 srw_pdu->u.request->maximumRecords);
1162 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1163 srw_pdu->u.request->recordSchema);
1164 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1165 srw_pdu->u.request->recordPacking);
1166 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1167 srw_pdu->u.request->recordXPath);
1168 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1169 srw_pdu->u.request->stylesheet);
1170 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1171 srw_pdu->u.request->resultSetTTL);
1173 case Z_SRW_explain_request:
1174 value[i++] = "explain";
1175 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1176 srw_pdu->u.explain_request->stylesheet);
1178 case Z_SRW_scan_request:
1179 value[i++] = "scan";
1181 switch(srw_pdu->u.scan_request->query_type)
1183 case Z_SRW_query_type_cql:
1184 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1185 srw_pdu->u.scan_request->scanClause.cql);
1187 case Z_SRW_query_type_pqf:
1188 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1189 srw_pdu->u.scan_request->scanClause.pqf);
1191 case Z_SRW_query_type_xcql:
1192 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1193 srw_pdu->u.scan_request->scanClause.xcql);
1196 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1197 srw_pdu->u.scan_request->responsePosition);
1198 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1199 srw_pdu->u.scan_request->maximumTerms);
1200 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1201 srw_pdu->u.scan_request->stylesheet);
1203 case Z_SRW_update_request:
1204 value[i++] = "update";
1209 if (srw_pdu->extra_args)
1211 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1212 for (; ea && i < max_names-1; ea = ea->next)
1215 value[i] = ea->value;
1224 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1225 ODR encode, const char *charset)
1227 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1231 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1232 srw_pdu->username, srw_pdu->password);
1233 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1235 yaz_array_to_uri(&uri_args, encode, name, value);
1237 hreq->method = "GET";
1240 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1242 sprintf(path, "%s?%s", hreq->path, uri_args);
1243 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1246 z_HTTP_header_add_content_type(encode, &hreq->headers,
1247 "text/xml", charset);
1251 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1252 ODR encode, const char *charset)
1254 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1257 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1258 srw_pdu->username, srw_pdu->password);
1259 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1262 yaz_array_to_uri(&uri_args, encode, name, value);
1264 hreq->method = "POST";
1266 hreq->content_buf = uri_args;
1267 hreq->content_len = strlen(uri_args);
1269 z_HTTP_header_add_content_type(encode, &hreq->headers,
1270 "application/x-www-form-urlencoded",
1275 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1276 ODR odr, const char *charset)
1278 Z_SOAP_Handler handlers[3] = {
1280 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1281 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1285 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1287 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1288 srw_pdu->username, srw_pdu->password);
1289 z_HTTP_header_add_content_type(odr,
1291 "text/xml", charset);
1293 z_HTTP_header_add(odr, &hreq->headers,
1294 "SOAPAction", "\"\"");
1295 p->which = Z_SOAP_generic;
1296 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1297 p->u.generic->no = 0;
1298 p->u.generic->ns = 0;
1299 p->u.generic->p = srw_pdu;
1300 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1303 if (srw_pdu->which == Z_SRW_update_request ||
1304 srw_pdu->which == Z_SRW_update_response)
1305 p->u.generic->no = 1; /* second handler */
1307 return z_soap_codec_enc(odr, &p,
1309 &hreq->content_len, handlers,
1313 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1315 Z_SRW_recordVersion *ver
1316 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1318 for (i = 0; i < num; ++i)
1320 ver[i].versionType = 0;
1321 ver[i].versionValue = 0;
1326 const char *yaz_srw_pack_to_str(int pack)
1330 case Z_SRW_recordPacking_string:
1332 case Z_SRW_recordPacking_XML:
1334 case Z_SRW_recordPacking_URL:
1340 int yaz_srw_str_to_pack(const char *str)
1342 if (!yaz_matchstr(str, "string"))
1343 return Z_SRW_recordPacking_string;
1344 if (!yaz_matchstr(str, "xml"))
1345 return Z_SRW_recordPacking_XML;
1346 if (!yaz_matchstr(str, "url"))
1347 return Z_SRW_recordPacking_URL;
1351 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1357 Z_SRW_extra_arg **ea = &sr->extra_args;
1358 yaz_uri_to_array(extra_args, odr, &name, &val);
1362 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1363 (*ea)->name = *name;
1364 (*ea)->value = *val;
1377 * c-file-style: "Stroustrup"
1378 * indent-tabs-mode: nil
1380 * vim: shiftwidth=4 tabstop=8 expandtab