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;
338 yaz_srw_decodeauth(*srw_pdu, hreq, 0, 0, decode);
340 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
341 (*srw_pdu)->u.request->database == 0)
342 (*srw_pdu)->u.request->database = db;
344 if ((*srw_pdu)->which == Z_SRW_explain_request &&
345 (*srw_pdu)->u.explain_request->database == 0)
346 (*srw_pdu)->u.explain_request->database = db;
348 if ((*srw_pdu)->which == Z_SRW_scan_request &&
349 (*srw_pdu)->u.scan_request->database == 0)
350 (*srw_pdu)->u.scan_request->database = db;
352 if ((*srw_pdu)->which == Z_SRW_update_request &&
353 (*srw_pdu)->u.update_request->database == 0)
354 (*srw_pdu)->u.update_request->database = db;
365 static int yaz_sru_decode_integer(ODR odr, const char *pname,
366 const char *valstr, Odr_int **valp,
367 Z_SRW_diagnostic **diag, int *num_diag,
373 if (sscanf(valstr, "%d", &ival) != 1)
375 yaz_add_srw_diagnostic(odr, diag, num_diag,
376 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
379 if (min_value >= 0 && ival < min_value)
381 yaz_add_srw_diagnostic(odr, diag, num_diag,
382 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
385 *valp = odr_intdup(odr, ival);
391 http://www.loc.gov/z3950/agency/zing/srw/service.html
393 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
394 Z_SOAP **soap_package, ODR decode, char **charset,
395 Z_SRW_diagnostic **diag, int *num_diag)
398 static Z_SOAP_Handler soap_handlers[2] = {
399 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
403 const char *content_type = z_HTTP_header_lookup(hreq->headers,
407 SRU GET: ignore content type.
408 SRU POST: we support "application/x-www-form-urlencoded";
409 not "multipart/form-data" .
411 if (!strcmp(hreq->method, "GET")
413 (!strcmp(hreq->method, "POST") && content_type &&
414 !yaz_strcmp_del("application/x-www-form-urlencoded",
415 content_type, "; ")))
417 char *db = "Default";
418 const char *p0 = hreq->path, *p1;
420 const char *operation = 0;
427 char *stylesheet = 0;
428 char *scanClause = 0;
429 char *pScanClause = 0;
430 char *recordXPath = 0;
431 char *recordSchema = 0;
432 char *recordPacking = "xml"; /* xml packing is default for SRU */
433 char *maximumRecords = 0;
434 char *startRecord = 0;
435 char *maximumTerms = 0;
436 char *responsePosition = 0;
437 char *extraRequestData = 0;
438 Z_SRW_extra_arg *extra_args = 0;
443 grab_charset(decode, content_type, charset);
444 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
449 p1 = strchr(p0, '?');
451 p1 = p0 + strlen(p0);
453 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
454 if (!strcmp(hreq->method, "POST"))
455 p1 = hreq->content_buf;
456 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
461 for (i = 0; uri_name[i]; i++)
463 char *n = uri_name[i];
464 char *v = uri_val[i];
465 if (!strcmp(n, "query"))
467 else if (!strcmp(n, "x-pquery"))
469 else if (!strcmp(n, "x-username"))
471 else if (!strcmp(n, "x-password"))
473 else if (!strcmp(n, "operation"))
475 else if (!strcmp(n, "stylesheet"))
477 else if (!strcmp(n, "sortKeys"))
479 else if (!strcmp(n, "recordXPath"))
481 else if (!strcmp(n, "recordSchema"))
483 else if (!strcmp(n, "recordPacking"))
485 else if (!strcmp(n, "version"))
487 else if (!strcmp(n, "scanClause"))
489 else if (!strcmp(n, "x-pScanClause"))
491 else if (!strcmp(n, "maximumRecords"))
493 else if (!strcmp(n, "startRecord"))
495 else if (!strcmp(n, "maximumTerms"))
497 else if (!strcmp(n, "responsePosition"))
498 responsePosition = v;
499 else if (!strcmp(n, "extraRequestData"))
500 extraRequestData = v;
501 else if (n[0] == 'x' && n[1] == '-')
503 Z_SRW_extra_arg **l = &extra_args;
506 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
507 (*l)->name = odr_strdup(decode, n);
508 (*l)->value = odr_strdup(decode, v);
512 yaz_add_srw_diagnostic(decode, diag, num_diag,
513 YAZ_SRW_UNSUPP_PARAMETER, n);
519 yaz_add_srw_diagnostic(
520 decode, diag, num_diag,
521 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
525 version = yaz_negotiate_sru_version(version);
528 { /* negotiation failed. */
529 yaz_add_srw_diagnostic(decode, diag, num_diag,
530 YAZ_SRW_UNSUPP_VERSION, "1.2");
537 yaz_add_srw_diagnostic(
538 decode, diag, num_diag,
539 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
540 operation = "explain";
542 if (!strcmp(operation, "searchRetrieve"))
544 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
546 sr->srw_version = version;
547 sr->extra_args = extra_args;
549 yaz_srw_decodeauth(sr, hreq, username, password, decode);
552 sr->u.request->query_type = Z_SRW_query_type_cql;
553 sr->u.request->query.cql = query;
557 sr->u.request->query_type = Z_SRW_query_type_pqf;
558 sr->u.request->query.pqf = pQuery;
561 yaz_add_srw_diagnostic(
562 decode, diag, num_diag,
563 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
567 sr->u.request->sort_type = Z_SRW_sort_type_sort;
568 sr->u.request->sort.sortKeys = sortKeys;
570 sr->u.request->recordXPath = recordXPath;
571 sr->u.request->recordSchema = recordSchema;
572 sr->u.request->recordPacking = recordPacking;
573 sr->u.request->stylesheet = stylesheet;
575 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
576 &sr->u.request->maximumRecords,
579 yaz_sru_decode_integer(decode, "startRecord", startRecord,
580 &sr->u.request->startRecord,
583 sr->u.request->database = db;
585 (*soap_package) = (Z_SOAP *)
586 odr_malloc(decode, sizeof(**soap_package));
587 (*soap_package)->which = Z_SOAP_generic;
589 (*soap_package)->u.generic = (Z_SOAP_Generic *)
590 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
592 (*soap_package)->u.generic->p = sr;
593 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
594 (*soap_package)->u.generic->no = 0;
596 (*soap_package)->ns = "SRU";
600 else if (!strcmp(operation, "explain"))
602 /* Transfer SRU explain parameters to common struct */
603 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
604 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
606 sr->srw_version = version;
607 sr->extra_args = extra_args;
608 yaz_srw_decodeauth(sr, hreq, username, password, decode);
610 sr->u.explain_request->recordPacking = recordPacking;
611 sr->u.explain_request->database = db;
613 sr->u.explain_request->stylesheet = stylesheet;
615 (*soap_package) = (Z_SOAP *)
616 odr_malloc(decode, sizeof(**soap_package));
617 (*soap_package)->which = Z_SOAP_generic;
619 (*soap_package)->u.generic = (Z_SOAP_Generic *)
620 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
622 (*soap_package)->u.generic->p = sr;
623 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
624 (*soap_package)->u.generic->no = 0;
626 (*soap_package)->ns = "SRU";
630 else if (!strcmp(operation, "scan"))
632 /* Transfer SRU scan parameters to common struct */
633 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
634 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
636 sr->srw_version = version;
637 sr->extra_args = extra_args;
639 yaz_srw_decodeauth(sr, hreq, username, password, decode);
643 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
644 sr->u.scan_request->scanClause.cql = scanClause;
646 else if (pScanClause)
648 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
649 sr->u.scan_request->scanClause.pqf = pScanClause;
652 yaz_add_srw_diagnostic(
653 decode, diag, num_diag,
654 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
655 sr->u.scan_request->database = db;
657 yaz_sru_decode_integer(decode, "maximumTerms",
659 &sr->u.scan_request->maximumTerms,
662 yaz_sru_decode_integer(decode, "responsePosition",
664 &sr->u.scan_request->responsePosition,
667 sr->u.scan_request->stylesheet = stylesheet;
669 (*soap_package) = (Z_SOAP *)
670 odr_malloc(decode, sizeof(**soap_package));
671 (*soap_package)->which = Z_SOAP_generic;
673 (*soap_package)->u.generic = (Z_SOAP_Generic *)
674 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
676 (*soap_package)->u.generic->p = sr;
677 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
678 (*soap_package)->u.generic->no = 0;
680 (*soap_package)->ns = "SRU";
686 /* unsupported operation ... */
687 /* Act as if we received a explain request and throw diagnostic. */
689 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
691 sr->srw_version = version;
693 sr->u.explain_request->recordPacking = recordPacking;
694 sr->u.explain_request->database = db;
696 sr->u.explain_request->stylesheet = stylesheet;
698 (*soap_package) = (Z_SOAP *)
699 odr_malloc(decode, sizeof(**soap_package));
700 (*soap_package)->which = Z_SOAP_generic;
702 (*soap_package)->u.generic = (Z_SOAP_Generic *)
703 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
705 (*soap_package)->u.generic->p = sr;
706 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
707 (*soap_package)->u.generic->no = 0;
709 (*soap_package)->ns = "SRU";
711 yaz_add_srw_diagnostic(decode, diag, num_diag,
712 YAZ_SRW_UNSUPP_OPERATION, operation);
721 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
723 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
724 odr_malloc(o, sizeof(*res));
726 res->extraRecordData_buf = 0;
727 res->extraRecordData_len = 0;
728 res->recordIdentifier = 0;
733 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
735 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
738 for (i = 0; i<n; i++)
740 res[i].recordSchema = 0;
741 res[i].recordPacking = Z_SRW_recordPacking_string;
742 res[i].recordData_buf = 0;
743 res[i].recordData_len = 0;
744 res[i].recordPosition = 0;
749 Z_SRW_record *yaz_srw_get_record(ODR o)
751 return yaz_srw_get_records(o, 1);
754 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
756 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
757 p->srw_version = odr_strdup(o, version);
761 p->extraResponseData_buf = 0;
762 p->extraResponseData_len = 0;
766 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
768 return yaz_srw_get_core_ver(o, "1.1");
771 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
773 return yaz_srw_get_pdu(o, which, "1.1");
776 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
778 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
783 case Z_SRW_searchRetrieve_request:
784 sr->u.request = (Z_SRW_searchRetrieveRequest *)
785 odr_malloc(o, sizeof(*sr->u.request));
786 sr->u.request->query_type = Z_SRW_query_type_cql;
787 sr->u.request->query.cql = 0;
788 sr->u.request->sort_type = Z_SRW_sort_type_none;
789 sr->u.request->sort.none = 0;
790 sr->u.request->startRecord = 0;
791 sr->u.request->maximumRecords = 0;
792 sr->u.request->recordSchema = 0;
793 sr->u.request->recordPacking = 0;
794 sr->u.request->recordXPath = 0;
795 sr->u.request->database = 0;
796 sr->u.request->resultSetTTL = 0;
797 sr->u.request->stylesheet = 0;
798 sr->u.request->facetList = 0;
800 case Z_SRW_searchRetrieve_response:
801 sr->u.response = (Z_SRW_searchRetrieveResponse *)
802 odr_malloc(o, sizeof(*sr->u.response));
803 sr->u.response->numberOfRecords = 0;
804 sr->u.response->resultSetId = 0;
805 sr->u.response->resultSetIdleTime = 0;
806 sr->u.response->records = 0;
807 sr->u.response->num_records = 0;
808 sr->u.response->diagnostics = 0;
809 sr->u.response->num_diagnostics = 0;
810 sr->u.response->nextRecordPosition = 0;
811 sr->u.response->extra_records = 0;
812 sr->u.response->facetList = 0;
814 case Z_SRW_explain_request:
815 sr->u.explain_request = (Z_SRW_explainRequest *)
816 odr_malloc(o, sizeof(*sr->u.explain_request));
817 sr->u.explain_request->recordPacking = 0;
818 sr->u.explain_request->database = 0;
819 sr->u.explain_request->stylesheet = 0;
821 case Z_SRW_explain_response:
822 sr->u.explain_response = (Z_SRW_explainResponse *)
823 odr_malloc(o, sizeof(*sr->u.explain_response));
824 sr->u.explain_response->record.recordData_buf = 0;
825 sr->u.explain_response->record.recordData_len = 0;
826 sr->u.explain_response->record.recordSchema = 0;
827 sr->u.explain_response->record.recordPosition = 0;
828 sr->u.explain_response->record.recordPacking =
829 Z_SRW_recordPacking_string;
830 sr->u.explain_response->diagnostics = 0;
831 sr->u.explain_response->num_diagnostics = 0;
832 sr->u.explain_response->extra_record = 0;
834 case Z_SRW_scan_request:
835 sr->u.scan_request = (Z_SRW_scanRequest *)
836 odr_malloc(o, sizeof(*sr->u.scan_request));
837 sr->u.scan_request->database = 0;
838 sr->u.scan_request->stylesheet = 0;
839 sr->u.scan_request->maximumTerms = 0;
840 sr->u.scan_request->responsePosition = 0;
841 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
842 sr->u.scan_request->scanClause.cql = 0;
844 case Z_SRW_scan_response:
845 sr->u.scan_response = (Z_SRW_scanResponse *)
846 odr_malloc(o, sizeof(*sr->u.scan_response));
847 sr->u.scan_response->terms = 0;
848 sr->u.scan_response->num_terms = 0;
849 sr->u.scan_response->diagnostics = 0;
850 sr->u.scan_response->num_diagnostics = 0;
852 case Z_SRW_update_request:
853 sr->u.update_request = (Z_SRW_updateRequest *)
854 odr_malloc(o, sizeof(*sr->u.update_request));
855 sr->u.update_request->database = 0;
856 sr->u.update_request->stylesheet = 0;
857 sr->u.update_request->record = 0;
858 sr->u.update_request->recordId = 0;
859 sr->u.update_request->recordVersions = 0;
860 sr->u.update_request->num_recordVersions = 0;
861 sr->u.update_request->extra_record = 0;
862 sr->u.update_request->extraRequestData_buf = 0;
863 sr->u.update_request->extraRequestData_len = 0;
864 sr->u.request->database = 0;
866 case Z_SRW_update_response:
867 sr->u.update_response = (Z_SRW_updateResponse *)
868 odr_malloc(o, sizeof(*sr->u.update_response));
869 sr->u.update_response->operationStatus = 0;
870 sr->u.update_response->recordId = 0;
871 sr->u.update_response->recordVersions = 0;
872 sr->u.update_response->num_recordVersions = 0;
873 sr->u.update_response->record = 0;
874 sr->u.update_response->extra_record = 0;
875 sr->u.update_response->extraResponseData_buf = 0;
876 sr->u.update_response->extraResponseData_len = 0;
877 sr->u.update_response->diagnostics = 0;
878 sr->u.update_response->num_diagnostics = 0;
884 static int bib1_srw_map[] = {
894 108, 10, /* Malformed query : Syntax error */
924 100, 1, /* bad map */
972 205, 1, /* bad map */
973 206, 1, /* bad map */
975 208, 1, /* bad map */
986 218, 1, /* bad map */
987 219, 1, /* bad map */
988 220, 1, /* bad map */
989 221, 1, /* bad map */
991 223, 1, /* bad map */
992 224, 1, /* bad map */
993 225, 1, /* bad map */
994 226, 1, /* bad map */
996 228, 1, /* bad map */
1001 233, 1, /* bad map */
1002 234, 1, /* bad map */
1008 240, 1, /* bad map */
1009 241, 1, /* bad map */
1011 243, 1, /* bad map */
1016 1001, 1, /* bad map */
1017 1002, 1, /* bad map */
1018 1003, 1, /* bad map */
1019 1004, 1, /* bad map */
1020 1005, 1, /* bad map */
1021 1006, 1, /* bad map */
1054 * This array contains overrides for when the first occurrence of a
1055 * particular SRW error in the array above does not correspond with
1056 * the best back-translation of that SRW error.
1058 static int srw_bib1_map[] = {
1060 /* No doubt there are many more */
1065 int yaz_diag_bib1_to_srw (int code)
1067 const int *p = bib1_srw_map;
1077 int yaz_diag_srw_to_bib1(int code)
1079 /* Check explicit reverse-map first */
1080 const int *p = srw_bib1_map;
1088 /* Fall back on reverse lookup in main map */
1099 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1100 char *a_name, Odr_int *val)
1105 value[*i] = (char *) odr_malloc(o, 40);
1106 sprintf(value[*i], ODR_INT_PRINTF, *val);
1111 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1112 char *a_name, char *val)
1122 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1123 char **name, char **value, int max_names)
1126 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1127 name[i] = "operation";
1128 switch(srw_pdu->which)
1130 case Z_SRW_searchRetrieve_request:
1131 value[i++] = "searchRetrieve";
1132 switch(srw_pdu->u.request->query_type)
1134 case Z_SRW_query_type_cql:
1135 yaz_add_name_value_str(encode, name, value, &i, "query",
1136 srw_pdu->u.request->query.cql);
1138 case Z_SRW_query_type_pqf:
1139 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1140 srw_pdu->u.request->query.pqf);
1142 case Z_SRW_query_type_xcql:
1143 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1144 srw_pdu->u.request->query.xcql);
1147 switch(srw_pdu->u.request->sort_type)
1149 case Z_SRW_sort_type_none:
1151 case Z_SRW_sort_type_sort:
1152 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1153 srw_pdu->u.request->sort.sortKeys);
1156 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1157 srw_pdu->u.request->startRecord);
1158 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1159 srw_pdu->u.request->maximumRecords);
1160 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1161 srw_pdu->u.request->recordSchema);
1162 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1163 srw_pdu->u.request->recordPacking);
1164 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1165 srw_pdu->u.request->recordXPath);
1166 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1167 srw_pdu->u.request->stylesheet);
1168 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1169 srw_pdu->u.request->resultSetTTL);
1171 case Z_SRW_explain_request:
1172 value[i++] = "explain";
1173 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1174 srw_pdu->u.explain_request->stylesheet);
1176 case Z_SRW_scan_request:
1177 value[i++] = "scan";
1179 switch(srw_pdu->u.scan_request->query_type)
1181 case Z_SRW_query_type_cql:
1182 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1183 srw_pdu->u.scan_request->scanClause.cql);
1185 case Z_SRW_query_type_pqf:
1186 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1187 srw_pdu->u.scan_request->scanClause.pqf);
1189 case Z_SRW_query_type_xcql:
1190 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1191 srw_pdu->u.scan_request->scanClause.xcql);
1194 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1195 srw_pdu->u.scan_request->responsePosition);
1196 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1197 srw_pdu->u.scan_request->maximumTerms);
1198 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1199 srw_pdu->u.scan_request->stylesheet);
1201 case Z_SRW_update_request:
1202 value[i++] = "update";
1207 if (srw_pdu->extra_args)
1209 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1210 for (; ea && i < max_names-1; ea = ea->next)
1213 value[i] = ea->value;
1222 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1223 ODR encode, const char *charset)
1225 char *name[30], *value[30]; /* definite upper limit for SRU params */
1229 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1230 srw_pdu->username, srw_pdu->password);
1231 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1233 yaz_array_to_uri(&uri_args, encode, name, value);
1235 hreq->method = "GET";
1238 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1240 sprintf(path, "%s?%s", hreq->path, uri_args);
1241 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1244 z_HTTP_header_add_content_type(encode, &hreq->headers,
1245 "text/xml", charset);
1249 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1250 ODR encode, const char *charset)
1252 char *name[30], *value[30]; /* definite upper limit for SRU params */
1255 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1256 srw_pdu->username, srw_pdu->password);
1257 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1260 yaz_array_to_uri(&uri_args, encode, name, value);
1262 hreq->method = "POST";
1264 hreq->content_buf = uri_args;
1265 hreq->content_len = strlen(uri_args);
1267 z_HTTP_header_add_content_type(encode, &hreq->headers,
1268 "application/x-www-form-urlencoded",
1273 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1274 ODR odr, const char *charset)
1276 Z_SOAP_Handler handlers[3] = {
1278 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1279 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1283 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1285 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1286 srw_pdu->username, srw_pdu->password);
1287 z_HTTP_header_add_content_type(odr,
1289 "text/xml", charset);
1291 z_HTTP_header_add(odr, &hreq->headers,
1292 "SOAPAction", "\"\"");
1293 p->which = Z_SOAP_generic;
1294 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1295 p->u.generic->no = 0;
1296 p->u.generic->ns = 0;
1297 p->u.generic->p = srw_pdu;
1298 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1301 if (srw_pdu->which == Z_SRW_update_request ||
1302 srw_pdu->which == Z_SRW_update_response)
1303 p->u.generic->no = 1; /* second handler */
1305 return z_soap_codec_enc(odr, &p,
1307 &hreq->content_len, handlers,
1311 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1313 Z_SRW_recordVersion *ver
1314 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1316 for ( i=0; i < num; ++i ){
1317 ver[i].versionType = 0;
1318 ver[i].versionValue = 0;
1323 const char *yaz_srw_pack_to_str(int pack)
1327 case Z_SRW_recordPacking_string:
1329 case Z_SRW_recordPacking_XML:
1331 case Z_SRW_recordPacking_URL:
1337 int yaz_srw_str_to_pack(const char *str)
1339 if (!yaz_matchstr(str, "string"))
1340 return Z_SRW_recordPacking_string;
1341 if (!yaz_matchstr(str, "xml"))
1342 return Z_SRW_recordPacking_XML;
1343 if (!yaz_matchstr(str, "url"))
1344 return Z_SRW_recordPacking_URL;
1348 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1354 Z_SRW_extra_arg **ea = &sr->extra_args;
1355 yaz_uri_to_array(extra_args, odr, &name, &val);
1359 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1360 (*ea)->name = *name;
1361 (*ea)->value = *val;
1374 * c-file-style: "Stroustrup"
1375 * indent-tabs-mode: nil
1377 * vim: shiftwidth=4 tabstop=8 expandtab