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;
771 case Z_SRW_explain_request:
772 sr->u.explain_request = (Z_SRW_explainRequest *)
773 odr_malloc(o, sizeof(*sr->u.explain_request));
774 sr->u.explain_request->recordPacking = 0;
775 sr->u.explain_request->database = 0;
776 sr->u.explain_request->stylesheet = 0;
778 case Z_SRW_explain_response:
779 sr->u.explain_response = (Z_SRW_explainResponse *)
780 odr_malloc(o, sizeof(*sr->u.explain_response));
781 sr->u.explain_response->record.recordData_buf = 0;
782 sr->u.explain_response->record.recordData_len = 0;
783 sr->u.explain_response->record.recordSchema = 0;
784 sr->u.explain_response->record.recordPosition = 0;
785 sr->u.explain_response->record.recordPacking =
786 Z_SRW_recordPacking_string;
787 sr->u.explain_response->diagnostics = 0;
788 sr->u.explain_response->num_diagnostics = 0;
789 sr->u.explain_response->extra_record = 0;
791 case Z_SRW_scan_request:
792 sr->u.scan_request = (Z_SRW_scanRequest *)
793 odr_malloc(o, sizeof(*sr->u.scan_request));
794 sr->u.scan_request->database = 0;
795 sr->u.scan_request->stylesheet = 0;
796 sr->u.scan_request->maximumTerms = 0;
797 sr->u.scan_request->responsePosition = 0;
798 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
799 sr->u.scan_request->scanClause.cql = 0;
801 case Z_SRW_scan_response:
802 sr->u.scan_response = (Z_SRW_scanResponse *)
803 odr_malloc(o, sizeof(*sr->u.scan_response));
804 sr->u.scan_response->terms = 0;
805 sr->u.scan_response->num_terms = 0;
806 sr->u.scan_response->diagnostics = 0;
807 sr->u.scan_response->num_diagnostics = 0;
809 case Z_SRW_update_request:
810 sr->u.update_request = (Z_SRW_updateRequest *)
811 odr_malloc(o, sizeof(*sr->u.update_request));
812 sr->u.update_request->database = 0;
813 sr->u.update_request->stylesheet = 0;
814 sr->u.update_request->record = 0;
815 sr->u.update_request->recordId = 0;
816 sr->u.update_request->recordVersions = 0;
817 sr->u.update_request->num_recordVersions = 0;
818 sr->u.update_request->extra_record = 0;
819 sr->u.update_request->extraRequestData_buf = 0;
820 sr->u.update_request->extraRequestData_len = 0;
821 sr->u.request->database = 0;
823 case Z_SRW_update_response:
824 sr->u.update_response = (Z_SRW_updateResponse *)
825 odr_malloc(o, sizeof(*sr->u.update_response));
826 sr->u.update_response->operationStatus = 0;
827 sr->u.update_response->recordId = 0;
828 sr->u.update_response->recordVersions = 0;
829 sr->u.update_response->num_recordVersions = 0;
830 sr->u.update_response->record = 0;
831 sr->u.update_response->extra_record = 0;
832 sr->u.update_response->extraResponseData_buf = 0;
833 sr->u.update_response->extraResponseData_len = 0;
834 sr->u.update_response->diagnostics = 0;
835 sr->u.update_response->num_diagnostics = 0;
841 static int bib1_srw_map[] = {
851 108, 10, /* Malformed query : Syntax error */
881 100, 1, /* bad map */
929 205, 1, /* bad map */
930 206, 1, /* bad map */
932 208, 1, /* bad map */
943 218, 1, /* bad map */
944 219, 1, /* bad map */
945 220, 1, /* bad map */
946 221, 1, /* bad map */
948 223, 1, /* bad map */
949 224, 1, /* bad map */
950 225, 1, /* bad map */
951 226, 1, /* bad map */
953 228, 1, /* bad map */
958 233, 1, /* bad map */
959 234, 1, /* bad map */
965 240, 1, /* bad map */
966 241, 1, /* bad map */
968 243, 1, /* bad map */
973 1001, 1, /* bad map */
974 1002, 1, /* bad map */
975 1003, 1, /* bad map */
976 1004, 1, /* bad map */
977 1005, 1, /* bad map */
978 1006, 1, /* bad map */
1011 * This array contains overrides for when the first occurrence of a
1012 * particular SRW error in the array above does not correspond with
1013 * the best back-translation of that SRW error.
1015 static int srw_bib1_map[] = {
1017 /* No doubt there are many more */
1022 int yaz_diag_bib1_to_srw (int code)
1024 const int *p = bib1_srw_map;
1034 int yaz_diag_srw_to_bib1(int code)
1036 /* Check explicit reverse-map first */
1037 const int *p = srw_bib1_map;
1045 /* Fall back on reverse lookup in main map */
1056 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1057 char *a_name, Odr_int *val)
1062 value[*i] = (char *) odr_malloc(o, 40);
1063 sprintf(value[*i], ODR_INT_PRINTF, *val);
1068 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1069 char *a_name, char *val)
1079 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1080 char **name, char **value, int max_names)
1083 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1084 name[i] = "operation";
1085 switch(srw_pdu->which)
1087 case Z_SRW_searchRetrieve_request:
1088 value[i++] = "searchRetrieve";
1089 switch(srw_pdu->u.request->query_type)
1091 case Z_SRW_query_type_cql:
1092 yaz_add_name_value_str(encode, name, value, &i, "query",
1093 srw_pdu->u.request->query.cql);
1095 case Z_SRW_query_type_pqf:
1096 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1097 srw_pdu->u.request->query.pqf);
1099 case Z_SRW_query_type_xcql:
1100 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1101 srw_pdu->u.request->query.xcql);
1104 switch(srw_pdu->u.request->sort_type)
1106 case Z_SRW_sort_type_none:
1108 case Z_SRW_sort_type_sort:
1109 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1110 srw_pdu->u.request->sort.sortKeys);
1113 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1114 srw_pdu->u.request->startRecord);
1115 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1116 srw_pdu->u.request->maximumRecords);
1117 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1118 srw_pdu->u.request->recordSchema);
1119 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1120 srw_pdu->u.request->recordPacking);
1121 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1122 srw_pdu->u.request->recordXPath);
1123 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1124 srw_pdu->u.request->stylesheet);
1125 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1126 srw_pdu->u.request->resultSetTTL);
1128 case Z_SRW_explain_request:
1129 value[i++] = "explain";
1130 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1131 srw_pdu->u.explain_request->stylesheet);
1133 case Z_SRW_scan_request:
1134 value[i++] = "scan";
1136 switch(srw_pdu->u.scan_request->query_type)
1138 case Z_SRW_query_type_cql:
1139 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1140 srw_pdu->u.scan_request->scanClause.cql);
1142 case Z_SRW_query_type_pqf:
1143 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1144 srw_pdu->u.scan_request->scanClause.pqf);
1146 case Z_SRW_query_type_xcql:
1147 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1148 srw_pdu->u.scan_request->scanClause.xcql);
1151 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1152 srw_pdu->u.scan_request->responsePosition);
1153 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1154 srw_pdu->u.scan_request->maximumTerms);
1155 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1156 srw_pdu->u.scan_request->stylesheet);
1158 case Z_SRW_update_request:
1159 value[i++] = "update";
1164 if (srw_pdu->extra_args)
1166 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1167 for (; ea && i < max_names-1; ea = ea->next)
1170 value[i] = ea->value;
1179 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1180 ODR encode, const char *charset)
1182 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1186 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1187 srw_pdu->username, srw_pdu->password);
1188 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1190 yaz_array_to_uri(&uri_args, encode, name, value);
1192 hreq->method = "GET";
1195 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1197 sprintf(path, "%s?%s", hreq->path, uri_args);
1198 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1201 z_HTTP_header_add_content_type(encode, &hreq->headers,
1202 "text/xml", charset);
1206 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1207 ODR encode, const char *charset)
1209 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1212 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1213 srw_pdu->username, srw_pdu->password);
1214 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1217 yaz_array_to_uri(&uri_args, encode, name, value);
1219 hreq->method = "POST";
1221 hreq->content_buf = uri_args;
1222 hreq->content_len = strlen(uri_args);
1224 z_HTTP_header_add_content_type(encode, &hreq->headers,
1225 "application/x-www-form-urlencoded",
1230 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1231 ODR odr, const char *charset)
1233 Z_SOAP_Handler handlers[3] = {
1235 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1236 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1240 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1242 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1243 srw_pdu->username, srw_pdu->password);
1244 z_HTTP_header_add_content_type(odr,
1246 "text/xml", charset);
1248 z_HTTP_header_add(odr, &hreq->headers,
1249 "SOAPAction", "\"\"");
1250 p->which = Z_SOAP_generic;
1251 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1252 p->u.generic->no = 0;
1253 p->u.generic->ns = 0;
1254 p->u.generic->p = srw_pdu;
1255 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1258 if (srw_pdu->which == Z_SRW_update_request ||
1259 srw_pdu->which == Z_SRW_update_response)
1260 p->u.generic->no = 1; /* second handler */
1262 return z_soap_codec_enc(odr, &p,
1264 &hreq->content_len, handlers,
1268 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1270 Z_SRW_recordVersion *ver
1271 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1273 for (i = 0; i < num; ++i)
1275 ver[i].versionType = 0;
1276 ver[i].versionValue = 0;
1281 const char *yaz_srw_pack_to_str(int pack)
1285 case Z_SRW_recordPacking_string:
1287 case Z_SRW_recordPacking_XML:
1289 case Z_SRW_recordPacking_URL:
1295 int yaz_srw_str_to_pack(const char *str)
1297 if (!yaz_matchstr(str, "string"))
1298 return Z_SRW_recordPacking_string;
1299 if (!yaz_matchstr(str, "xml"))
1300 return Z_SRW_recordPacking_XML;
1301 if (!yaz_matchstr(str, "url"))
1302 return Z_SRW_recordPacking_URL;
1306 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1312 Z_SRW_extra_arg **ea = &sr->extra_args;
1313 yaz_uri_to_array(extra_args, odr, &name, &val);
1317 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1318 (*ea)->name = *name;
1319 (*ea)->value = *val;
1332 * c-file-style: "Stroustrup"
1333 * indent-tabs-mode: nil
1335 * vim: shiftwidth=4 tabstop=8 expandtab