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_atttribute_create(ODR o, const char *name) {
40 Z_AttributeList *attributes= (Z_AttributeList *) odr_malloc(o, sizeof(*attributes));
41 Z_AttributeElement ** elements;
42 attributes->num_attributes = 1;
43 /* TODO check on name instead
44 if (!attributes->num_attributes) {
45 attributes->attributes = (Z_AttributeElement**)odr_nullval();
49 elements = (Z_AttributeElement**) odr_malloc (o, attributes->num_attributes * sizeof(*elements));
50 elements[0] = (Z_AttributeElement*)odr_malloc(o,sizeof(**elements));
51 elements[0]->attributeType = odr_malloc(o, sizeof(*elements[0]->attributeType));
52 *elements[0]->attributeType = 1;
53 elements[0]->attributeSet = odr_nullval();
54 elements[0]->which = Z_AttributeValue_complex;
55 elements[0]->value.complex = (Z_ComplexAttribute *) odr_malloc(o, sizeof(Z_ComplexAttribute));
56 elements[0]->value.complex->num_list = 1;
57 elements[0]->value.complex->list = (Z_StringOrNumeric **) odr_malloc(o, 1 * sizeof(Z_StringOrNumeric *));
58 elements[0]->value.complex->list[0] = (Z_StringOrNumeric *) odr_malloc(o, sizeof(Z_StringOrNumeric));
59 elements[0]->value.complex->list[0]->which = Z_StringOrNumeric_string;
60 elements[0]->value.complex->list[0]->u.string = (Z_InternationalString *) odr_strdup(o, name);
61 elements[0]->value.complex->semanticAction = 0;
62 elements[0]->value.complex->num_semanticAction = 0;
63 attributes->attributes = elements;
68 const char *yaz_element_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name) {
70 struct _xmlAttr *attr;
71 // check if the node name matches
72 if (strcmp((const char*) ptr->name, node_name))
74 // check if the attribute name and return the value
75 for (attr = ptr->properties; attr; attr = attr->next)
76 if (attr->children && attr->children->type == XML_TEXT_NODE) {
77 if (!strcmp((const char *) attr->name, attribute_name))
78 return (const char *) attr->children->content;
84 static int yaz_base64decode(const char *in, char *out)
86 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
87 "abcdefghijklmnopqrstuvwxyz0123456789+/";
96 if (!(p = strchr(map, in[0])))
100 if (!(p = strchr(map, in[1])))
104 *(out++) = i0 << 2 | i1 >> 4;
108 if (!(p = strchr(map, in[2])))
112 *(out++) = i1 << 4 | i2 >> 2;
116 if (!(p = strchr(map, in[3])))
120 *(out++) = i2 << 6 | i3;
131 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
133 const char *content_type = z_HTTP_header_lookup(hres->headers,
137 if (!yaz_strcmp_del("text/xml", content_type, "; "))
139 if (!yaz_strcmp_del("application/xml", content_type, "; "))
146 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
147 * 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;
163 char ubuf[256] = "", pbuf[256] = "", *p;
164 if (strncmp(basic, "Basic ", 6))
168 if (!len || len > 256)
170 olen = yaz_base64decode(basic, out);
171 /* Format of out should be username:password at this point */
173 if ((p = strchr(ubuf, ':'))) {
179 sr->username = odr_strdup(decode, ubuf);
181 sr->password = odr_strdup(decode, pbuf);
186 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
188 const char *v = yaz_uri_val(path, name, o);
190 *intp = odr_intdup(o, atoi(v));
193 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
194 const char *uri, const char *message,
197 d->uri = odr_strdup(o, uri);
199 d->message = odr_strdup(o, message);
203 d->details = odr_strdup(o, details);
208 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
209 int code, const char *details)
213 sprintf(uri, "info:srw/diagnostic/1/%d", code);
214 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
217 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
218 int *num, const char *uri,
219 const char *message, const char *details)
221 Z_SRW_diagnostic *d_new;
222 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
224 memcpy (d_new, *d, *num *sizeof(**d));
227 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
231 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
232 int *num, int code, const char *addinfo)
236 sprintf(uri, "info:srw/diagnostic/1/%d", code);
237 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
241 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
242 int *num, int code, const char *addinfo)
246 sprintf(uri, "info:srw/diagnostic/12/%d", code);
247 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
251 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
252 int code, const char *details)
254 const char *message = yaz_diag_srw_str(code);
257 len += strlen(message);
259 len += strlen(details);
261 record->recordData_buf = (char *) odr_malloc(o, len);
263 sprintf(record->recordData_buf, "<diagnostic "
264 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
265 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
267 sprintf(record->recordData_buf + strlen(record->recordData_buf),
268 " <details>%s</details>\n", details);
270 sprintf(record->recordData_buf + strlen(record->recordData_buf),
271 " <message>%s</message>\n", message);
272 sprintf(record->recordData_buf + strlen(record->recordData_buf),
274 record->recordData_len = strlen(record->recordData_buf);
275 record->recordPosition = odr_intdup(o, pos);
276 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
279 static void grab_charset(ODR o, const char *content_type, char **charset)
283 const char *charset_p = 0;
284 if (content_type && (charset_p = strstr(content_type, "; charset=")))
288 while (i < 20 && charset_p[i] &&
289 !strchr("; \n\r", charset_p[i]))
291 *charset = (char*) odr_malloc(o, i+1);
292 memcpy(*charset, charset_p, i);
293 (*charset)[i] = '\0';
298 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
299 Z_SOAP **soap_package, ODR decode, char **charset)
301 if (!strcmp(hreq->method, "POST"))
303 const char *content_type = z_HTTP_header_lookup(hreq->headers,
306 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
307 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
308 !yaz_strcmp_del("text/plain", content_type, "; ")))
310 char *db = "Default";
311 const char *p0 = hreq->path, *p1;
314 static Z_SOAP_Handler soap_handlers[4] = {
316 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
317 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
318 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
325 p1 = strchr(p0, '?');
327 p1 = p0 + strlen(p0);
329 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
330 grab_charset(decode, content_type, charset);
332 ret = z_soap_codec(decode, soap_package,
333 &hreq->content_buf, &hreq->content_len,
335 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
337 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
339 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
340 (*srw_pdu)->u.request->database == 0)
341 (*srw_pdu)->u.request->database = db;
343 if ((*srw_pdu)->which == Z_SRW_explain_request &&
344 (*srw_pdu)->u.explain_request->database == 0)
345 (*srw_pdu)->u.explain_request->database = db;
347 if ((*srw_pdu)->which == Z_SRW_scan_request &&
348 (*srw_pdu)->u.scan_request->database == 0)
349 (*srw_pdu)->u.scan_request->database = db;
351 if ((*srw_pdu)->which == Z_SRW_update_request &&
352 (*srw_pdu)->u.update_request->database == 0)
353 (*srw_pdu)->u.update_request->database = db;
364 static int yaz_sru_decode_integer(ODR odr, const char *pname,
365 const char *valstr, Odr_int **valp,
366 Z_SRW_diagnostic **diag, int *num_diag,
372 if (sscanf(valstr, "%d", &ival) != 1)
374 yaz_add_srw_diagnostic(odr, diag, num_diag,
375 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
378 if (min_value >= 0 && ival < min_value)
380 yaz_add_srw_diagnostic(odr, diag, num_diag,
381 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
384 *valp = odr_intdup(odr, ival);
390 http://www.loc.gov/z3950/agency/zing/srw/service.html
392 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
393 Z_SOAP **soap_package, ODR decode, char **charset,
394 Z_SRW_diagnostic **diag, int *num_diag)
397 static Z_SOAP_Handler soap_handlers[2] = {
398 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
402 const char *content_type = z_HTTP_header_lookup(hreq->headers,
406 SRU GET: ignore content type.
407 SRU POST: we support "application/x-www-form-urlencoded";
408 not "multipart/form-data" .
410 if (!strcmp(hreq->method, "GET")
412 (!strcmp(hreq->method, "POST") && content_type &&
413 !yaz_strcmp_del("application/x-www-form-urlencoded",
414 content_type, "; ")))
416 char *db = "Default";
417 const char *p0 = hreq->path, *p1;
419 const char *operation = 0;
426 char *stylesheet = 0;
427 char *scanClause = 0;
428 char *pScanClause = 0;
429 char *recordXPath = 0;
430 char *recordSchema = 0;
431 char *recordPacking = "xml"; /* xml packing is default for SRU */
432 char *maximumRecords = 0;
433 char *startRecord = 0;
434 char *maximumTerms = 0;
435 char *responsePosition = 0;
436 char *extraRequestData = 0;
437 Z_SRW_extra_arg *extra_args = 0;
442 grab_charset(decode, content_type, charset);
443 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
448 p1 = strchr(p0, '?');
450 p1 = p0 + strlen(p0);
452 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
453 if (!strcmp(hreq->method, "POST"))
454 p1 = hreq->content_buf;
455 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
460 for (i = 0; uri_name[i]; i++)
462 char *n = uri_name[i];
463 char *v = uri_val[i];
464 if (!strcmp(n, "query"))
466 else if (!strcmp(n, "x-pquery"))
468 else if (!strcmp(n, "x-username"))
470 else if (!strcmp(n, "x-password"))
472 else if (!strcmp(n, "operation"))
474 else if (!strcmp(n, "stylesheet"))
476 else if (!strcmp(n, "sortKeys"))
478 else if (!strcmp(n, "recordXPath"))
480 else if (!strcmp(n, "recordSchema"))
482 else if (!strcmp(n, "recordPacking"))
484 else if (!strcmp(n, "version"))
486 else if (!strcmp(n, "scanClause"))
488 else if (!strcmp(n, "x-pScanClause"))
490 else if (!strcmp(n, "maximumRecords"))
492 else if (!strcmp(n, "startRecord"))
494 else if (!strcmp(n, "maximumTerms"))
496 else if (!strcmp(n, "responsePosition"))
497 responsePosition = v;
498 else if (!strcmp(n, "extraRequestData"))
499 extraRequestData = v;
500 else if (n[0] == 'x' && n[1] == '-')
502 Z_SRW_extra_arg **l = &extra_args;
505 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
506 (*l)->name = odr_strdup(decode, n);
507 (*l)->value = odr_strdup(decode, v);
511 yaz_add_srw_diagnostic(decode, diag, num_diag,
512 YAZ_SRW_UNSUPP_PARAMETER, n);
518 yaz_add_srw_diagnostic(
519 decode, diag, num_diag,
520 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
524 version = yaz_negotiate_sru_version(version);
527 { /* negotiation failed. */
528 yaz_add_srw_diagnostic(decode, diag, num_diag,
529 YAZ_SRW_UNSUPP_VERSION, "1.2");
536 yaz_add_srw_diagnostic(
537 decode, diag, num_diag,
538 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
539 operation = "explain";
541 if (!strcmp(operation, "searchRetrieve"))
543 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
545 sr->srw_version = version;
546 sr->extra_args = extra_args;
548 yaz_srw_decodeauth(sr, hreq, username, password, decode);
551 sr->u.request->query_type = Z_SRW_query_type_cql;
552 sr->u.request->query.cql = query;
556 sr->u.request->query_type = Z_SRW_query_type_pqf;
557 sr->u.request->query.pqf = pQuery;
560 yaz_add_srw_diagnostic(
561 decode, diag, num_diag,
562 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
566 sr->u.request->sort_type = Z_SRW_sort_type_sort;
567 sr->u.request->sort.sortKeys = sortKeys;
569 sr->u.request->recordXPath = recordXPath;
570 sr->u.request->recordSchema = recordSchema;
571 sr->u.request->recordPacking = recordPacking;
572 sr->u.request->stylesheet = stylesheet;
574 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
575 &sr->u.request->maximumRecords,
578 yaz_sru_decode_integer(decode, "startRecord", startRecord,
579 &sr->u.request->startRecord,
582 sr->u.request->database = db;
584 (*soap_package) = (Z_SOAP *)
585 odr_malloc(decode, sizeof(**soap_package));
586 (*soap_package)->which = Z_SOAP_generic;
588 (*soap_package)->u.generic = (Z_SOAP_Generic *)
589 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
591 (*soap_package)->u.generic->p = sr;
592 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
593 (*soap_package)->u.generic->no = 0;
595 (*soap_package)->ns = "SRU";
599 else if (!strcmp(operation, "explain"))
601 /* Transfer SRU explain parameters to common struct */
602 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
603 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
605 sr->srw_version = version;
606 sr->extra_args = extra_args;
607 yaz_srw_decodeauth(sr, hreq, username, password, decode);
609 sr->u.explain_request->recordPacking = recordPacking;
610 sr->u.explain_request->database = db;
612 sr->u.explain_request->stylesheet = stylesheet;
614 (*soap_package) = (Z_SOAP *)
615 odr_malloc(decode, sizeof(**soap_package));
616 (*soap_package)->which = Z_SOAP_generic;
618 (*soap_package)->u.generic = (Z_SOAP_Generic *)
619 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
621 (*soap_package)->u.generic->p = sr;
622 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
623 (*soap_package)->u.generic->no = 0;
625 (*soap_package)->ns = "SRU";
629 else if (!strcmp(operation, "scan"))
631 /* Transfer SRU scan parameters to common struct */
632 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
633 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
635 sr->srw_version = version;
636 sr->extra_args = extra_args;
638 yaz_srw_decodeauth(sr, hreq, username, password, decode);
642 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
643 sr->u.scan_request->scanClause.cql = scanClause;
645 else if (pScanClause)
647 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
648 sr->u.scan_request->scanClause.pqf = pScanClause;
651 yaz_add_srw_diagnostic(
652 decode, diag, num_diag,
653 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
654 sr->u.scan_request->database = db;
656 yaz_sru_decode_integer(decode, "maximumTerms",
658 &sr->u.scan_request->maximumTerms,
661 yaz_sru_decode_integer(decode, "responsePosition",
663 &sr->u.scan_request->responsePosition,
666 sr->u.scan_request->stylesheet = stylesheet;
668 (*soap_package) = (Z_SOAP *)
669 odr_malloc(decode, sizeof(**soap_package));
670 (*soap_package)->which = Z_SOAP_generic;
672 (*soap_package)->u.generic = (Z_SOAP_Generic *)
673 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
675 (*soap_package)->u.generic->p = sr;
676 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
677 (*soap_package)->u.generic->no = 0;
679 (*soap_package)->ns = "SRU";
685 /* unsupported operation ... */
686 /* Act as if we received a explain request and throw diagnostic. */
688 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
690 sr->srw_version = version;
692 sr->u.explain_request->recordPacking = recordPacking;
693 sr->u.explain_request->database = db;
695 sr->u.explain_request->stylesheet = stylesheet;
697 (*soap_package) = (Z_SOAP *)
698 odr_malloc(decode, sizeof(**soap_package));
699 (*soap_package)->which = Z_SOAP_generic;
701 (*soap_package)->u.generic = (Z_SOAP_Generic *)
702 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
704 (*soap_package)->u.generic->p = sr;
705 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
706 (*soap_package)->u.generic->no = 0;
708 (*soap_package)->ns = "SRU";
710 yaz_add_srw_diagnostic(decode, diag, num_diag,
711 YAZ_SRW_UNSUPP_OPERATION, operation);
720 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
722 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
723 odr_malloc(o, sizeof(*res));
725 res->extraRecordData_buf = 0;
726 res->extraRecordData_len = 0;
727 res->recordIdentifier = 0;
732 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
734 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
737 for (i = 0; i<n; i++)
739 res[i].recordSchema = 0;
740 res[i].recordPacking = Z_SRW_recordPacking_string;
741 res[i].recordData_buf = 0;
742 res[i].recordData_len = 0;
743 res[i].recordPosition = 0;
748 Z_SRW_record *yaz_srw_get_record(ODR o)
750 return yaz_srw_get_records(o, 1);
753 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
755 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
756 p->srw_version = odr_strdup(o, version);
760 p->extraResponseData_buf = 0;
761 p->extraResponseData_len = 0;
765 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
767 return yaz_srw_get_core_ver(o, "1.1");
770 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
772 return yaz_srw_get_pdu(o, which, "1.1");
775 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
777 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
782 case Z_SRW_searchRetrieve_request:
783 sr->u.request = (Z_SRW_searchRetrieveRequest *)
784 odr_malloc(o, sizeof(*sr->u.request));
785 sr->u.request->query_type = Z_SRW_query_type_cql;
786 sr->u.request->query.cql = 0;
787 sr->u.request->sort_type = Z_SRW_sort_type_none;
788 sr->u.request->sort.none = 0;
789 sr->u.request->startRecord = 0;
790 sr->u.request->maximumRecords = 0;
791 sr->u.request->recordSchema = 0;
792 sr->u.request->recordPacking = 0;
793 sr->u.request->recordXPath = 0;
794 sr->u.request->database = 0;
795 sr->u.request->resultSetTTL = 0;
796 sr->u.request->stylesheet = 0;
797 sr->u.request->facetList = 0;
799 case Z_SRW_searchRetrieve_response:
800 sr->u.response = (Z_SRW_searchRetrieveResponse *)
801 odr_malloc(o, sizeof(*sr->u.response));
802 sr->u.response->numberOfRecords = 0;
803 sr->u.response->resultSetId = 0;
804 sr->u.response->resultSetIdleTime = 0;
805 sr->u.response->records = 0;
806 sr->u.response->num_records = 0;
807 sr->u.response->diagnostics = 0;
808 sr->u.response->num_diagnostics = 0;
809 sr->u.response->nextRecordPosition = 0;
810 sr->u.response->extra_records = 0;
811 sr->u.response->facetList = 0;
813 case Z_SRW_explain_request:
814 sr->u.explain_request = (Z_SRW_explainRequest *)
815 odr_malloc(o, sizeof(*sr->u.explain_request));
816 sr->u.explain_request->recordPacking = 0;
817 sr->u.explain_request->database = 0;
818 sr->u.explain_request->stylesheet = 0;
820 case Z_SRW_explain_response:
821 sr->u.explain_response = (Z_SRW_explainResponse *)
822 odr_malloc(o, sizeof(*sr->u.explain_response));
823 sr->u.explain_response->record.recordData_buf = 0;
824 sr->u.explain_response->record.recordData_len = 0;
825 sr->u.explain_response->record.recordSchema = 0;
826 sr->u.explain_response->record.recordPosition = 0;
827 sr->u.explain_response->record.recordPacking =
828 Z_SRW_recordPacking_string;
829 sr->u.explain_response->diagnostics = 0;
830 sr->u.explain_response->num_diagnostics = 0;
831 sr->u.explain_response->extra_record = 0;
833 case Z_SRW_scan_request:
834 sr->u.scan_request = (Z_SRW_scanRequest *)
835 odr_malloc(o, sizeof(*sr->u.scan_request));
836 sr->u.scan_request->database = 0;
837 sr->u.scan_request->stylesheet = 0;
838 sr->u.scan_request->maximumTerms = 0;
839 sr->u.scan_request->responsePosition = 0;
840 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
841 sr->u.scan_request->scanClause.cql = 0;
843 case Z_SRW_scan_response:
844 sr->u.scan_response = (Z_SRW_scanResponse *)
845 odr_malloc(o, sizeof(*sr->u.scan_response));
846 sr->u.scan_response->terms = 0;
847 sr->u.scan_response->num_terms = 0;
848 sr->u.scan_response->diagnostics = 0;
849 sr->u.scan_response->num_diagnostics = 0;
851 case Z_SRW_update_request:
852 sr->u.update_request = (Z_SRW_updateRequest *)
853 odr_malloc(o, sizeof(*sr->u.update_request));
854 sr->u.update_request->database = 0;
855 sr->u.update_request->stylesheet = 0;
856 sr->u.update_request->record = 0;
857 sr->u.update_request->recordId = 0;
858 sr->u.update_request->recordVersions = 0;
859 sr->u.update_request->num_recordVersions = 0;
860 sr->u.update_request->extra_record = 0;
861 sr->u.update_request->extraRequestData_buf = 0;
862 sr->u.update_request->extraRequestData_len = 0;
863 sr->u.request->database = 0;
865 case Z_SRW_update_response:
866 sr->u.update_response = (Z_SRW_updateResponse *)
867 odr_malloc(o, sizeof(*sr->u.update_response));
868 sr->u.update_response->operationStatus = 0;
869 sr->u.update_response->recordId = 0;
870 sr->u.update_response->recordVersions = 0;
871 sr->u.update_response->num_recordVersions = 0;
872 sr->u.update_response->record = 0;
873 sr->u.update_response->extra_record = 0;
874 sr->u.update_response->extraResponseData_buf = 0;
875 sr->u.update_response->extraResponseData_len = 0;
876 sr->u.update_response->diagnostics = 0;
877 sr->u.update_response->num_diagnostics = 0;
883 static int bib1_srw_map[] = {
893 108, 10, /* Malformed query : Syntax error */
923 100, 1, /* bad map */
971 205, 1, /* bad map */
972 206, 1, /* bad map */
974 208, 1, /* bad map */
985 218, 1, /* bad map */
986 219, 1, /* bad map */
987 220, 1, /* bad map */
988 221, 1, /* bad map */
990 223, 1, /* bad map */
991 224, 1, /* bad map */
992 225, 1, /* bad map */
993 226, 1, /* bad map */
995 228, 1, /* bad map */
1000 233, 1, /* bad map */
1001 234, 1, /* bad map */
1007 240, 1, /* bad map */
1008 241, 1, /* bad map */
1010 243, 1, /* bad map */
1015 1001, 1, /* bad map */
1016 1002, 1, /* bad map */
1017 1003, 1, /* bad map */
1018 1004, 1, /* bad map */
1019 1005, 1, /* bad map */
1020 1006, 1, /* bad map */
1053 * This array contains overrides for when the first occurrence of a
1054 * particular SRW error in the array above does not correspond with
1055 * the best back-translation of that SRW error.
1057 static int srw_bib1_map[] = {
1059 /* No doubt there are many more */
1064 int yaz_diag_bib1_to_srw (int code)
1066 const int *p = bib1_srw_map;
1076 int yaz_diag_srw_to_bib1(int code)
1078 /* Check explicit reverse-map first */
1079 const int *p = srw_bib1_map;
1087 /* Fall back on reverse lookup in main map */
1098 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1099 char *a_name, Odr_int *val)
1104 value[*i] = (char *) odr_malloc(o, 40);
1105 sprintf(value[*i], ODR_INT_PRINTF, *val);
1110 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1111 char *a_name, char *val)
1121 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1122 char **name, char **value, int max_names)
1125 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1126 name[i] = "operation";
1127 switch(srw_pdu->which)
1129 case Z_SRW_searchRetrieve_request:
1130 value[i++] = "searchRetrieve";
1131 switch(srw_pdu->u.request->query_type)
1133 case Z_SRW_query_type_cql:
1134 yaz_add_name_value_str(encode, name, value, &i, "query",
1135 srw_pdu->u.request->query.cql);
1137 case Z_SRW_query_type_pqf:
1138 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1139 srw_pdu->u.request->query.pqf);
1141 case Z_SRW_query_type_xcql:
1142 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1143 srw_pdu->u.request->query.xcql);
1146 switch(srw_pdu->u.request->sort_type)
1148 case Z_SRW_sort_type_none:
1150 case Z_SRW_sort_type_sort:
1151 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1152 srw_pdu->u.request->sort.sortKeys);
1155 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1156 srw_pdu->u.request->startRecord);
1157 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1158 srw_pdu->u.request->maximumRecords);
1159 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1160 srw_pdu->u.request->recordSchema);
1161 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1162 srw_pdu->u.request->recordPacking);
1163 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1164 srw_pdu->u.request->recordXPath);
1165 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1166 srw_pdu->u.request->stylesheet);
1167 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1168 srw_pdu->u.request->resultSetTTL);
1170 case Z_SRW_explain_request:
1171 value[i++] = "explain";
1172 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1173 srw_pdu->u.explain_request->stylesheet);
1175 case Z_SRW_scan_request:
1176 value[i++] = "scan";
1178 switch(srw_pdu->u.scan_request->query_type)
1180 case Z_SRW_query_type_cql:
1181 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1182 srw_pdu->u.scan_request->scanClause.cql);
1184 case Z_SRW_query_type_pqf:
1185 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1186 srw_pdu->u.scan_request->scanClause.pqf);
1188 case Z_SRW_query_type_xcql:
1189 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1190 srw_pdu->u.scan_request->scanClause.xcql);
1193 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1194 srw_pdu->u.scan_request->responsePosition);
1195 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1196 srw_pdu->u.scan_request->maximumTerms);
1197 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1198 srw_pdu->u.scan_request->stylesheet);
1200 case Z_SRW_update_request:
1201 value[i++] = "update";
1206 if (srw_pdu->extra_args)
1208 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1209 for (; ea && i < max_names-1; ea = ea->next)
1212 value[i] = ea->value;
1221 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1222 ODR encode, const char *charset)
1224 char *name[30], *value[30]; /* definite upper limit for SRU params */
1228 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1229 srw_pdu->username, srw_pdu->password);
1230 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1232 yaz_array_to_uri(&uri_args, encode, name, value);
1234 hreq->method = "GET";
1237 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1239 sprintf(path, "%s?%s", hreq->path, uri_args);
1240 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1243 z_HTTP_header_add_content_type(encode, &hreq->headers,
1244 "text/xml", charset);
1248 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1249 ODR encode, const char *charset)
1251 char *name[30], *value[30]; /* definite upper limit for SRU params */
1254 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1255 srw_pdu->username, srw_pdu->password);
1256 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1259 yaz_array_to_uri(&uri_args, encode, name, value);
1261 hreq->method = "POST";
1263 hreq->content_buf = uri_args;
1264 hreq->content_len = strlen(uri_args);
1266 z_HTTP_header_add_content_type(encode, &hreq->headers,
1267 "application/x-www-form-urlencoded",
1272 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1273 ODR odr, const char *charset)
1275 Z_SOAP_Handler handlers[3] = {
1277 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1278 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1282 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1284 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1285 srw_pdu->username, srw_pdu->password);
1286 z_HTTP_header_add_content_type(odr,
1288 "text/xml", charset);
1290 z_HTTP_header_add(odr, &hreq->headers,
1291 "SOAPAction", "\"\"");
1292 p->which = Z_SOAP_generic;
1293 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1294 p->u.generic->no = 0;
1295 p->u.generic->ns = 0;
1296 p->u.generic->p = srw_pdu;
1297 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1300 if (srw_pdu->which == Z_SRW_update_request ||
1301 srw_pdu->which == Z_SRW_update_response)
1302 p->u.generic->no = 1; /* second handler */
1304 return z_soap_codec_enc(odr, &p,
1306 &hreq->content_len, handlers,
1310 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1312 Z_SRW_recordVersion *ver
1313 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1315 for ( i=0; i < num; ++i ){
1316 ver[i].versionType = 0;
1317 ver[i].versionValue = 0;
1322 const char *yaz_srw_pack_to_str(int pack)
1326 case Z_SRW_recordPacking_string:
1328 case Z_SRW_recordPacking_XML:
1330 case Z_SRW_recordPacking_URL:
1336 int yaz_srw_str_to_pack(const char *str)
1338 if (!yaz_matchstr(str, "string"))
1339 return Z_SRW_recordPacking_string;
1340 if (!yaz_matchstr(str, "xml"))
1341 return Z_SRW_recordPacking_XML;
1342 if (!yaz_matchstr(str, "url"))
1343 return Z_SRW_recordPacking_URL;
1347 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1353 Z_SRW_extra_arg **ea = &sr->extra_args;
1354 yaz_uri_to_array(extra_args, odr, &name, &val);
1358 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1359 (*ea)->name = *name;
1360 (*ea)->value = *val;
1373 * c-file-style: "Stroustrup"
1374 * indent-tabs-mode: nil
1376 * vim: shiftwidth=4 tabstop=8 expandtab