1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2010 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SRW/SRU utilities.
13 #include <yaz/matchstr.h>
14 #include <yaz/yaz-iconv.h>
17 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
19 return odr_strdupn(n, uri, len);
22 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
29 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
31 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
32 yaz_encode_sru_dbpath_buf(dst, db);
37 static int yaz_base64decode(const char *in, char *out)
39 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
40 "abcdefghijklmnopqrstuvwxyz0123456789+/";
49 if (!(p = strchr(map, in[0])))
53 if (!(p = strchr(map, in[1])))
57 *(out++) = i0 << 2 | i1 >> 4;
61 if (!(p = strchr(map, in[2])))
65 *(out++) = i1 << 4 | i2 >> 2;
69 if (!(p = strchr(map, in[3])))
73 *(out++) = i2 << 6 | i3;
84 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
86 const char *content_type = z_HTTP_header_lookup(hres->headers,
90 if (!yaz_strcmp_del("text/xml", content_type, "; "))
92 if (!yaz_strcmp_del("application/xml", content_type, "; "))
99 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
100 * parameters. Added by SH.
103 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
104 char *username, char *password, ODR decode)
106 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
109 sr->username = username;
111 sr->password = password;
116 char ubuf[256] = "", pbuf[256] = "", *p;
117 if (strncmp(basic, "Basic ", 6))
121 if (!len || len > 256)
123 olen = yaz_base64decode(basic, out);
124 /* Format of out should be username:password at this point */
126 if ((p = strchr(ubuf, ':'))) {
132 sr->username = odr_strdup(decode, ubuf);
134 sr->password = odr_strdup(decode, pbuf);
139 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
141 const char *v = yaz_uri_val(path, name, o);
143 *intp = odr_intdup(o, atoi(v));
146 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
147 const char *uri, const char *message,
150 d->uri = odr_strdup(o, uri);
152 d->message = odr_strdup(o, message);
156 d->details = odr_strdup(o, details);
161 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
162 int code, const char *details)
166 sprintf(uri, "info:srw/diagnostic/1/%d", code);
167 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
170 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
171 int *num, const char *uri,
172 const char *message, const char *details)
174 Z_SRW_diagnostic *d_new;
175 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
177 memcpy (d_new, *d, *num *sizeof(**d));
180 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
184 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
185 int *num, int code, const char *addinfo)
189 sprintf(uri, "info:srw/diagnostic/1/%d", code);
190 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
194 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
195 int *num, int code, const char *addinfo)
199 sprintf(uri, "info:srw/diagnostic/12/%d", code);
200 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
204 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
205 int code, const char *details)
207 const char *message = yaz_diag_srw_str(code);
210 len += strlen(message);
212 len += strlen(details);
214 record->recordData_buf = (char *) odr_malloc(o, len);
216 sprintf(record->recordData_buf, "<diagnostic "
217 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
218 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
220 sprintf(record->recordData_buf + strlen(record->recordData_buf),
221 " <details>%s</details>\n", details);
223 sprintf(record->recordData_buf + strlen(record->recordData_buf),
224 " <message>%s</message>\n", message);
225 sprintf(record->recordData_buf + strlen(record->recordData_buf),
227 record->recordData_len = strlen(record->recordData_buf);
228 record->recordPosition = odr_intdup(o, pos);
229 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
232 static void grab_charset(ODR o, const char *content_type, char **charset)
236 const char *charset_p = 0;
237 if (content_type && (charset_p = strstr(content_type, "; charset=")))
241 while (i < 20 && charset_p[i] &&
242 !strchr("; \n\r", charset_p[i]))
244 *charset = (char*) odr_malloc(o, i+1);
245 memcpy(*charset, charset_p, i);
246 (*charset)[i] = '\0';
251 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
252 Z_SOAP **soap_package, ODR decode, char **charset)
254 if (!strcmp(hreq->method, "POST"))
256 const char *content_type = z_HTTP_header_lookup(hreq->headers,
259 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
260 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
261 !yaz_strcmp_del("text/plain", content_type, "; ")))
263 char *db = "Default";
264 const char *p0 = hreq->path, *p1;
267 static Z_SOAP_Handler soap_handlers[4] = {
269 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
270 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
271 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
278 p1 = strchr(p0, '?');
280 p1 = p0 + strlen(p0);
282 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
283 grab_charset(decode, content_type, charset);
285 ret = z_soap_codec(decode, soap_package,
286 &hreq->content_buf, &hreq->content_len,
288 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
290 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
292 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
293 (*srw_pdu)->u.request->database == 0)
294 (*srw_pdu)->u.request->database = db;
296 if ((*srw_pdu)->which == Z_SRW_explain_request &&
297 (*srw_pdu)->u.explain_request->database == 0)
298 (*srw_pdu)->u.explain_request->database = db;
300 if ((*srw_pdu)->which == Z_SRW_scan_request &&
301 (*srw_pdu)->u.scan_request->database == 0)
302 (*srw_pdu)->u.scan_request->database = db;
304 if ((*srw_pdu)->which == Z_SRW_update_request &&
305 (*srw_pdu)->u.update_request->database == 0)
306 (*srw_pdu)->u.update_request->database = db;
317 static int yaz_sru_decode_integer(ODR odr, const char *pname,
318 const char *valstr, Odr_int **valp,
319 Z_SRW_diagnostic **diag, int *num_diag,
325 if (sscanf(valstr, "%d", &ival) != 1)
327 yaz_add_srw_diagnostic(odr, diag, num_diag,
328 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
331 if (min_value >= 0 && ival < min_value)
333 yaz_add_srw_diagnostic(odr, diag, num_diag,
334 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
337 *valp = odr_intdup(odr, ival);
343 http://www.loc.gov/z3950/agency/zing/srw/service.html
345 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
346 Z_SOAP **soap_package, ODR decode, char **charset,
347 Z_SRW_diagnostic **diag, int *num_diag)
350 static Z_SOAP_Handler soap_handlers[2] = {
351 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
355 const char *content_type = z_HTTP_header_lookup(hreq->headers,
359 SRU GET: ignore content type.
360 SRU POST: we support "application/x-www-form-urlencoded";
361 not "multipart/form-data" .
363 if (!strcmp(hreq->method, "GET")
365 (!strcmp(hreq->method, "POST") && content_type &&
366 !yaz_strcmp_del("application/x-www-form-urlencoded",
367 content_type, "; ")))
369 char *db = "Default";
370 const char *p0 = hreq->path, *p1;
372 const char *operation = 0;
379 char *stylesheet = 0;
380 char *scanClause = 0;
381 char *pScanClause = 0;
382 char *recordXPath = 0;
383 char *recordSchema = 0;
384 char *recordPacking = "xml"; /* xml packing is default for SRU */
385 char *maximumRecords = 0;
386 char *startRecord = 0;
387 char *maximumTerms = 0;
388 char *responsePosition = 0;
389 char *extraRequestData = 0;
390 Z_SRW_extra_arg *extra_args = 0;
395 grab_charset(decode, content_type, charset);
396 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
401 p1 = strchr(p0, '?');
403 p1 = p0 + strlen(p0);
405 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
406 if (!strcmp(hreq->method, "POST"))
407 p1 = hreq->content_buf;
408 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
413 for (i = 0; uri_name[i]; i++)
415 char *n = uri_name[i];
416 char *v = uri_val[i];
417 if (!strcmp(n, "query"))
419 else if (!strcmp(n, "x-pquery"))
421 else if (!strcmp(n, "x-username"))
423 else if (!strcmp(n, "x-password"))
425 else if (!strcmp(n, "operation"))
427 else if (!strcmp(n, "stylesheet"))
429 else if (!strcmp(n, "sortKeys"))
431 else if (!strcmp(n, "recordXPath"))
433 else if (!strcmp(n, "recordSchema"))
435 else if (!strcmp(n, "recordPacking"))
437 else if (!strcmp(n, "version"))
439 else if (!strcmp(n, "scanClause"))
441 else if (!strcmp(n, "x-pScanClause"))
443 else if (!strcmp(n, "maximumRecords"))
445 else if (!strcmp(n, "startRecord"))
447 else if (!strcmp(n, "maximumTerms"))
449 else if (!strcmp(n, "responsePosition"))
450 responsePosition = v;
451 else if (!strcmp(n, "extraRequestData"))
452 extraRequestData = v;
453 else if (n[0] == 'x' && n[1] == '-')
455 Z_SRW_extra_arg **l = &extra_args;
458 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
459 (*l)->name = odr_strdup(decode, n);
460 (*l)->value = odr_strdup(decode, v);
464 yaz_add_srw_diagnostic(decode, diag, num_diag,
465 YAZ_SRW_UNSUPP_PARAMETER, n);
471 yaz_add_srw_diagnostic(
472 decode, diag, num_diag,
473 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
477 version = yaz_negotiate_sru_version(version);
480 { /* negotiation failed. */
481 yaz_add_srw_diagnostic(decode, diag, num_diag,
482 YAZ_SRW_UNSUPP_VERSION, "1.2");
489 yaz_add_srw_diagnostic(
490 decode, diag, num_diag,
491 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
492 operation = "explain";
494 if (!strcmp(operation, "searchRetrieve"))
496 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
498 sr->srw_version = version;
499 sr->extra_args = extra_args;
501 yaz_srw_decodeauth(sr, hreq, username, password, decode);
504 sr->u.request->query_type = Z_SRW_query_type_cql;
505 sr->u.request->query.cql = query;
509 sr->u.request->query_type = Z_SRW_query_type_pqf;
510 sr->u.request->query.pqf = pQuery;
513 yaz_add_srw_diagnostic(
514 decode, diag, num_diag,
515 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
519 sr->u.request->sort_type = Z_SRW_sort_type_sort;
520 sr->u.request->sort.sortKeys = sortKeys;
522 sr->u.request->recordXPath = recordXPath;
523 sr->u.request->recordSchema = recordSchema;
524 sr->u.request->recordPacking = recordPacking;
525 sr->u.request->stylesheet = stylesheet;
527 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
528 &sr->u.request->maximumRecords,
531 yaz_sru_decode_integer(decode, "startRecord", startRecord,
532 &sr->u.request->startRecord,
535 sr->u.request->database = db;
537 (*soap_package) = (Z_SOAP *)
538 odr_malloc(decode, sizeof(**soap_package));
539 (*soap_package)->which = Z_SOAP_generic;
541 (*soap_package)->u.generic = (Z_SOAP_Generic *)
542 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
544 (*soap_package)->u.generic->p = sr;
545 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
546 (*soap_package)->u.generic->no = 0;
548 (*soap_package)->ns = "SRU";
552 else if (!strcmp(operation, "explain"))
554 /* Transfer SRU explain parameters to common struct */
555 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
556 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
558 sr->srw_version = version;
559 sr->extra_args = extra_args;
560 yaz_srw_decodeauth(sr, hreq, username, password, decode);
562 sr->u.explain_request->recordPacking = recordPacking;
563 sr->u.explain_request->database = db;
565 sr->u.explain_request->stylesheet = stylesheet;
567 (*soap_package) = (Z_SOAP *)
568 odr_malloc(decode, sizeof(**soap_package));
569 (*soap_package)->which = Z_SOAP_generic;
571 (*soap_package)->u.generic = (Z_SOAP_Generic *)
572 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
574 (*soap_package)->u.generic->p = sr;
575 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
576 (*soap_package)->u.generic->no = 0;
578 (*soap_package)->ns = "SRU";
582 else if (!strcmp(operation, "scan"))
584 /* Transfer SRU scan parameters to common struct */
585 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
586 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
588 sr->srw_version = version;
589 sr->extra_args = extra_args;
591 yaz_srw_decodeauth(sr, hreq, username, password, decode);
595 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
596 sr->u.scan_request->scanClause.cql = scanClause;
598 else if (pScanClause)
600 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
601 sr->u.scan_request->scanClause.pqf = pScanClause;
604 yaz_add_srw_diagnostic(
605 decode, diag, num_diag,
606 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
607 sr->u.scan_request->database = db;
609 yaz_sru_decode_integer(decode, "maximumTerms",
611 &sr->u.scan_request->maximumTerms,
614 yaz_sru_decode_integer(decode, "responsePosition",
616 &sr->u.scan_request->responsePosition,
619 sr->u.scan_request->stylesheet = stylesheet;
621 (*soap_package) = (Z_SOAP *)
622 odr_malloc(decode, sizeof(**soap_package));
623 (*soap_package)->which = Z_SOAP_generic;
625 (*soap_package)->u.generic = (Z_SOAP_Generic *)
626 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
628 (*soap_package)->u.generic->p = sr;
629 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
630 (*soap_package)->u.generic->no = 0;
632 (*soap_package)->ns = "SRU";
638 /* unsupported operation ... */
639 /* Act as if we received a explain request and throw diagnostic. */
641 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
643 sr->srw_version = version;
645 sr->u.explain_request->recordPacking = recordPacking;
646 sr->u.explain_request->database = db;
648 sr->u.explain_request->stylesheet = stylesheet;
650 (*soap_package) = (Z_SOAP *)
651 odr_malloc(decode, sizeof(**soap_package));
652 (*soap_package)->which = Z_SOAP_generic;
654 (*soap_package)->u.generic = (Z_SOAP_Generic *)
655 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
657 (*soap_package)->u.generic->p = sr;
658 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
659 (*soap_package)->u.generic->no = 0;
661 (*soap_package)->ns = "SRU";
663 yaz_add_srw_diagnostic(decode, diag, num_diag,
664 YAZ_SRW_UNSUPP_OPERATION, operation);
673 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
675 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
676 odr_malloc(o, sizeof(*res));
678 res->extraRecordData_buf = 0;
679 res->extraRecordData_len = 0;
680 res->recordIdentifier = 0;
685 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
687 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
690 for (i = 0; i<n; i++)
692 res[i].recordSchema = 0;
693 res[i].recordPacking = Z_SRW_recordPacking_string;
694 res[i].recordData_buf = 0;
695 res[i].recordData_len = 0;
696 res[i].recordPosition = 0;
701 Z_SRW_record *yaz_srw_get_record(ODR o)
703 return yaz_srw_get_records(o, 1);
706 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
708 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
709 p->srw_version = odr_strdup(o, version);
713 p->extraResponseData_buf = 0;
714 p->extraResponseData_len = 0;
718 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
720 return yaz_srw_get_core_ver(o, "1.1");
723 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
725 return yaz_srw_get_pdu(o, which, "1.1");
728 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
730 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
735 case Z_SRW_searchRetrieve_request:
736 sr->u.request = (Z_SRW_searchRetrieveRequest *)
737 odr_malloc(o, sizeof(*sr->u.request));
738 sr->u.request->query_type = Z_SRW_query_type_cql;
739 sr->u.request->query.cql = 0;
740 sr->u.request->sort_type = Z_SRW_sort_type_none;
741 sr->u.request->sort.none = 0;
742 sr->u.request->startRecord = 0;
743 sr->u.request->maximumRecords = 0;
744 sr->u.request->recordSchema = 0;
745 sr->u.request->recordPacking = 0;
746 sr->u.request->recordXPath = 0;
747 sr->u.request->database = 0;
748 sr->u.request->resultSetTTL = 0;
749 sr->u.request->stylesheet = 0;
751 case Z_SRW_searchRetrieve_response:
752 sr->u.response = (Z_SRW_searchRetrieveResponse *)
753 odr_malloc(o, sizeof(*sr->u.response));
754 sr->u.response->numberOfRecords = 0;
755 sr->u.response->resultSetId = 0;
756 sr->u.response->resultSetIdleTime = 0;
757 sr->u.response->records = 0;
758 sr->u.response->num_records = 0;
759 sr->u.response->diagnostics = 0;
760 sr->u.response->num_diagnostics = 0;
761 sr->u.response->nextRecordPosition = 0;
762 sr->u.response->extra_records = 0;
764 case Z_SRW_explain_request:
765 sr->u.explain_request = (Z_SRW_explainRequest *)
766 odr_malloc(o, sizeof(*sr->u.explain_request));
767 sr->u.explain_request->recordPacking = 0;
768 sr->u.explain_request->database = 0;
769 sr->u.explain_request->stylesheet = 0;
771 case Z_SRW_explain_response:
772 sr->u.explain_response = (Z_SRW_explainResponse *)
773 odr_malloc(o, sizeof(*sr->u.explain_response));
774 sr->u.explain_response->record.recordData_buf = 0;
775 sr->u.explain_response->record.recordData_len = 0;
776 sr->u.explain_response->record.recordSchema = 0;
777 sr->u.explain_response->record.recordPosition = 0;
778 sr->u.explain_response->record.recordPacking =
779 Z_SRW_recordPacking_string;
780 sr->u.explain_response->diagnostics = 0;
781 sr->u.explain_response->num_diagnostics = 0;
782 sr->u.explain_response->extra_record = 0;
784 case Z_SRW_scan_request:
785 sr->u.scan_request = (Z_SRW_scanRequest *)
786 odr_malloc(o, sizeof(*sr->u.scan_request));
787 sr->u.scan_request->database = 0;
788 sr->u.scan_request->stylesheet = 0;
789 sr->u.scan_request->maximumTerms = 0;
790 sr->u.scan_request->responsePosition = 0;
791 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
792 sr->u.scan_request->scanClause.cql = 0;
794 case Z_SRW_scan_response:
795 sr->u.scan_response = (Z_SRW_scanResponse *)
796 odr_malloc(o, sizeof(*sr->u.scan_response));
797 sr->u.scan_response->terms = 0;
798 sr->u.scan_response->num_terms = 0;
799 sr->u.scan_response->diagnostics = 0;
800 sr->u.scan_response->num_diagnostics = 0;
802 case Z_SRW_update_request:
803 sr->u.update_request = (Z_SRW_updateRequest *)
804 odr_malloc(o, sizeof(*sr->u.update_request));
805 sr->u.update_request->database = 0;
806 sr->u.update_request->stylesheet = 0;
807 sr->u.update_request->record = 0;
808 sr->u.update_request->recordId = 0;
809 sr->u.update_request->recordVersions = 0;
810 sr->u.update_request->num_recordVersions = 0;
811 sr->u.update_request->extra_record = 0;
812 sr->u.update_request->extraRequestData_buf = 0;
813 sr->u.update_request->extraRequestData_len = 0;
814 sr->u.request->database = 0;
816 case Z_SRW_update_response:
817 sr->u.update_response = (Z_SRW_updateResponse *)
818 odr_malloc(o, sizeof(*sr->u.update_response));
819 sr->u.update_response->operationStatus = 0;
820 sr->u.update_response->recordId = 0;
821 sr->u.update_response->recordVersions = 0;
822 sr->u.update_response->num_recordVersions = 0;
823 sr->u.update_response->record = 0;
824 sr->u.update_response->extra_record = 0;
825 sr->u.update_response->extraResponseData_buf = 0;
826 sr->u.update_response->extraResponseData_len = 0;
827 sr->u.update_response->diagnostics = 0;
828 sr->u.update_response->num_diagnostics = 0;
834 static int bib1_srw_map[] = {
844 108, 10, /* Malformed query : Syntax error */
874 100, 1, /* bad map */
922 205, 1, /* bad map */
923 206, 1, /* bad map */
925 208, 1, /* bad map */
936 218, 1, /* bad map */
937 219, 1, /* bad map */
938 220, 1, /* bad map */
939 221, 1, /* bad map */
941 223, 1, /* bad map */
942 224, 1, /* bad map */
943 225, 1, /* bad map */
944 226, 1, /* bad map */
946 228, 1, /* bad map */
951 233, 1, /* bad map */
952 234, 1, /* bad map */
958 240, 1, /* bad map */
959 241, 1, /* bad map */
961 243, 1, /* bad map */
966 1001, 1, /* bad map */
967 1002, 1, /* bad map */
968 1003, 1, /* bad map */
969 1004, 1, /* bad map */
970 1005, 1, /* bad map */
971 1006, 1, /* bad map */
1004 * This array contains overrides for when the first occurrence of a
1005 * particular SRW error in the array above does not correspond with
1006 * the best back-translation of that SRW error.
1008 static int srw_bib1_map[] = {
1010 /* No doubt there are many more */
1015 int yaz_diag_bib1_to_srw (int code)
1017 const int *p = bib1_srw_map;
1027 int yaz_diag_srw_to_bib1(int code)
1029 /* Check explicit reverse-map first */
1030 const int *p = srw_bib1_map;
1038 /* Fall back on reverse lookup in main map */
1049 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1050 char *a_name, Odr_int *val)
1055 value[*i] = (char *) odr_malloc(o, 40);
1056 sprintf(value[*i], ODR_INT_PRINTF, *val);
1061 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1062 char *a_name, char *val)
1072 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1073 char **name, char **value, int max_names)
1076 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1077 name[i] = "operation";
1078 switch(srw_pdu->which)
1080 case Z_SRW_searchRetrieve_request:
1081 value[i++] = "searchRetrieve";
1082 switch(srw_pdu->u.request->query_type)
1084 case Z_SRW_query_type_cql:
1085 yaz_add_name_value_str(encode, name, value, &i, "query",
1086 srw_pdu->u.request->query.cql);
1088 case Z_SRW_query_type_pqf:
1089 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1090 srw_pdu->u.request->query.pqf);
1092 case Z_SRW_query_type_xcql:
1093 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1094 srw_pdu->u.request->query.xcql);
1097 switch(srw_pdu->u.request->sort_type)
1099 case Z_SRW_sort_type_none:
1101 case Z_SRW_sort_type_sort:
1102 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1103 srw_pdu->u.request->sort.sortKeys);
1106 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1107 srw_pdu->u.request->startRecord);
1108 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1109 srw_pdu->u.request->maximumRecords);
1110 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1111 srw_pdu->u.request->recordSchema);
1112 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1113 srw_pdu->u.request->recordPacking);
1114 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1115 srw_pdu->u.request->recordXPath);
1116 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1117 srw_pdu->u.request->stylesheet);
1118 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1119 srw_pdu->u.request->resultSetTTL);
1121 case Z_SRW_explain_request:
1122 value[i++] = "explain";
1123 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1124 srw_pdu->u.explain_request->stylesheet);
1126 case Z_SRW_scan_request:
1127 value[i++] = "scan";
1129 switch(srw_pdu->u.scan_request->query_type)
1131 case Z_SRW_query_type_cql:
1132 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1133 srw_pdu->u.scan_request->scanClause.cql);
1135 case Z_SRW_query_type_pqf:
1136 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1137 srw_pdu->u.scan_request->scanClause.pqf);
1139 case Z_SRW_query_type_xcql:
1140 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1141 srw_pdu->u.scan_request->scanClause.xcql);
1144 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1145 srw_pdu->u.scan_request->responsePosition);
1146 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1147 srw_pdu->u.scan_request->maximumTerms);
1148 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1149 srw_pdu->u.scan_request->stylesheet);
1151 case Z_SRW_update_request:
1152 value[i++] = "update";
1157 if (srw_pdu->extra_args)
1159 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1160 for (; ea && i < max_names-1; ea = ea->next)
1163 value[i] = ea->value;
1172 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1173 ODR encode, const char *charset)
1175 char *name[30], *value[30]; /* definite upper limit for SRU params */
1179 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1180 srw_pdu->username, srw_pdu->password);
1181 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1183 yaz_array_to_uri(&uri_args, encode, name, value);
1185 hreq->method = "GET";
1188 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1190 sprintf(path, "%s?%s", hreq->path, uri_args);
1193 z_HTTP_header_add_content_type(encode, &hreq->headers,
1194 "text/xml", charset);
1198 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1199 ODR encode, const char *charset)
1201 char *name[30], *value[30]; /* definite upper limit for SRU params */
1204 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1205 srw_pdu->username, srw_pdu->password);
1206 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1209 yaz_array_to_uri(&uri_args, encode, name, value);
1211 hreq->method = "POST";
1213 hreq->content_buf = uri_args;
1214 hreq->content_len = strlen(uri_args);
1216 z_HTTP_header_add_content_type(encode, &hreq->headers,
1217 "application/x-www-form-urlencoded",
1222 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1223 ODR odr, const char *charset)
1225 Z_SOAP_Handler handlers[3] = {
1227 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1228 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1232 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1234 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1235 srw_pdu->username, srw_pdu->password);
1236 z_HTTP_header_add_content_type(odr,
1238 "text/xml", charset);
1240 z_HTTP_header_add(odr, &hreq->headers,
1241 "SOAPAction", "\"\"");
1242 p->which = Z_SOAP_generic;
1243 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1244 p->u.generic->no = 0;
1245 p->u.generic->ns = 0;
1246 p->u.generic->p = srw_pdu;
1247 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1250 if (srw_pdu->which == Z_SRW_update_request ||
1251 srw_pdu->which == Z_SRW_update_response)
1252 p->u.generic->no = 1; /* second handler */
1254 return z_soap_codec_enc(odr, &p,
1256 &hreq->content_len, handlers,
1260 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1262 Z_SRW_recordVersion *ver
1263 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1265 for ( i=0; i < num; ++i ){
1266 ver[i].versionType = 0;
1267 ver[i].versionValue = 0;
1272 const char *yaz_srw_pack_to_str(int pack)
1276 case Z_SRW_recordPacking_string:
1278 case Z_SRW_recordPacking_XML:
1280 case Z_SRW_recordPacking_URL:
1286 int yaz_srw_str_to_pack(const char *str)
1288 if (!yaz_matchstr(str, "string"))
1289 return Z_SRW_recordPacking_string;
1290 if (!yaz_matchstr(str, "xml"))
1291 return Z_SRW_recordPacking_XML;
1292 if (!yaz_matchstr(str, "url"))
1293 return Z_SRW_recordPacking_URL;
1297 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1303 Z_SRW_extra_arg **ea = &sr->extra_args;
1304 yaz_uri_to_array(extra_args, odr, &name, &val);
1308 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1309 (*ea)->name = *name;
1310 (*ea)->value = *val;
1323 * c-file-style: "Stroustrup"
1324 * indent-tabs-mode: nil
1326 * vim: shiftwidth=4 tabstop=8 expandtab