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_attribute_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;
130 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
132 const char *content_type = z_HTTP_header_lookup(hres->headers,
136 if (!yaz_strcmp_del("text/xml", content_type, "; "))
138 if (!yaz_strcmp_del("application/xml", content_type, "; "))
145 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
146 * parameters. Added by SH.
148 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
149 char *username, char *password, ODR decode)
151 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
154 sr->username = username;
156 sr->password = password;
161 char ubuf[256] = "", pbuf[256] = "", *p;
162 if (strncmp(basic, "Basic ", 6))
166 if (!len || len > 256)
168 olen = yaz_base64decode(basic, out);
169 /* Format of out should be username:password at this point */
171 if ((p = strchr(ubuf, ':'))) {
177 sr->username = odr_strdup(decode, ubuf);
179 sr->password = odr_strdup(decode, pbuf);
183 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
185 const char *v = yaz_uri_val(path, name, o);
187 *intp = odr_intdup(o, atoi(v));
190 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
191 const char *uri, const char *message,
194 d->uri = odr_strdup(o, uri);
196 d->message = odr_strdup(o, message);
200 d->details = odr_strdup(o, details);
205 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
206 int code, const char *details)
210 sprintf(uri, "info:srw/diagnostic/1/%d", code);
211 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
214 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
215 int *num, const char *uri,
216 const char *message, const char *details)
218 Z_SRW_diagnostic *d_new;
219 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
221 memcpy (d_new, *d, *num *sizeof(**d));
224 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
228 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
229 int *num, int code, const char *addinfo)
233 sprintf(uri, "info:srw/diagnostic/1/%d", code);
234 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
238 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
239 int *num, int code, const char *addinfo)
243 sprintf(uri, "info:srw/diagnostic/12/%d", code);
244 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
248 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
249 int code, const char *details)
251 const char *message = yaz_diag_srw_str(code);
254 len += strlen(message);
256 len += strlen(details);
258 record->recordData_buf = (char *) odr_malloc(o, len);
260 sprintf(record->recordData_buf, "<diagnostic "
261 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
262 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
264 sprintf(record->recordData_buf + strlen(record->recordData_buf),
265 " <details>%s</details>\n", details);
267 sprintf(record->recordData_buf + strlen(record->recordData_buf),
268 " <message>%s</message>\n", message);
269 sprintf(record->recordData_buf + strlen(record->recordData_buf),
271 record->recordData_len = strlen(record->recordData_buf);
272 record->recordPosition = odr_intdup(o, pos);
273 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
276 static void grab_charset(ODR o, const char *content_type, char **charset)
280 const char *charset_p = 0;
281 if (content_type && (charset_p = strstr(content_type, "; charset=")))
285 while (i < 20 && charset_p[i] &&
286 !strchr("; \n\r", charset_p[i]))
288 *charset = (char*) odr_malloc(o, i+1);
289 memcpy(*charset, charset_p, i);
290 (*charset)[i] = '\0';
295 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
296 Z_SOAP **soap_package, ODR decode, char **charset)
298 if (!strcmp(hreq->method, "POST"))
300 const char *content_type = z_HTTP_header_lookup(hreq->headers,
303 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
304 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
305 !yaz_strcmp_del("text/plain", content_type, "; ")))
307 char *db = "Default";
308 const char *p0 = hreq->path, *p1;
311 static Z_SOAP_Handler soap_handlers[4] = {
313 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
314 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
315 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
322 p1 = strchr(p0, '?');
324 p1 = p0 + strlen(p0);
326 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
327 grab_charset(decode, content_type, charset);
329 ret = z_soap_codec(decode, soap_package,
330 &hreq->content_buf, &hreq->content_len,
332 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
334 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
335 yaz_srw_decodeauth(*srw_pdu, hreq, 0, 0, decode);
337 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
338 (*srw_pdu)->u.request->database == 0)
339 (*srw_pdu)->u.request->database = db;
341 if ((*srw_pdu)->which == Z_SRW_explain_request &&
342 (*srw_pdu)->u.explain_request->database == 0)
343 (*srw_pdu)->u.explain_request->database = db;
345 if ((*srw_pdu)->which == Z_SRW_scan_request &&
346 (*srw_pdu)->u.scan_request->database == 0)
347 (*srw_pdu)->u.scan_request->database = db;
349 if ((*srw_pdu)->which == Z_SRW_update_request &&
350 (*srw_pdu)->u.update_request->database == 0)
351 (*srw_pdu)->u.update_request->database = db;
362 static int yaz_sru_decode_integer(ODR odr, const char *pname,
363 const char *valstr, Odr_int **valp,
364 Z_SRW_diagnostic **diag, int *num_diag,
370 if (sscanf(valstr, "%d", &ival) != 1)
372 yaz_add_srw_diagnostic(odr, diag, num_diag,
373 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
376 if (min_value >= 0 && ival < min_value)
378 yaz_add_srw_diagnostic(odr, diag, num_diag,
379 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
382 *valp = odr_intdup(odr, ival);
388 http://www.loc.gov/z3950/agency/zing/srw/service.html
390 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
391 Z_SOAP **soap_package, ODR decode, char **charset,
392 Z_SRW_diagnostic **diag, int *num_diag)
395 static Z_SOAP_Handler soap_handlers[2] = {
396 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
400 const char *content_type = z_HTTP_header_lookup(hreq->headers,
404 SRU GET: ignore content type.
405 SRU POST: we support "application/x-www-form-urlencoded";
406 not "multipart/form-data" .
408 if (!strcmp(hreq->method, "GET")
410 (!strcmp(hreq->method, "POST") && content_type &&
411 !yaz_strcmp_del("application/x-www-form-urlencoded",
412 content_type, "; ")))
414 char *db = "Default";
415 const char *p0 = hreq->path, *p1;
417 const char *operation = 0;
424 char *stylesheet = 0;
425 char *scanClause = 0;
426 char *pScanClause = 0;
427 char *recordXPath = 0;
428 char *recordSchema = 0;
429 char *recordPacking = "xml"; /* xml packing is default for SRU */
430 char *maximumRecords = 0;
431 char *startRecord = 0;
432 char *maximumTerms = 0;
433 char *responsePosition = 0;
434 char *extraRequestData = 0;
435 Z_SRW_extra_arg *extra_args = 0;
440 grab_charset(decode, content_type, charset);
441 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
446 p1 = strchr(p0, '?');
448 p1 = p0 + strlen(p0);
450 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
451 if (!strcmp(hreq->method, "POST"))
452 p1 = hreq->content_buf;
453 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
458 for (i = 0; uri_name[i]; i++)
460 char *n = uri_name[i];
461 char *v = uri_val[i];
462 if (!strcmp(n, "query"))
464 else if (!strcmp(n, "x-pquery"))
466 else if (!strcmp(n, "x-username"))
468 else if (!strcmp(n, "x-password"))
470 else if (!strcmp(n, "operation"))
472 else if (!strcmp(n, "stylesheet"))
474 else if (!strcmp(n, "sortKeys"))
476 else if (!strcmp(n, "recordXPath"))
478 else if (!strcmp(n, "recordSchema"))
480 else if (!strcmp(n, "recordPacking"))
482 else if (!strcmp(n, "version"))
484 else if (!strcmp(n, "scanClause"))
486 else if (!strcmp(n, "x-pScanClause"))
488 else if (!strcmp(n, "maximumRecords"))
490 else if (!strcmp(n, "startRecord"))
492 else if (!strcmp(n, "maximumTerms"))
494 else if (!strcmp(n, "responsePosition"))
495 responsePosition = v;
496 else if (!strcmp(n, "extraRequestData"))
497 extraRequestData = v;
498 else if (n[0] == 'x' && n[1] == '-')
500 Z_SRW_extra_arg **l = &extra_args;
503 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
504 (*l)->name = odr_strdup(decode, n);
505 (*l)->value = odr_strdup(decode, v);
509 yaz_add_srw_diagnostic(decode, diag, num_diag,
510 YAZ_SRW_UNSUPP_PARAMETER, n);
516 yaz_add_srw_diagnostic(
517 decode, diag, num_diag,
518 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
522 version = yaz_negotiate_sru_version(version);
525 { /* negotiation failed. */
526 yaz_add_srw_diagnostic(decode, diag, num_diag,
527 YAZ_SRW_UNSUPP_VERSION, "1.2");
534 yaz_add_srw_diagnostic(
535 decode, diag, num_diag,
536 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
537 operation = "explain";
539 if (!strcmp(operation, "searchRetrieve"))
541 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
543 sr->srw_version = version;
544 sr->extra_args = extra_args;
546 yaz_srw_decodeauth(sr, hreq, username, password, decode);
549 sr->u.request->query_type = Z_SRW_query_type_cql;
550 sr->u.request->query.cql = query;
554 sr->u.request->query_type = Z_SRW_query_type_pqf;
555 sr->u.request->query.pqf = pQuery;
558 yaz_add_srw_diagnostic(
559 decode, diag, num_diag,
560 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
564 sr->u.request->sort_type = Z_SRW_sort_type_sort;
565 sr->u.request->sort.sortKeys = sortKeys;
567 sr->u.request->recordXPath = recordXPath;
568 sr->u.request->recordSchema = recordSchema;
569 sr->u.request->recordPacking = recordPacking;
570 sr->u.request->stylesheet = stylesheet;
572 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
573 &sr->u.request->maximumRecords,
576 yaz_sru_decode_integer(decode, "startRecord", startRecord,
577 &sr->u.request->startRecord,
580 sr->u.request->database = db;
582 (*soap_package) = (Z_SOAP *)
583 odr_malloc(decode, sizeof(**soap_package));
584 (*soap_package)->which = Z_SOAP_generic;
586 (*soap_package)->u.generic = (Z_SOAP_Generic *)
587 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
589 (*soap_package)->u.generic->p = sr;
590 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
591 (*soap_package)->u.generic->no = 0;
593 (*soap_package)->ns = "SRU";
597 else if (!strcmp(operation, "explain"))
599 /* Transfer SRU explain parameters to common struct */
600 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
601 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
603 sr->srw_version = version;
604 sr->extra_args = extra_args;
605 yaz_srw_decodeauth(sr, hreq, username, password, decode);
607 sr->u.explain_request->recordPacking = recordPacking;
608 sr->u.explain_request->database = db;
610 sr->u.explain_request->stylesheet = stylesheet;
612 (*soap_package) = (Z_SOAP *)
613 odr_malloc(decode, sizeof(**soap_package));
614 (*soap_package)->which = Z_SOAP_generic;
616 (*soap_package)->u.generic = (Z_SOAP_Generic *)
617 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
619 (*soap_package)->u.generic->p = sr;
620 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
621 (*soap_package)->u.generic->no = 0;
623 (*soap_package)->ns = "SRU";
627 else if (!strcmp(operation, "scan"))
629 /* Transfer SRU scan parameters to common struct */
630 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
631 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
633 sr->srw_version = version;
634 sr->extra_args = extra_args;
636 yaz_srw_decodeauth(sr, hreq, username, password, decode);
640 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
641 sr->u.scan_request->scanClause.cql = scanClause;
643 else if (pScanClause)
645 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
646 sr->u.scan_request->scanClause.pqf = pScanClause;
649 yaz_add_srw_diagnostic(
650 decode, diag, num_diag,
651 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
652 sr->u.scan_request->database = db;
654 yaz_sru_decode_integer(decode, "maximumTerms",
656 &sr->u.scan_request->maximumTerms,
659 yaz_sru_decode_integer(decode, "responsePosition",
661 &sr->u.scan_request->responsePosition,
664 sr->u.scan_request->stylesheet = stylesheet;
666 (*soap_package) = (Z_SOAP *)
667 odr_malloc(decode, sizeof(**soap_package));
668 (*soap_package)->which = Z_SOAP_generic;
670 (*soap_package)->u.generic = (Z_SOAP_Generic *)
671 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
673 (*soap_package)->u.generic->p = sr;
674 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
675 (*soap_package)->u.generic->no = 0;
677 (*soap_package)->ns = "SRU";
683 /* unsupported operation ... */
684 /* Act as if we received a explain request and throw diagnostic. */
686 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
688 sr->srw_version = version;
690 sr->u.explain_request->recordPacking = recordPacking;
691 sr->u.explain_request->database = db;
693 sr->u.explain_request->stylesheet = stylesheet;
695 (*soap_package) = (Z_SOAP *)
696 odr_malloc(decode, sizeof(**soap_package));
697 (*soap_package)->which = Z_SOAP_generic;
699 (*soap_package)->u.generic = (Z_SOAP_Generic *)
700 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
702 (*soap_package)->u.generic->p = sr;
703 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
704 (*soap_package)->u.generic->no = 0;
706 (*soap_package)->ns = "SRU";
708 yaz_add_srw_diagnostic(decode, diag, num_diag,
709 YAZ_SRW_UNSUPP_OPERATION, operation);
718 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
720 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
721 odr_malloc(o, sizeof(*res));
723 res->extraRecordData_buf = 0;
724 res->extraRecordData_len = 0;
725 res->recordIdentifier = 0;
730 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
732 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
735 for (i = 0; i<n; i++)
737 res[i].recordSchema = 0;
738 res[i].recordPacking = Z_SRW_recordPacking_string;
739 res[i].recordData_buf = 0;
740 res[i].recordData_len = 0;
741 res[i].recordPosition = 0;
746 Z_SRW_record *yaz_srw_get_record(ODR o)
748 return yaz_srw_get_records(o, 1);
751 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
753 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
754 p->srw_version = odr_strdup(o, version);
758 p->extraResponseData_buf = 0;
759 p->extraResponseData_len = 0;
763 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
765 return yaz_srw_get_core_ver(o, "1.1");
768 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
770 return yaz_srw_get_pdu(o, which, "1.1");
773 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
775 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
780 case Z_SRW_searchRetrieve_request:
781 sr->u.request = (Z_SRW_searchRetrieveRequest *)
782 odr_malloc(o, sizeof(*sr->u.request));
783 sr->u.request->query_type = Z_SRW_query_type_cql;
784 sr->u.request->query.cql = 0;
785 sr->u.request->sort_type = Z_SRW_sort_type_none;
786 sr->u.request->sort.none = 0;
787 sr->u.request->startRecord = 0;
788 sr->u.request->maximumRecords = 0;
789 sr->u.request->recordSchema = 0;
790 sr->u.request->recordPacking = 0;
791 sr->u.request->recordXPath = 0;
792 sr->u.request->database = 0;
793 sr->u.request->resultSetTTL = 0;
794 sr->u.request->stylesheet = 0;
795 sr->u.request->facetList = 0;
797 case Z_SRW_searchRetrieve_response:
798 sr->u.response = (Z_SRW_searchRetrieveResponse *)
799 odr_malloc(o, sizeof(*sr->u.response));
800 sr->u.response->numberOfRecords = 0;
801 sr->u.response->resultSetId = 0;
802 sr->u.response->resultSetIdleTime = 0;
803 sr->u.response->records = 0;
804 sr->u.response->num_records = 0;
805 sr->u.response->diagnostics = 0;
806 sr->u.response->num_diagnostics = 0;
807 sr->u.response->nextRecordPosition = 0;
808 sr->u.response->extra_records = 0;
809 sr->u.response->facetList = 0;
811 case Z_SRW_explain_request:
812 sr->u.explain_request = (Z_SRW_explainRequest *)
813 odr_malloc(o, sizeof(*sr->u.explain_request));
814 sr->u.explain_request->recordPacking = 0;
815 sr->u.explain_request->database = 0;
816 sr->u.explain_request->stylesheet = 0;
818 case Z_SRW_explain_response:
819 sr->u.explain_response = (Z_SRW_explainResponse *)
820 odr_malloc(o, sizeof(*sr->u.explain_response));
821 sr->u.explain_response->record.recordData_buf = 0;
822 sr->u.explain_response->record.recordData_len = 0;
823 sr->u.explain_response->record.recordSchema = 0;
824 sr->u.explain_response->record.recordPosition = 0;
825 sr->u.explain_response->record.recordPacking =
826 Z_SRW_recordPacking_string;
827 sr->u.explain_response->diagnostics = 0;
828 sr->u.explain_response->num_diagnostics = 0;
829 sr->u.explain_response->extra_record = 0;
831 case Z_SRW_scan_request:
832 sr->u.scan_request = (Z_SRW_scanRequest *)
833 odr_malloc(o, sizeof(*sr->u.scan_request));
834 sr->u.scan_request->database = 0;
835 sr->u.scan_request->stylesheet = 0;
836 sr->u.scan_request->maximumTerms = 0;
837 sr->u.scan_request->responsePosition = 0;
838 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
839 sr->u.scan_request->scanClause.cql = 0;
841 case Z_SRW_scan_response:
842 sr->u.scan_response = (Z_SRW_scanResponse *)
843 odr_malloc(o, sizeof(*sr->u.scan_response));
844 sr->u.scan_response->terms = 0;
845 sr->u.scan_response->num_terms = 0;
846 sr->u.scan_response->diagnostics = 0;
847 sr->u.scan_response->num_diagnostics = 0;
849 case Z_SRW_update_request:
850 sr->u.update_request = (Z_SRW_updateRequest *)
851 odr_malloc(o, sizeof(*sr->u.update_request));
852 sr->u.update_request->database = 0;
853 sr->u.update_request->stylesheet = 0;
854 sr->u.update_request->record = 0;
855 sr->u.update_request->recordId = 0;
856 sr->u.update_request->recordVersions = 0;
857 sr->u.update_request->num_recordVersions = 0;
858 sr->u.update_request->extra_record = 0;
859 sr->u.update_request->extraRequestData_buf = 0;
860 sr->u.update_request->extraRequestData_len = 0;
861 sr->u.request->database = 0;
863 case Z_SRW_update_response:
864 sr->u.update_response = (Z_SRW_updateResponse *)
865 odr_malloc(o, sizeof(*sr->u.update_response));
866 sr->u.update_response->operationStatus = 0;
867 sr->u.update_response->recordId = 0;
868 sr->u.update_response->recordVersions = 0;
869 sr->u.update_response->num_recordVersions = 0;
870 sr->u.update_response->record = 0;
871 sr->u.update_response->extra_record = 0;
872 sr->u.update_response->extraResponseData_buf = 0;
873 sr->u.update_response->extraResponseData_len = 0;
874 sr->u.update_response->diagnostics = 0;
875 sr->u.update_response->num_diagnostics = 0;
881 static int bib1_srw_map[] = {
891 108, 10, /* Malformed query : Syntax error */
921 100, 1, /* bad map */
969 205, 1, /* bad map */
970 206, 1, /* bad map */
972 208, 1, /* bad map */
983 218, 1, /* bad map */
984 219, 1, /* bad map */
985 220, 1, /* bad map */
986 221, 1, /* bad map */
988 223, 1, /* bad map */
989 224, 1, /* bad map */
990 225, 1, /* bad map */
991 226, 1, /* bad map */
993 228, 1, /* bad map */
998 233, 1, /* bad map */
999 234, 1, /* bad map */
1005 240, 1, /* bad map */
1006 241, 1, /* bad map */
1008 243, 1, /* bad map */
1013 1001, 1, /* bad map */
1014 1002, 1, /* bad map */
1015 1003, 1, /* bad map */
1016 1004, 1, /* bad map */
1017 1005, 1, /* bad map */
1018 1006, 1, /* bad map */
1051 * This array contains overrides for when the first occurrence of a
1052 * particular SRW error in the array above does not correspond with
1053 * the best back-translation of that SRW error.
1055 static int srw_bib1_map[] = {
1057 /* No doubt there are many more */
1062 int yaz_diag_bib1_to_srw (int code)
1064 const int *p = bib1_srw_map;
1074 int yaz_diag_srw_to_bib1(int code)
1076 /* Check explicit reverse-map first */
1077 const int *p = srw_bib1_map;
1085 /* Fall back on reverse lookup in main map */
1096 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1097 char *a_name, Odr_int *val)
1102 value[*i] = (char *) odr_malloc(o, 40);
1103 sprintf(value[*i], ODR_INT_PRINTF, *val);
1108 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1109 char *a_name, char *val)
1119 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1120 char **name, char **value, int max_names)
1123 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1124 name[i] = "operation";
1125 switch(srw_pdu->which)
1127 case Z_SRW_searchRetrieve_request:
1128 value[i++] = "searchRetrieve";
1129 switch(srw_pdu->u.request->query_type)
1131 case Z_SRW_query_type_cql:
1132 yaz_add_name_value_str(encode, name, value, &i, "query",
1133 srw_pdu->u.request->query.cql);
1135 case Z_SRW_query_type_pqf:
1136 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1137 srw_pdu->u.request->query.pqf);
1139 case Z_SRW_query_type_xcql:
1140 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1141 srw_pdu->u.request->query.xcql);
1144 switch(srw_pdu->u.request->sort_type)
1146 case Z_SRW_sort_type_none:
1148 case Z_SRW_sort_type_sort:
1149 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1150 srw_pdu->u.request->sort.sortKeys);
1153 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1154 srw_pdu->u.request->startRecord);
1155 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1156 srw_pdu->u.request->maximumRecords);
1157 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1158 srw_pdu->u.request->recordSchema);
1159 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1160 srw_pdu->u.request->recordPacking);
1161 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1162 srw_pdu->u.request->recordXPath);
1163 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1164 srw_pdu->u.request->stylesheet);
1165 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1166 srw_pdu->u.request->resultSetTTL);
1168 case Z_SRW_explain_request:
1169 value[i++] = "explain";
1170 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1171 srw_pdu->u.explain_request->stylesheet);
1173 case Z_SRW_scan_request:
1174 value[i++] = "scan";
1176 switch(srw_pdu->u.scan_request->query_type)
1178 case Z_SRW_query_type_cql:
1179 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1180 srw_pdu->u.scan_request->scanClause.cql);
1182 case Z_SRW_query_type_pqf:
1183 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1184 srw_pdu->u.scan_request->scanClause.pqf);
1186 case Z_SRW_query_type_xcql:
1187 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1188 srw_pdu->u.scan_request->scanClause.xcql);
1191 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1192 srw_pdu->u.scan_request->responsePosition);
1193 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1194 srw_pdu->u.scan_request->maximumTerms);
1195 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1196 srw_pdu->u.scan_request->stylesheet);
1198 case Z_SRW_update_request:
1199 value[i++] = "update";
1204 if (srw_pdu->extra_args)
1206 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1207 for (; ea && i < max_names-1; ea = ea->next)
1210 value[i] = ea->value;
1219 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1220 ODR encode, const char *charset)
1222 char *name[30], *value[30]; /* definite upper limit for SRU params */
1226 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1227 srw_pdu->username, srw_pdu->password);
1228 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1230 yaz_array_to_uri(&uri_args, encode, name, value);
1232 hreq->method = "GET";
1235 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1237 sprintf(path, "%s?%s", hreq->path, uri_args);
1238 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1241 z_HTTP_header_add_content_type(encode, &hreq->headers,
1242 "text/xml", charset);
1246 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1247 ODR encode, const char *charset)
1249 char *name[30], *value[30]; /* definite upper limit for SRU params */
1252 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1253 srw_pdu->username, srw_pdu->password);
1254 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1257 yaz_array_to_uri(&uri_args, encode, name, value);
1259 hreq->method = "POST";
1261 hreq->content_buf = uri_args;
1262 hreq->content_len = strlen(uri_args);
1264 z_HTTP_header_add_content_type(encode, &hreq->headers,
1265 "application/x-www-form-urlencoded",
1270 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1271 ODR odr, const char *charset)
1273 Z_SOAP_Handler handlers[3] = {
1275 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1276 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1280 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1282 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1283 srw_pdu->username, srw_pdu->password);
1284 z_HTTP_header_add_content_type(odr,
1286 "text/xml", charset);
1288 z_HTTP_header_add(odr, &hreq->headers,
1289 "SOAPAction", "\"\"");
1290 p->which = Z_SOAP_generic;
1291 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1292 p->u.generic->no = 0;
1293 p->u.generic->ns = 0;
1294 p->u.generic->p = srw_pdu;
1295 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1298 if (srw_pdu->which == Z_SRW_update_request ||
1299 srw_pdu->which == Z_SRW_update_response)
1300 p->u.generic->no = 1; /* second handler */
1302 return z_soap_codec_enc(odr, &p,
1304 &hreq->content_len, handlers,
1308 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1310 Z_SRW_recordVersion *ver
1311 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1313 for ( i=0; i < num; ++i ){
1314 ver[i].versionType = 0;
1315 ver[i].versionValue = 0;
1320 const char *yaz_srw_pack_to_str(int pack)
1324 case Z_SRW_recordPacking_string:
1326 case Z_SRW_recordPacking_XML:
1328 case Z_SRW_recordPacking_URL:
1334 int yaz_srw_str_to_pack(const char *str)
1336 if (!yaz_matchstr(str, "string"))
1337 return Z_SRW_recordPacking_string;
1338 if (!yaz_matchstr(str, "xml"))
1339 return Z_SRW_recordPacking_XML;
1340 if (!yaz_matchstr(str, "url"))
1341 return Z_SRW_recordPacking_URL;
1345 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1351 Z_SRW_extra_arg **ea = &sr->extra_args;
1352 yaz_uri_to_array(extra_args, odr, &name, &val);
1356 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1357 (*ea)->name = *name;
1358 (*ea)->value = *val;
1371 * c-file-style: "Stroustrup"
1372 * indent-tabs-mode: nil
1374 * vim: shiftwidth=4 tabstop=8 expandtab