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 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
22 return odr_strdupn(n, uri, len);
25 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
32 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
34 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
35 yaz_encode_sru_dbpath_buf(dst, db);
39 Z_AttributeList *yaz_use_attribute_create(ODR o, const char *name)
41 Z_AttributeList *attributes= (Z_AttributeList *)
42 odr_malloc(o, sizeof(*attributes));
43 Z_AttributeElement ** elements;
44 attributes->num_attributes = 1;
45 elements = (Z_AttributeElement**)
46 odr_malloc (o, attributes->num_attributes * sizeof(*elements));
47 elements[0] = (Z_AttributeElement*) odr_malloc(o,sizeof(**elements));
48 elements[0]->attributeType = odr_intdup(o, 1);
49 elements[0]->attributeSet = odr_nullval();
50 elements[0]->which = Z_AttributeValue_complex;
51 elements[0]->value.complex = (Z_ComplexAttribute *)
52 odr_malloc(o, sizeof(Z_ComplexAttribute));
53 elements[0]->value.complex->num_list = 1;
54 elements[0]->value.complex->list = (Z_StringOrNumeric **)
55 odr_malloc(o, 1 * sizeof(Z_StringOrNumeric *));
56 elements[0]->value.complex->list[0] = (Z_StringOrNumeric *)
57 odr_malloc(o, sizeof(Z_StringOrNumeric));
58 elements[0]->value.complex->list[0]->which = Z_StringOrNumeric_string;
59 elements[0]->value.complex->list[0]->u.string = odr_strdup(o, name);
60 elements[0]->value.complex->semanticAction = 0;
61 elements[0]->value.complex->num_semanticAction = 0;
62 attributes->attributes = elements;
67 const char *yaz_element_attribute_value_get(xmlNodePtr ptr,
68 const char *node_name,
69 const char *attribute_name)
71 struct _xmlAttr *attr;
72 // check if the node name matches
73 if (strcmp((const char*) ptr->name, node_name))
75 // check if the attribute name and return the value
76 for (attr = ptr->properties; attr; attr = attr->next)
77 if (attr->children && attr->children->type == XML_TEXT_NODE)
79 if (!strcmp((const char *) attr->name, attribute_name))
80 return (const char *) attr->children->content;
86 static int yaz_base64decode(const char *in, char *out)
88 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
89 "abcdefghijklmnopqrstuvwxyz0123456789+/";
98 if (!(p = strchr(map, in[0])))
102 if (!(p = strchr(map, in[1])))
106 *(out++) = i0 << 2 | i1 >> 4;
110 if (!(p = strchr(map, in[2])))
114 *(out++) = i1 << 4 | i2 >> 2;
118 if (!(p = strchr(map, in[3])))
122 *(out++) = i2 << 6 | i3;
132 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
134 const char *content_type = z_HTTP_header_lookup(hres->headers,
138 if (!yaz_strcmp_del("text/xml", content_type, "; "))
140 if (!yaz_strcmp_del("application/xml", content_type, "; "))
147 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
148 * parameters. Added by SH.
150 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
151 char *username, char *password, ODR decode)
153 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
156 sr->username = username;
158 sr->password = password;
164 char ubuf[256] = "", pbuf[256] = "", *p;
165 if (strncmp(basic, "Basic ", 6))
169 if (!len || len > 256)
171 olen = yaz_base64decode(basic, out);
172 /* Format of out should be username:password at this point */
174 if ((p = strchr(ubuf, ':')))
181 sr->username = odr_strdup(decode, ubuf);
183 sr->password = odr_strdup(decode, pbuf);
187 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
189 const char *v = yaz_uri_val(path, name, o);
191 *intp = odr_intdup(o, atoi(v));
194 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
195 const char *uri, const char *message,
198 d->uri = odr_strdup(o, uri);
200 d->message = odr_strdup(o, message);
204 d->details = odr_strdup(o, details);
209 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
210 int code, const char *details)
214 sprintf(uri, "info:srw/diagnostic/1/%d", code);
215 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
218 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
219 int *num, const char *uri,
220 const char *message, const char *details)
222 Z_SRW_diagnostic *d_new;
223 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
225 memcpy (d_new, *d, *num *sizeof(**d));
228 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
232 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
233 int *num, int code, const char *addinfo)
237 sprintf(uri, "info:srw/diagnostic/1/%d", code);
238 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
242 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
243 int *num, int code, const char *addinfo)
247 sprintf(uri, "info:srw/diagnostic/12/%d", code);
248 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
252 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
253 int code, const char *details)
255 const char *message = yaz_diag_srw_str(code);
258 len += strlen(message);
260 len += strlen(details);
262 record->recordData_buf = (char *) odr_malloc(o, len);
264 sprintf(record->recordData_buf, "<diagnostic "
265 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
266 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
268 sprintf(record->recordData_buf + strlen(record->recordData_buf),
269 " <details>%s</details>\n", details);
271 sprintf(record->recordData_buf + strlen(record->recordData_buf),
272 " <message>%s</message>\n", message);
273 sprintf(record->recordData_buf + strlen(record->recordData_buf),
275 record->recordData_len = strlen(record->recordData_buf);
276 record->recordPosition = odr_intdup(o, pos);
277 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
280 static void grab_charset(ODR o, const char *content_type, char **charset)
284 const char *charset_p = 0;
285 if (content_type && (charset_p = strstr(content_type, "; charset=")))
289 while (i < 20 && charset_p[i] &&
290 !strchr("; \n\r", charset_p[i]))
292 *charset = (char*) odr_malloc(o, i+1);
293 memcpy(*charset, charset_p, i);
294 (*charset)[i] = '\0';
299 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
300 Z_SOAP **soap_package, ODR decode, char **charset)
302 if (!strcmp(hreq->method, "POST"))
304 const char *content_type = z_HTTP_header_lookup(hreq->headers,
307 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
308 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
309 !yaz_strcmp_del("text/plain", content_type, "; ")))
311 char *db = "Default";
312 const char *p0 = hreq->path, *p1;
315 static Z_SOAP_Handler soap_handlers[4] = {
317 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
318 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
319 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
326 p1 = strchr(p0, '?');
328 p1 = p0 + strlen(p0);
330 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
331 grab_charset(decode, content_type, charset);
333 ret = z_soap_codec(decode, soap_package,
334 &hreq->content_buf, &hreq->content_len,
336 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
338 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
339 yaz_srw_decodeauth(*srw_pdu, hreq, 0, 0, decode);
341 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
342 (*srw_pdu)->u.request->database == 0)
343 (*srw_pdu)->u.request->database = db;
345 if ((*srw_pdu)->which == Z_SRW_explain_request &&
346 (*srw_pdu)->u.explain_request->database == 0)
347 (*srw_pdu)->u.explain_request->database = db;
349 if ((*srw_pdu)->which == Z_SRW_scan_request &&
350 (*srw_pdu)->u.scan_request->database == 0)
351 (*srw_pdu)->u.scan_request->database = db;
353 if ((*srw_pdu)->which == Z_SRW_update_request &&
354 (*srw_pdu)->u.update_request->database == 0)
355 (*srw_pdu)->u.update_request->database = db;
366 static int yaz_sru_decode_integer(ODR odr, const char *pname,
367 const char *valstr, Odr_int **valp,
368 Z_SRW_diagnostic **diag, int *num_diag,
374 if (sscanf(valstr, "%d", &ival) != 1)
376 yaz_add_srw_diagnostic(odr, diag, num_diag,
377 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
380 if (min_value >= 0 && ival < min_value)
382 yaz_add_srw_diagnostic(odr, diag, num_diag,
383 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
386 *valp = odr_intdup(odr, ival);
392 http://www.loc.gov/z3950/agency/zing/srw/service.html
394 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
395 Z_SOAP **soap_package, ODR decode, char **charset,
396 Z_SRW_diagnostic **diag, int *num_diag)
399 static Z_SOAP_Handler soap_handlers[2] = {
400 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
404 const char *content_type = z_HTTP_header_lookup(hreq->headers,
408 SRU GET: ignore content type.
409 SRU POST: we support "application/x-www-form-urlencoded";
410 not "multipart/form-data" .
412 if (!strcmp(hreq->method, "GET")
414 (!strcmp(hreq->method, "POST") && content_type &&
415 !yaz_strcmp_del("application/x-www-form-urlencoded",
416 content_type, "; ")))
418 char *db = "Default";
419 const char *p0 = hreq->path, *p1;
421 const char *operation = 0;
428 char *stylesheet = 0;
429 char *scanClause = 0;
430 char *pScanClause = 0;
431 char *recordXPath = 0;
432 char *recordSchema = 0;
433 char *recordPacking = "xml"; /* xml packing is default for SRU */
434 char *maximumRecords = 0;
435 char *startRecord = 0;
436 char *maximumTerms = 0;
437 char *responsePosition = 0;
438 char *extraRequestData = 0;
439 Z_SRW_extra_arg *extra_args = 0;
444 grab_charset(decode, content_type, charset);
445 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
450 p1 = strchr(p0, '?');
452 p1 = p0 + strlen(p0);
454 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
455 if (!strcmp(hreq->method, "POST"))
456 p1 = hreq->content_buf;
457 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
462 for (i = 0; uri_name[i]; i++)
464 char *n = uri_name[i];
465 char *v = uri_val[i];
466 if (!strcmp(n, "query"))
468 else if (!strcmp(n, "x-pquery"))
470 else if (!strcmp(n, "x-username"))
472 else if (!strcmp(n, "x-password"))
474 else if (!strcmp(n, "operation"))
476 else if (!strcmp(n, "stylesheet"))
478 else if (!strcmp(n, "sortKeys"))
480 else if (!strcmp(n, "recordXPath"))
482 else if (!strcmp(n, "recordSchema"))
484 else if (!strcmp(n, "recordPacking"))
486 else if (!strcmp(n, "version"))
488 else if (!strcmp(n, "scanClause"))
490 else if (!strcmp(n, "x-pScanClause"))
492 else if (!strcmp(n, "maximumRecords"))
494 else if (!strcmp(n, "startRecord"))
496 else if (!strcmp(n, "maximumTerms"))
498 else if (!strcmp(n, "responsePosition"))
499 responsePosition = v;
500 else if (!strcmp(n, "extraRequestData"))
501 extraRequestData = v;
502 else if (n[0] == 'x' && n[1] == '-')
504 Z_SRW_extra_arg **l = &extra_args;
507 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
508 (*l)->name = odr_strdup(decode, n);
509 (*l)->value = odr_strdup(decode, v);
513 yaz_add_srw_diagnostic(decode, diag, num_diag,
514 YAZ_SRW_UNSUPP_PARAMETER, n);
520 yaz_add_srw_diagnostic(
521 decode, diag, num_diag,
522 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
526 version = yaz_negotiate_sru_version(version);
529 { /* negotiation failed. */
530 yaz_add_srw_diagnostic(decode, diag, num_diag,
531 YAZ_SRW_UNSUPP_VERSION, "1.2");
538 yaz_add_srw_diagnostic(
539 decode, diag, num_diag,
540 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
541 operation = "explain";
543 if (!strcmp(operation, "searchRetrieve"))
545 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
547 sr->srw_version = version;
548 sr->extra_args = extra_args;
550 yaz_srw_decodeauth(sr, hreq, username, password, decode);
553 sr->u.request->query_type = Z_SRW_query_type_cql;
554 sr->u.request->query.cql = query;
558 sr->u.request->query_type = Z_SRW_query_type_pqf;
559 sr->u.request->query.pqf = pQuery;
562 yaz_add_srw_diagnostic(
563 decode, diag, num_diag,
564 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
568 sr->u.request->sort_type = Z_SRW_sort_type_sort;
569 sr->u.request->sort.sortKeys = sortKeys;
571 sr->u.request->recordXPath = recordXPath;
572 sr->u.request->recordSchema = recordSchema;
573 sr->u.request->recordPacking = recordPacking;
574 sr->u.request->stylesheet = stylesheet;
576 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
577 &sr->u.request->maximumRecords,
580 yaz_sru_decode_integer(decode, "startRecord", startRecord,
581 &sr->u.request->startRecord,
584 sr->u.request->database = db;
586 (*soap_package) = (Z_SOAP *)
587 odr_malloc(decode, sizeof(**soap_package));
588 (*soap_package)->which = Z_SOAP_generic;
590 (*soap_package)->u.generic = (Z_SOAP_Generic *)
591 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
593 (*soap_package)->u.generic->p = sr;
594 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
595 (*soap_package)->u.generic->no = 0;
597 (*soap_package)->ns = "SRU";
601 else if (!strcmp(operation, "explain"))
603 /* Transfer SRU explain parameters to common struct */
604 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
605 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
607 sr->srw_version = version;
608 sr->extra_args = extra_args;
609 yaz_srw_decodeauth(sr, hreq, username, password, decode);
611 sr->u.explain_request->recordPacking = recordPacking;
612 sr->u.explain_request->database = db;
614 sr->u.explain_request->stylesheet = stylesheet;
616 (*soap_package) = (Z_SOAP *)
617 odr_malloc(decode, sizeof(**soap_package));
618 (*soap_package)->which = Z_SOAP_generic;
620 (*soap_package)->u.generic = (Z_SOAP_Generic *)
621 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
623 (*soap_package)->u.generic->p = sr;
624 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
625 (*soap_package)->u.generic->no = 0;
627 (*soap_package)->ns = "SRU";
631 else if (!strcmp(operation, "scan"))
633 /* Transfer SRU scan parameters to common struct */
634 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
635 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
637 sr->srw_version = version;
638 sr->extra_args = extra_args;
640 yaz_srw_decodeauth(sr, hreq, username, password, decode);
644 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
645 sr->u.scan_request->scanClause.cql = scanClause;
647 else if (pScanClause)
649 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
650 sr->u.scan_request->scanClause.pqf = pScanClause;
653 yaz_add_srw_diagnostic(
654 decode, diag, num_diag,
655 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
656 sr->u.scan_request->database = db;
658 yaz_sru_decode_integer(decode, "maximumTerms",
660 &sr->u.scan_request->maximumTerms,
663 yaz_sru_decode_integer(decode, "responsePosition",
665 &sr->u.scan_request->responsePosition,
668 sr->u.scan_request->stylesheet = stylesheet;
670 (*soap_package) = (Z_SOAP *)
671 odr_malloc(decode, sizeof(**soap_package));
672 (*soap_package)->which = Z_SOAP_generic;
674 (*soap_package)->u.generic = (Z_SOAP_Generic *)
675 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
677 (*soap_package)->u.generic->p = sr;
678 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
679 (*soap_package)->u.generic->no = 0;
681 (*soap_package)->ns = "SRU";
687 /* unsupported operation ... */
688 /* Act as if we received a explain request and throw diagnostic. */
690 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
692 sr->srw_version = version;
694 sr->u.explain_request->recordPacking = recordPacking;
695 sr->u.explain_request->database = db;
697 sr->u.explain_request->stylesheet = stylesheet;
699 (*soap_package) = (Z_SOAP *)
700 odr_malloc(decode, sizeof(**soap_package));
701 (*soap_package)->which = Z_SOAP_generic;
703 (*soap_package)->u.generic = (Z_SOAP_Generic *)
704 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
706 (*soap_package)->u.generic->p = sr;
707 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
708 (*soap_package)->u.generic->no = 0;
710 (*soap_package)->ns = "SRU";
712 yaz_add_srw_diagnostic(decode, diag, num_diag,
713 YAZ_SRW_UNSUPP_OPERATION, operation);
722 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
724 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
725 odr_malloc(o, sizeof(*res));
727 res->extraRecordData_buf = 0;
728 res->extraRecordData_len = 0;
729 res->recordIdentifier = 0;
734 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
736 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
739 for (i = 0; i<n; i++)
741 res[i].recordSchema = 0;
742 res[i].recordPacking = Z_SRW_recordPacking_string;
743 res[i].recordData_buf = 0;
744 res[i].recordData_len = 0;
745 res[i].recordPosition = 0;
750 Z_SRW_record *yaz_srw_get_record(ODR o)
752 return yaz_srw_get_records(o, 1);
755 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
757 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
758 p->srw_version = odr_strdup(o, version);
762 p->extraResponseData_buf = 0;
763 p->extraResponseData_len = 0;
767 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
769 return yaz_srw_get_core_ver(o, "1.1");
772 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
774 return yaz_srw_get_pdu(o, which, "1.1");
777 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
779 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
784 case Z_SRW_searchRetrieve_request:
785 sr->u.request = (Z_SRW_searchRetrieveRequest *)
786 odr_malloc(o, sizeof(*sr->u.request));
787 sr->u.request->query_type = Z_SRW_query_type_cql;
788 sr->u.request->query.cql = 0;
789 sr->u.request->sort_type = Z_SRW_sort_type_none;
790 sr->u.request->sort.none = 0;
791 sr->u.request->startRecord = 0;
792 sr->u.request->maximumRecords = 0;
793 sr->u.request->recordSchema = 0;
794 sr->u.request->recordPacking = 0;
795 sr->u.request->recordXPath = 0;
796 sr->u.request->database = 0;
797 sr->u.request->resultSetTTL = 0;
798 sr->u.request->stylesheet = 0;
799 sr->u.request->facetList = 0;
801 case Z_SRW_searchRetrieve_response:
802 sr->u.response = (Z_SRW_searchRetrieveResponse *)
803 odr_malloc(o, sizeof(*sr->u.response));
804 sr->u.response->numberOfRecords = 0;
805 sr->u.response->resultSetId = 0;
806 sr->u.response->resultSetIdleTime = 0;
807 sr->u.response->records = 0;
808 sr->u.response->num_records = 0;
809 sr->u.response->diagnostics = 0;
810 sr->u.response->num_diagnostics = 0;
811 sr->u.response->nextRecordPosition = 0;
812 sr->u.response->extra_records = 0;
813 sr->u.response->facetList = 0;
815 case Z_SRW_explain_request:
816 sr->u.explain_request = (Z_SRW_explainRequest *)
817 odr_malloc(o, sizeof(*sr->u.explain_request));
818 sr->u.explain_request->recordPacking = 0;
819 sr->u.explain_request->database = 0;
820 sr->u.explain_request->stylesheet = 0;
822 case Z_SRW_explain_response:
823 sr->u.explain_response = (Z_SRW_explainResponse *)
824 odr_malloc(o, sizeof(*sr->u.explain_response));
825 sr->u.explain_response->record.recordData_buf = 0;
826 sr->u.explain_response->record.recordData_len = 0;
827 sr->u.explain_response->record.recordSchema = 0;
828 sr->u.explain_response->record.recordPosition = 0;
829 sr->u.explain_response->record.recordPacking =
830 Z_SRW_recordPacking_string;
831 sr->u.explain_response->diagnostics = 0;
832 sr->u.explain_response->num_diagnostics = 0;
833 sr->u.explain_response->extra_record = 0;
835 case Z_SRW_scan_request:
836 sr->u.scan_request = (Z_SRW_scanRequest *)
837 odr_malloc(o, sizeof(*sr->u.scan_request));
838 sr->u.scan_request->database = 0;
839 sr->u.scan_request->stylesheet = 0;
840 sr->u.scan_request->maximumTerms = 0;
841 sr->u.scan_request->responsePosition = 0;
842 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
843 sr->u.scan_request->scanClause.cql = 0;
845 case Z_SRW_scan_response:
846 sr->u.scan_response = (Z_SRW_scanResponse *)
847 odr_malloc(o, sizeof(*sr->u.scan_response));
848 sr->u.scan_response->terms = 0;
849 sr->u.scan_response->num_terms = 0;
850 sr->u.scan_response->diagnostics = 0;
851 sr->u.scan_response->num_diagnostics = 0;
853 case Z_SRW_update_request:
854 sr->u.update_request = (Z_SRW_updateRequest *)
855 odr_malloc(o, sizeof(*sr->u.update_request));
856 sr->u.update_request->database = 0;
857 sr->u.update_request->stylesheet = 0;
858 sr->u.update_request->record = 0;
859 sr->u.update_request->recordId = 0;
860 sr->u.update_request->recordVersions = 0;
861 sr->u.update_request->num_recordVersions = 0;
862 sr->u.update_request->extra_record = 0;
863 sr->u.update_request->extraRequestData_buf = 0;
864 sr->u.update_request->extraRequestData_len = 0;
865 sr->u.request->database = 0;
867 case Z_SRW_update_response:
868 sr->u.update_response = (Z_SRW_updateResponse *)
869 odr_malloc(o, sizeof(*sr->u.update_response));
870 sr->u.update_response->operationStatus = 0;
871 sr->u.update_response->recordId = 0;
872 sr->u.update_response->recordVersions = 0;
873 sr->u.update_response->num_recordVersions = 0;
874 sr->u.update_response->record = 0;
875 sr->u.update_response->extra_record = 0;
876 sr->u.update_response->extraResponseData_buf = 0;
877 sr->u.update_response->extraResponseData_len = 0;
878 sr->u.update_response->diagnostics = 0;
879 sr->u.update_response->num_diagnostics = 0;
885 static int bib1_srw_map[] = {
895 108, 10, /* Malformed query : Syntax error */
925 100, 1, /* bad map */
973 205, 1, /* bad map */
974 206, 1, /* bad map */
976 208, 1, /* bad map */
987 218, 1, /* bad map */
988 219, 1, /* bad map */
989 220, 1, /* bad map */
990 221, 1, /* bad map */
992 223, 1, /* bad map */
993 224, 1, /* bad map */
994 225, 1, /* bad map */
995 226, 1, /* bad map */
997 228, 1, /* bad map */
1002 233, 1, /* bad map */
1003 234, 1, /* bad map */
1009 240, 1, /* bad map */
1010 241, 1, /* bad map */
1012 243, 1, /* bad map */
1017 1001, 1, /* bad map */
1018 1002, 1, /* bad map */
1019 1003, 1, /* bad map */
1020 1004, 1, /* bad map */
1021 1005, 1, /* bad map */
1022 1006, 1, /* bad map */
1055 * This array contains overrides for when the first occurrence of a
1056 * particular SRW error in the array above does not correspond with
1057 * the best back-translation of that SRW error.
1059 static int srw_bib1_map[] = {
1061 /* No doubt there are many more */
1066 int yaz_diag_bib1_to_srw (int code)
1068 const int *p = bib1_srw_map;
1078 int yaz_diag_srw_to_bib1(int code)
1080 /* Check explicit reverse-map first */
1081 const int *p = srw_bib1_map;
1089 /* Fall back on reverse lookup in main map */
1100 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1101 char *a_name, Odr_int *val)
1106 value[*i] = (char *) odr_malloc(o, 40);
1107 sprintf(value[*i], ODR_INT_PRINTF, *val);
1112 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1113 char *a_name, char *val)
1123 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1124 char **name, char **value, int max_names)
1127 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1128 name[i] = "operation";
1129 switch(srw_pdu->which)
1131 case Z_SRW_searchRetrieve_request:
1132 value[i++] = "searchRetrieve";
1133 switch(srw_pdu->u.request->query_type)
1135 case Z_SRW_query_type_cql:
1136 yaz_add_name_value_str(encode, name, value, &i, "query",
1137 srw_pdu->u.request->query.cql);
1139 case Z_SRW_query_type_pqf:
1140 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1141 srw_pdu->u.request->query.pqf);
1143 case Z_SRW_query_type_xcql:
1144 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1145 srw_pdu->u.request->query.xcql);
1148 switch(srw_pdu->u.request->sort_type)
1150 case Z_SRW_sort_type_none:
1152 case Z_SRW_sort_type_sort:
1153 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1154 srw_pdu->u.request->sort.sortKeys);
1157 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1158 srw_pdu->u.request->startRecord);
1159 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1160 srw_pdu->u.request->maximumRecords);
1161 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1162 srw_pdu->u.request->recordSchema);
1163 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1164 srw_pdu->u.request->recordPacking);
1165 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1166 srw_pdu->u.request->recordXPath);
1167 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1168 srw_pdu->u.request->stylesheet);
1169 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1170 srw_pdu->u.request->resultSetTTL);
1172 case Z_SRW_explain_request:
1173 value[i++] = "explain";
1174 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1175 srw_pdu->u.explain_request->stylesheet);
1177 case Z_SRW_scan_request:
1178 value[i++] = "scan";
1180 switch(srw_pdu->u.scan_request->query_type)
1182 case Z_SRW_query_type_cql:
1183 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1184 srw_pdu->u.scan_request->scanClause.cql);
1186 case Z_SRW_query_type_pqf:
1187 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1188 srw_pdu->u.scan_request->scanClause.pqf);
1190 case Z_SRW_query_type_xcql:
1191 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1192 srw_pdu->u.scan_request->scanClause.xcql);
1195 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1196 srw_pdu->u.scan_request->responsePosition);
1197 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1198 srw_pdu->u.scan_request->maximumTerms);
1199 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1200 srw_pdu->u.scan_request->stylesheet);
1202 case Z_SRW_update_request:
1203 value[i++] = "update";
1208 if (srw_pdu->extra_args)
1210 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1211 for (; ea && i < max_names-1; ea = ea->next)
1214 value[i] = ea->value;
1223 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1224 ODR encode, const char *charset)
1226 char *name[30], *value[30]; /* definite upper limit for SRU params */
1230 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1231 srw_pdu->username, srw_pdu->password);
1232 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1234 yaz_array_to_uri(&uri_args, encode, name, value);
1236 hreq->method = "GET";
1239 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1241 sprintf(path, "%s?%s", hreq->path, uri_args);
1242 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1245 z_HTTP_header_add_content_type(encode, &hreq->headers,
1246 "text/xml", charset);
1250 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1251 ODR encode, const char *charset)
1253 char *name[30], *value[30]; /* definite upper limit for SRU params */
1256 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1257 srw_pdu->username, srw_pdu->password);
1258 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1261 yaz_array_to_uri(&uri_args, encode, name, value);
1263 hreq->method = "POST";
1265 hreq->content_buf = uri_args;
1266 hreq->content_len = strlen(uri_args);
1268 z_HTTP_header_add_content_type(encode, &hreq->headers,
1269 "application/x-www-form-urlencoded",
1274 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1275 ODR odr, const char *charset)
1277 Z_SOAP_Handler handlers[3] = {
1279 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1280 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1284 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1286 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1287 srw_pdu->username, srw_pdu->password);
1288 z_HTTP_header_add_content_type(odr,
1290 "text/xml", charset);
1292 z_HTTP_header_add(odr, &hreq->headers,
1293 "SOAPAction", "\"\"");
1294 p->which = Z_SOAP_generic;
1295 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1296 p->u.generic->no = 0;
1297 p->u.generic->ns = 0;
1298 p->u.generic->p = srw_pdu;
1299 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1302 if (srw_pdu->which == Z_SRW_update_request ||
1303 srw_pdu->which == Z_SRW_update_response)
1304 p->u.generic->no = 1; /* second handler */
1306 return z_soap_codec_enc(odr, &p,
1308 &hreq->content_len, handlers,
1312 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1314 Z_SRW_recordVersion *ver
1315 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1317 for (i = 0; i < num; ++i)
1319 ver[i].versionType = 0;
1320 ver[i].versionValue = 0;
1325 const char *yaz_srw_pack_to_str(int pack)
1329 case Z_SRW_recordPacking_string:
1331 case Z_SRW_recordPacking_XML:
1333 case Z_SRW_recordPacking_URL:
1339 int yaz_srw_str_to_pack(const char *str)
1341 if (!yaz_matchstr(str, "string"))
1342 return Z_SRW_recordPacking_string;
1343 if (!yaz_matchstr(str, "xml"))
1344 return Z_SRW_recordPacking_XML;
1345 if (!yaz_matchstr(str, "url"))
1346 return Z_SRW_recordPacking_URL;
1350 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1356 Z_SRW_extra_arg **ea = &sr->extra_args;
1357 yaz_uri_to_array(extra_args, odr, &name, &val);
1361 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1362 (*ea)->name = *name;
1363 (*ea)->value = *val;
1376 * c-file-style: "Stroustrup"
1377 * indent-tabs-mode: nil
1379 * vim: shiftwidth=4 tabstop=8 expandtab