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/base64.h>
18 #include <yaz/yaz-iconv.h>
21 #define MAX_SRU_PARAMETERS 30
23 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
25 return odr_strdupn(n, uri, len);
28 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
35 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
37 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
38 yaz_encode_sru_dbpath_buf(dst, db);
42 Z_AttributeList *yaz_use_attribute_create(ODR o, const char *name)
44 Z_AttributeList *attributes= (Z_AttributeList *)
45 odr_malloc(o, sizeof(*attributes));
46 Z_AttributeElement ** elements;
47 attributes->num_attributes = 1;
48 elements = (Z_AttributeElement**)
49 odr_malloc(o, attributes->num_attributes * sizeof(*elements));
50 elements[0] = (Z_AttributeElement*) odr_malloc(o,sizeof(**elements));
51 elements[0]->attributeType = odr_intdup(o, 1);
52 elements[0]->attributeSet = odr_nullval();
53 elements[0]->which = Z_AttributeValue_complex;
54 elements[0]->value.complex = (Z_ComplexAttribute *)
55 odr_malloc(o, sizeof(Z_ComplexAttribute));
56 elements[0]->value.complex->num_list = 1;
57 elements[0]->value.complex->list = (Z_StringOrNumeric **)
58 odr_malloc(o, 1 * sizeof(Z_StringOrNumeric *));
59 elements[0]->value.complex->list[0] = (Z_StringOrNumeric *)
60 odr_malloc(o, sizeof(Z_StringOrNumeric));
61 elements[0]->value.complex->list[0]->which = Z_StringOrNumeric_string;
62 elements[0]->value.complex->list[0]->u.string = odr_strdup(o, name);
63 elements[0]->value.complex->semanticAction = 0;
64 elements[0]->value.complex->num_semanticAction = 0;
65 attributes->attributes = elements;
70 const char *yaz_element_attribute_value_get(xmlNodePtr ptr,
71 const char *node_name,
72 const char *attribute_name)
74 struct _xmlAttr *attr;
75 // check if the node name matches
76 if (strcmp((const char*) ptr->name, node_name))
78 // check if the attribute name and return the value
79 for (attr = ptr->properties; attr; attr = attr->next)
80 if (attr->children && attr->children->type == XML_TEXT_NODE)
82 if (!strcmp((const char *) attr->name, attribute_name))
83 return (const char *) attr->children->content;
89 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
91 const char *content_type = z_HTTP_header_lookup(hres->headers,
95 if (!yaz_strcmp_del("text/xml", content_type, "; "))
97 if (!yaz_strcmp_del("application/xml", content_type, "; "))
104 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
105 * parameters. Added by SH.
107 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
108 char *username, char *password, ODR decode)
110 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
113 sr->username = username;
115 sr->password = password;
121 char ubuf[256] = "", pbuf[256] = "", *p;
122 if (strncmp(basic, "Basic ", 6))
126 if (!len || len > 256)
128 yaz_base64decode(basic, out);
129 /* Format of out should be username:password at this point */
131 if ((p = strchr(ubuf, ':')))
138 sr->username = odr_strdup(decode, ubuf);
140 sr->password = odr_strdup(decode, pbuf);
144 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
146 const char *v = yaz_uri_val(path, name, o);
148 *intp = odr_intdup(o, atoi(v));
151 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
152 const char *uri, const char *message,
155 d->uri = odr_strdup(o, uri);
157 d->message = odr_strdup(o, message);
161 d->details = odr_strdup(o, details);
166 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
167 int code, const char *details)
171 sprintf(uri, "info:srw/diagnostic/1/%d", code);
172 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
175 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
176 int *num, const char *uri,
177 const char *message, const char *details)
179 Z_SRW_diagnostic *d_new;
180 d_new = (Z_SRW_diagnostic *) odr_malloc(o, (*num + 1)* sizeof(**d));
182 memcpy(d_new, *d, *num *sizeof(**d));
185 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
189 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
190 int *num, int code, const char *addinfo)
194 sprintf(uri, "info:srw/diagnostic/1/%d", code);
195 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
199 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
200 int *num, int code, const char *addinfo)
204 sprintf(uri, "info:srw/diagnostic/12/%d", code);
205 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
209 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
210 int code, const char *details)
212 const char *message = yaz_diag_srw_str(code);
215 len += strlen(message);
217 len += strlen(details);
219 record->recordData_buf = (char *) odr_malloc(o, len);
221 sprintf(record->recordData_buf, "<diagnostic "
222 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
223 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
225 sprintf(record->recordData_buf + strlen(record->recordData_buf),
226 " <details>%s</details>\n", details);
228 sprintf(record->recordData_buf + strlen(record->recordData_buf),
229 " <message>%s</message>\n", message);
230 sprintf(record->recordData_buf + strlen(record->recordData_buf),
232 record->recordData_len = strlen(record->recordData_buf);
233 record->recordPosition = odr_intdup(o, pos);
234 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
237 static void grab_charset(ODR o, const char *content_type, char **charset)
241 const char *charset_p = 0;
242 if (content_type && (charset_p = strstr(content_type, "; charset=")))
246 while (i < 20 && charset_p[i] &&
247 !strchr("; \n\r", charset_p[i]))
249 *charset = (char*) odr_malloc(o, i+1);
250 memcpy(*charset, charset_p, i);
251 (*charset)[i] = '\0';
256 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
257 Z_SOAP **soap_package, ODR decode, char **charset)
259 if (!strcmp(hreq->method, "POST"))
261 const char *content_type = z_HTTP_header_lookup(hreq->headers,
264 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
265 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
266 !yaz_strcmp_del("text/plain", content_type, "; ")))
268 char *db = "Default";
269 const char *p0 = hreq->path, *p1;
272 static Z_SOAP_Handler soap_handlers[4] = {
274 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
275 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
276 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
283 p1 = strchr(p0, '?');
285 p1 = p0 + strlen(p0);
287 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
288 grab_charset(decode, content_type, charset);
290 ret = z_soap_codec(decode, soap_package,
291 &hreq->content_buf, &hreq->content_len,
293 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
295 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
296 yaz_srw_decodeauth(*srw_pdu, hreq, 0, 0, decode);
298 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
299 (*srw_pdu)->u.request->database == 0)
300 (*srw_pdu)->u.request->database = db;
302 if ((*srw_pdu)->which == Z_SRW_explain_request &&
303 (*srw_pdu)->u.explain_request->database == 0)
304 (*srw_pdu)->u.explain_request->database = db;
306 if ((*srw_pdu)->which == Z_SRW_scan_request &&
307 (*srw_pdu)->u.scan_request->database == 0)
308 (*srw_pdu)->u.scan_request->database = db;
310 if ((*srw_pdu)->which == Z_SRW_update_request &&
311 (*srw_pdu)->u.update_request->database == 0)
312 (*srw_pdu)->u.update_request->database = db;
323 static int yaz_sru_decode_integer(ODR odr, const char *pname,
324 const char *valstr, Odr_int **valp,
325 Z_SRW_diagnostic **diag, int *num_diag,
331 if (sscanf(valstr, "%d", &ival) != 1)
333 yaz_add_srw_diagnostic(odr, diag, num_diag,
334 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
337 if (min_value >= 0 && ival < min_value)
339 yaz_add_srw_diagnostic(odr, diag, num_diag,
340 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
343 *valp = odr_intdup(odr, ival);
349 http://www.loc.gov/z3950/agency/zing/srw/service.html
351 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
352 Z_SOAP **soap_package, ODR decode, char **charset,
353 Z_SRW_diagnostic **diag, int *num_diag)
356 static Z_SOAP_Handler soap_handlers[2] = {
357 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
361 const char *content_type = z_HTTP_header_lookup(hreq->headers,
365 SRU GET: ignore content type.
366 SRU POST: we support "application/x-www-form-urlencoded";
367 not "multipart/form-data" .
369 if (!strcmp(hreq->method, "GET")
371 (!strcmp(hreq->method, "POST") && content_type &&
372 !yaz_strcmp_del("application/x-www-form-urlencoded",
373 content_type, "; ")))
375 char *db = "Default";
376 const char *p0 = hreq->path, *p1;
378 const char *operation = 0;
385 char *stylesheet = 0;
386 char *scanClause = 0;
387 char *pScanClause = 0;
388 char *recordXPath = 0;
389 char *recordSchema = 0;
390 char *recordPacking = "xml"; /* xml packing is default for SRU */
391 char *maximumRecords = 0;
392 char *startRecord = 0;
393 char *maximumTerms = 0;
394 char *responsePosition = 0;
395 Z_SRW_extra_arg *extra_args = 0;
400 grab_charset(decode, content_type, charset);
401 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
406 p1 = strchr(p0, '?');
408 p1 = p0 + strlen(p0);
410 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
411 if (!strcmp(hreq->method, "POST"))
412 p1 = hreq->content_buf;
413 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
418 for (i = 0; uri_name[i]; i++)
420 char *n = uri_name[i];
421 char *v = uri_val[i];
422 if (!strcmp(n, "query"))
424 else if (!strcmp(n, "x-pquery"))
426 else if (!strcmp(n, "x-username"))
428 else if (!strcmp(n, "x-password"))
430 else if (!strcmp(n, "operation"))
432 else if (!strcmp(n, "stylesheet"))
434 else if (!strcmp(n, "sortKeys"))
436 else if (!strcmp(n, "recordXPath"))
438 else if (!strcmp(n, "recordSchema"))
440 else if (!strcmp(n, "recordPacking"))
442 else if (!strcmp(n, "version"))
444 else if (!strcmp(n, "scanClause"))
446 else if (!strcmp(n, "x-pScanClause"))
448 else if (!strcmp(n, "maximumRecords"))
450 else if (!strcmp(n, "startRecord"))
452 else if (!strcmp(n, "maximumTerms"))
454 else if (!strcmp(n, "responsePosition"))
455 responsePosition = v;
456 else if (!strcmp(n, "extraRequestData"))
457 ; /* ignoring extraRequestData */
458 else if (n[0] == 'x' && n[1] == '-')
460 Z_SRW_extra_arg **l = &extra_args;
463 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
464 (*l)->name = odr_strdup(decode, n);
465 (*l)->value = odr_strdup(decode, v);
469 yaz_add_srw_diagnostic(decode, diag, num_diag,
470 YAZ_SRW_UNSUPP_PARAMETER, n);
476 yaz_add_srw_diagnostic(
477 decode, diag, num_diag,
478 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
482 version = yaz_negotiate_sru_version(version);
485 { /* negotiation failed. */
486 yaz_add_srw_diagnostic(decode, diag, num_diag,
487 YAZ_SRW_UNSUPP_VERSION, "1.2");
494 yaz_add_srw_diagnostic(
495 decode, diag, num_diag,
496 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
497 operation = "explain";
499 if (!strcmp(operation, "searchRetrieve"))
501 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
503 sr->srw_version = version;
504 sr->extra_args = extra_args;
506 yaz_srw_decodeauth(sr, hreq, username, password, decode);
509 sr->u.request->query_type = Z_SRW_query_type_cql;
510 sr->u.request->query.cql = query;
514 sr->u.request->query_type = Z_SRW_query_type_pqf;
515 sr->u.request->query.pqf = pQuery;
518 yaz_add_srw_diagnostic(
519 decode, diag, num_diag,
520 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
524 sr->u.request->sort_type = Z_SRW_sort_type_sort;
525 sr->u.request->sort.sortKeys = sortKeys;
527 sr->u.request->recordXPath = recordXPath;
528 sr->u.request->recordSchema = recordSchema;
529 sr->u.request->recordPacking = recordPacking;
530 sr->u.request->stylesheet = stylesheet;
532 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
533 &sr->u.request->maximumRecords,
536 yaz_sru_decode_integer(decode, "startRecord", startRecord,
537 &sr->u.request->startRecord,
540 sr->u.request->database = db;
542 (*soap_package) = (Z_SOAP *)
543 odr_malloc(decode, sizeof(**soap_package));
544 (*soap_package)->which = Z_SOAP_generic;
546 (*soap_package)->u.generic = (Z_SOAP_Generic *)
547 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
549 (*soap_package)->u.generic->p = sr;
550 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
551 (*soap_package)->u.generic->no = 0;
553 (*soap_package)->ns = "SRU";
557 else if (!strcmp(operation, "explain"))
559 /* Transfer SRU explain parameters to common struct */
560 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
561 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
563 sr->srw_version = version;
564 sr->extra_args = extra_args;
565 yaz_srw_decodeauth(sr, hreq, username, password, decode);
567 sr->u.explain_request->recordPacking = recordPacking;
568 sr->u.explain_request->database = db;
570 sr->u.explain_request->stylesheet = stylesheet;
572 (*soap_package) = (Z_SOAP *)
573 odr_malloc(decode, sizeof(**soap_package));
574 (*soap_package)->which = Z_SOAP_generic;
576 (*soap_package)->u.generic = (Z_SOAP_Generic *)
577 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
579 (*soap_package)->u.generic->p = sr;
580 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
581 (*soap_package)->u.generic->no = 0;
583 (*soap_package)->ns = "SRU";
587 else if (!strcmp(operation, "scan"))
589 /* Transfer SRU scan parameters to common struct */
590 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
591 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
593 sr->srw_version = version;
594 sr->extra_args = extra_args;
596 yaz_srw_decodeauth(sr, hreq, username, password, decode);
600 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
601 sr->u.scan_request->scanClause.cql = scanClause;
603 else if (pScanClause)
605 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
606 sr->u.scan_request->scanClause.pqf = pScanClause;
609 yaz_add_srw_diagnostic(
610 decode, diag, num_diag,
611 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
612 sr->u.scan_request->database = db;
614 yaz_sru_decode_integer(decode, "maximumTerms",
616 &sr->u.scan_request->maximumTerms,
619 yaz_sru_decode_integer(decode, "responsePosition",
621 &sr->u.scan_request->responsePosition,
624 sr->u.scan_request->stylesheet = stylesheet;
626 (*soap_package) = (Z_SOAP *)
627 odr_malloc(decode, sizeof(**soap_package));
628 (*soap_package)->which = Z_SOAP_generic;
630 (*soap_package)->u.generic = (Z_SOAP_Generic *)
631 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
633 (*soap_package)->u.generic->p = sr;
634 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
635 (*soap_package)->u.generic->no = 0;
637 (*soap_package)->ns = "SRU";
643 /* unsupported operation ... */
644 /* Act as if we received a explain request and throw diagnostic. */
646 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
648 sr->srw_version = version;
650 sr->u.explain_request->recordPacking = recordPacking;
651 sr->u.explain_request->database = db;
653 sr->u.explain_request->stylesheet = stylesheet;
655 (*soap_package) = (Z_SOAP *)
656 odr_malloc(decode, sizeof(**soap_package));
657 (*soap_package)->which = Z_SOAP_generic;
659 (*soap_package)->u.generic = (Z_SOAP_Generic *)
660 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
662 (*soap_package)->u.generic->p = sr;
663 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
664 (*soap_package)->u.generic->no = 0;
666 (*soap_package)->ns = "SRU";
668 yaz_add_srw_diagnostic(decode, diag, num_diag,
669 YAZ_SRW_UNSUPP_OPERATION, operation);
678 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
680 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
681 odr_malloc(o, sizeof(*res));
683 res->extraRecordData_buf = 0;
684 res->extraRecordData_len = 0;
685 res->recordIdentifier = 0;
690 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
692 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
695 for (i = 0; i<n; i++)
697 res[i].recordSchema = 0;
698 res[i].recordPacking = Z_SRW_recordPacking_string;
699 res[i].recordData_buf = 0;
700 res[i].recordData_len = 0;
701 res[i].recordPosition = 0;
706 Z_SRW_record *yaz_srw_get_record(ODR o)
708 return yaz_srw_get_records(o, 1);
711 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
713 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
714 p->srw_version = odr_strdup(o, version);
718 p->extraResponseData_buf = 0;
719 p->extraResponseData_len = 0;
723 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
725 return yaz_srw_get_core_ver(o, "1.1");
728 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
730 return yaz_srw_get_pdu(o, which, "1.1");
733 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
735 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
740 case Z_SRW_searchRetrieve_request:
741 sr->u.request = (Z_SRW_searchRetrieveRequest *)
742 odr_malloc(o, sizeof(*sr->u.request));
743 sr->u.request->query_type = Z_SRW_query_type_cql;
744 sr->u.request->query.cql = 0;
745 sr->u.request->sort_type = Z_SRW_sort_type_none;
746 sr->u.request->sort.none = 0;
747 sr->u.request->startRecord = 0;
748 sr->u.request->maximumRecords = 0;
749 sr->u.request->recordSchema = 0;
750 sr->u.request->recordPacking = 0;
751 sr->u.request->recordXPath = 0;
752 sr->u.request->database = 0;
753 sr->u.request->resultSetTTL = 0;
754 sr->u.request->stylesheet = 0;
755 sr->u.request->facetList = 0;
757 case Z_SRW_searchRetrieve_response:
758 sr->u.response = (Z_SRW_searchRetrieveResponse *)
759 odr_malloc(o, sizeof(*sr->u.response));
760 sr->u.response->numberOfRecords = 0;
761 sr->u.response->resultSetId = 0;
762 sr->u.response->resultSetIdleTime = 0;
763 sr->u.response->records = 0;
764 sr->u.response->num_records = 0;
765 sr->u.response->diagnostics = 0;
766 sr->u.response->num_diagnostics = 0;
767 sr->u.response->nextRecordPosition = 0;
768 sr->u.response->extra_records = 0;
769 sr->u.response->facetList = 0;
770 sr->u.response->suggestions = 0;
772 case Z_SRW_explain_request:
773 sr->u.explain_request = (Z_SRW_explainRequest *)
774 odr_malloc(o, sizeof(*sr->u.explain_request));
775 sr->u.explain_request->recordPacking = 0;
776 sr->u.explain_request->database = 0;
777 sr->u.explain_request->stylesheet = 0;
779 case Z_SRW_explain_response:
780 sr->u.explain_response = (Z_SRW_explainResponse *)
781 odr_malloc(o, sizeof(*sr->u.explain_response));
782 sr->u.explain_response->record.recordData_buf = 0;
783 sr->u.explain_response->record.recordData_len = 0;
784 sr->u.explain_response->record.recordSchema = 0;
785 sr->u.explain_response->record.recordPosition = 0;
786 sr->u.explain_response->record.recordPacking =
787 Z_SRW_recordPacking_string;
788 sr->u.explain_response->diagnostics = 0;
789 sr->u.explain_response->num_diagnostics = 0;
790 sr->u.explain_response->extra_record = 0;
792 case Z_SRW_scan_request:
793 sr->u.scan_request = (Z_SRW_scanRequest *)
794 odr_malloc(o, sizeof(*sr->u.scan_request));
795 sr->u.scan_request->database = 0;
796 sr->u.scan_request->stylesheet = 0;
797 sr->u.scan_request->maximumTerms = 0;
798 sr->u.scan_request->responsePosition = 0;
799 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
800 sr->u.scan_request->scanClause.cql = 0;
802 case Z_SRW_scan_response:
803 sr->u.scan_response = (Z_SRW_scanResponse *)
804 odr_malloc(o, sizeof(*sr->u.scan_response));
805 sr->u.scan_response->terms = 0;
806 sr->u.scan_response->num_terms = 0;
807 sr->u.scan_response->diagnostics = 0;
808 sr->u.scan_response->num_diagnostics = 0;
810 case Z_SRW_update_request:
811 sr->u.update_request = (Z_SRW_updateRequest *)
812 odr_malloc(o, sizeof(*sr->u.update_request));
813 sr->u.update_request->database = 0;
814 sr->u.update_request->stylesheet = 0;
815 sr->u.update_request->record = 0;
816 sr->u.update_request->recordId = 0;
817 sr->u.update_request->recordVersions = 0;
818 sr->u.update_request->num_recordVersions = 0;
819 sr->u.update_request->extra_record = 0;
820 sr->u.update_request->extraRequestData_buf = 0;
821 sr->u.update_request->extraRequestData_len = 0;
822 sr->u.request->database = 0;
824 case Z_SRW_update_response:
825 sr->u.update_response = (Z_SRW_updateResponse *)
826 odr_malloc(o, sizeof(*sr->u.update_response));
827 sr->u.update_response->operationStatus = 0;
828 sr->u.update_response->recordId = 0;
829 sr->u.update_response->recordVersions = 0;
830 sr->u.update_response->num_recordVersions = 0;
831 sr->u.update_response->record = 0;
832 sr->u.update_response->extra_record = 0;
833 sr->u.update_response->extraResponseData_buf = 0;
834 sr->u.update_response->extraResponseData_len = 0;
835 sr->u.update_response->diagnostics = 0;
836 sr->u.update_response->num_diagnostics = 0;
842 static int bib1_srw_map[] = {
852 108, 10, /* Malformed query : Syntax error */
882 100, 1, /* bad map */
930 205, 1, /* bad map */
931 206, 1, /* bad map */
933 208, 1, /* bad map */
944 218, 1, /* bad map */
945 219, 1, /* bad map */
946 220, 1, /* bad map */
947 221, 1, /* bad map */
949 223, 1, /* bad map */
950 224, 1, /* bad map */
951 225, 1, /* bad map */
952 226, 1, /* bad map */
954 228, 1, /* bad map */
959 233, 1, /* bad map */
960 234, 1, /* bad map */
966 240, 1, /* bad map */
967 241, 1, /* bad map */
969 243, 1, /* bad map */
974 1001, 1, /* bad map */
975 1002, 1, /* bad map */
976 1003, 1, /* bad map */
977 1004, 1, /* bad map */
978 1005, 1, /* bad map */
979 1006, 1, /* bad map */
1012 * This array contains overrides for when the first occurrence of a
1013 * particular SRW error in the array above does not correspond with
1014 * the best back-translation of that SRW error.
1016 static int srw_bib1_map[] = {
1018 /* No doubt there are many more */
1023 int yaz_diag_bib1_to_srw (int code)
1025 const int *p = bib1_srw_map;
1035 int yaz_diag_srw_to_bib1(int code)
1037 /* Check explicit reverse-map first */
1038 const int *p = srw_bib1_map;
1046 /* Fall back on reverse lookup in main map */
1057 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1058 char *a_name, Odr_int *val)
1063 value[*i] = (char *) odr_malloc(o, 40);
1064 sprintf(value[*i], ODR_INT_PRINTF, *val);
1069 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1070 char *a_name, char *val)
1080 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1081 char **name, char **value, int max_names)
1084 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1085 name[i] = "operation";
1086 switch(srw_pdu->which)
1088 case Z_SRW_searchRetrieve_request:
1089 value[i++] = "searchRetrieve";
1090 switch(srw_pdu->u.request->query_type)
1092 case Z_SRW_query_type_cql:
1093 yaz_add_name_value_str(encode, name, value, &i, "query",
1094 srw_pdu->u.request->query.cql);
1096 case Z_SRW_query_type_pqf:
1097 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1098 srw_pdu->u.request->query.pqf);
1100 case Z_SRW_query_type_xcql:
1101 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1102 srw_pdu->u.request->query.xcql);
1105 switch(srw_pdu->u.request->sort_type)
1107 case Z_SRW_sort_type_none:
1109 case Z_SRW_sort_type_sort:
1110 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1111 srw_pdu->u.request->sort.sortKeys);
1114 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1115 srw_pdu->u.request->startRecord);
1116 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1117 srw_pdu->u.request->maximumRecords);
1118 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1119 srw_pdu->u.request->recordSchema);
1120 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1121 srw_pdu->u.request->recordPacking);
1122 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1123 srw_pdu->u.request->recordXPath);
1124 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1125 srw_pdu->u.request->stylesheet);
1126 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1127 srw_pdu->u.request->resultSetTTL);
1129 case Z_SRW_explain_request:
1130 value[i++] = "explain";
1131 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1132 srw_pdu->u.explain_request->stylesheet);
1134 case Z_SRW_scan_request:
1135 value[i++] = "scan";
1137 switch(srw_pdu->u.scan_request->query_type)
1139 case Z_SRW_query_type_cql:
1140 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1141 srw_pdu->u.scan_request->scanClause.cql);
1143 case Z_SRW_query_type_pqf:
1144 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1145 srw_pdu->u.scan_request->scanClause.pqf);
1147 case Z_SRW_query_type_xcql:
1148 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1149 srw_pdu->u.scan_request->scanClause.xcql);
1152 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1153 srw_pdu->u.scan_request->responsePosition);
1154 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1155 srw_pdu->u.scan_request->maximumTerms);
1156 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1157 srw_pdu->u.scan_request->stylesheet);
1159 case Z_SRW_update_request:
1160 value[i++] = "update";
1165 if (srw_pdu->extra_args)
1167 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1168 for (; ea && i < max_names-1; ea = ea->next)
1171 value[i] = ea->value;
1180 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1181 ODR encode, const char *charset)
1183 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1187 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1188 srw_pdu->username, srw_pdu->password);
1189 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1191 yaz_array_to_uri(&uri_args, encode, name, value);
1193 hreq->method = "GET";
1196 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1198 sprintf(path, "%s?%s", hreq->path, uri_args);
1199 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1202 z_HTTP_header_add_content_type(encode, &hreq->headers,
1203 "text/xml", charset);
1207 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1208 ODR encode, const char *charset)
1210 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1213 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1214 srw_pdu->username, srw_pdu->password);
1215 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1218 yaz_array_to_uri(&uri_args, encode, name, value);
1220 hreq->method = "POST";
1222 hreq->content_buf = uri_args;
1223 hreq->content_len = strlen(uri_args);
1225 z_HTTP_header_add_content_type(encode, &hreq->headers,
1226 "application/x-www-form-urlencoded",
1231 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1232 ODR odr, const char *charset)
1234 Z_SOAP_Handler handlers[3] = {
1236 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1237 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1241 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1243 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1244 srw_pdu->username, srw_pdu->password);
1245 z_HTTP_header_add_content_type(odr,
1247 "text/xml", charset);
1249 z_HTTP_header_add(odr, &hreq->headers,
1250 "SOAPAction", "\"\"");
1251 p->which = Z_SOAP_generic;
1252 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1253 p->u.generic->no = 0;
1254 p->u.generic->ns = 0;
1255 p->u.generic->p = srw_pdu;
1256 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1259 if (srw_pdu->which == Z_SRW_update_request ||
1260 srw_pdu->which == Z_SRW_update_response)
1261 p->u.generic->no = 1; /* second handler */
1263 return z_soap_codec_enc(odr, &p,
1265 &hreq->content_len, handlers,
1269 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1271 Z_SRW_recordVersion *ver
1272 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1274 for (i = 0; i < num; ++i)
1276 ver[i].versionType = 0;
1277 ver[i].versionValue = 0;
1282 const char *yaz_srw_pack_to_str(int pack)
1286 case Z_SRW_recordPacking_string:
1288 case Z_SRW_recordPacking_XML:
1290 case Z_SRW_recordPacking_URL:
1296 int yaz_srw_str_to_pack(const char *str)
1298 if (!yaz_matchstr(str, "string"))
1299 return Z_SRW_recordPacking_string;
1300 if (!yaz_matchstr(str, "xml"))
1301 return Z_SRW_recordPacking_XML;
1302 if (!yaz_matchstr(str, "url"))
1303 return Z_SRW_recordPacking_URL;
1307 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1313 Z_SRW_extra_arg **ea = &sr->extra_args;
1314 yaz_uri_to_array(extra_args, odr, &name, &val);
1318 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1319 (*ea)->name = *name;
1320 (*ea)->value = *val;
1333 * c-file-style: "Stroustrup"
1334 * indent-tabs-mode: nil
1336 * vim: shiftwidth=4 tabstop=8 expandtab