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[] = {
881 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[] = {
1019 /* No doubt there are many more */
1024 int yaz_diag_bib1_to_srw (int code)
1026 const int *p = bib1_srw_map;
1036 int yaz_diag_srw_to_bib1(int code)
1038 /* Check explicit reverse-map first */
1039 const int *p = srw_bib1_map;
1047 /* Fall back on reverse lookup in main map */
1058 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1059 char *a_name, Odr_int *val)
1064 value[*i] = (char *) odr_malloc(o, 40);
1065 sprintf(value[*i], ODR_INT_PRINTF, *val);
1070 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1071 char *a_name, char *val)
1081 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1082 char **name, char **value, int max_names)
1085 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1086 name[i] = "operation";
1087 switch(srw_pdu->which)
1089 case Z_SRW_searchRetrieve_request:
1090 value[i++] = "searchRetrieve";
1091 switch(srw_pdu->u.request->query_type)
1093 case Z_SRW_query_type_cql:
1094 yaz_add_name_value_str(encode, name, value, &i, "query",
1095 srw_pdu->u.request->query.cql);
1097 case Z_SRW_query_type_pqf:
1098 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1099 srw_pdu->u.request->query.pqf);
1101 case Z_SRW_query_type_xcql:
1102 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1103 srw_pdu->u.request->query.xcql);
1106 switch(srw_pdu->u.request->sort_type)
1108 case Z_SRW_sort_type_none:
1110 case Z_SRW_sort_type_sort:
1111 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1112 srw_pdu->u.request->sort.sortKeys);
1115 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1116 srw_pdu->u.request->startRecord);
1117 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1118 srw_pdu->u.request->maximumRecords);
1119 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1120 srw_pdu->u.request->recordSchema);
1121 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1122 srw_pdu->u.request->recordPacking);
1123 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1124 srw_pdu->u.request->recordXPath);
1125 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1126 srw_pdu->u.request->stylesheet);
1127 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1128 srw_pdu->u.request->resultSetTTL);
1130 case Z_SRW_explain_request:
1131 value[i++] = "explain";
1132 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1133 srw_pdu->u.explain_request->stylesheet);
1135 case Z_SRW_scan_request:
1136 value[i++] = "scan";
1138 switch(srw_pdu->u.scan_request->query_type)
1140 case Z_SRW_query_type_cql:
1141 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1142 srw_pdu->u.scan_request->scanClause.cql);
1144 case Z_SRW_query_type_pqf:
1145 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1146 srw_pdu->u.scan_request->scanClause.pqf);
1148 case Z_SRW_query_type_xcql:
1149 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1150 srw_pdu->u.scan_request->scanClause.xcql);
1153 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1154 srw_pdu->u.scan_request->responsePosition);
1155 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1156 srw_pdu->u.scan_request->maximumTerms);
1157 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1158 srw_pdu->u.scan_request->stylesheet);
1160 case Z_SRW_update_request:
1161 value[i++] = "update";
1166 if (srw_pdu->extra_args)
1168 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1169 for (; ea && i < max_names-1; ea = ea->next)
1172 value[i] = ea->value;
1181 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1182 ODR encode, const char *charset)
1184 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1188 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1189 srw_pdu->username, srw_pdu->password);
1190 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1192 yaz_array_to_uri(&uri_args, encode, name, value);
1194 hreq->method = "GET";
1197 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1199 sprintf(path, "%s?%s", hreq->path, uri_args);
1200 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1203 z_HTTP_header_add_content_type(encode, &hreq->headers,
1204 "text/xml", charset);
1208 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1209 ODR encode, const char *charset)
1211 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1214 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1215 srw_pdu->username, srw_pdu->password);
1216 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1219 yaz_array_to_uri(&uri_args, encode, name, value);
1221 hreq->method = "POST";
1223 hreq->content_buf = uri_args;
1224 hreq->content_len = strlen(uri_args);
1226 z_HTTP_header_add_content_type(encode, &hreq->headers,
1227 "application/x-www-form-urlencoded",
1232 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1233 ODR odr, const char *charset)
1235 Z_SOAP_Handler handlers[3] = {
1237 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1238 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1242 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1244 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1245 srw_pdu->username, srw_pdu->password);
1246 z_HTTP_header_add_content_type(odr,
1248 "text/xml", charset);
1250 z_HTTP_header_add(odr, &hreq->headers,
1251 "SOAPAction", "\"\"");
1252 p->which = Z_SOAP_generic;
1253 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1254 p->u.generic->no = 0;
1255 p->u.generic->ns = 0;
1256 p->u.generic->p = srw_pdu;
1257 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1260 if (srw_pdu->which == Z_SRW_update_request ||
1261 srw_pdu->which == Z_SRW_update_response)
1262 p->u.generic->no = 1; /* second handler */
1264 return z_soap_codec_enc(odr, &p,
1266 &hreq->content_len, handlers,
1270 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1272 Z_SRW_recordVersion *ver
1273 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1275 for (i = 0; i < num; ++i)
1277 ver[i].versionType = 0;
1278 ver[i].versionValue = 0;
1283 const char *yaz_srw_pack_to_str(int pack)
1287 case Z_SRW_recordPacking_string:
1289 case Z_SRW_recordPacking_XML:
1291 case Z_SRW_recordPacking_URL:
1297 int yaz_srw_str_to_pack(const char *str)
1299 if (!yaz_matchstr(str, "string"))
1300 return Z_SRW_recordPacking_string;
1301 if (!yaz_matchstr(str, "xml"))
1302 return Z_SRW_recordPacking_XML;
1303 if (!yaz_matchstr(str, "url"))
1304 return Z_SRW_recordPacking_URL;
1308 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1314 Z_SRW_extra_arg **ea = &sr->extra_args;
1315 yaz_uri_to_array(extra_args, odr, &name, &val);
1319 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1320 (*ea)->name = *name;
1321 (*ea)->value = *val;
1334 * c-file-style: "Stroustrup"
1335 * indent-tabs-mode: nil
1337 * vim: shiftwidth=4 tabstop=8 expandtab