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;
750 sr->u.request->facetList = 0;
752 case Z_SRW_searchRetrieve_response:
753 sr->u.response = (Z_SRW_searchRetrieveResponse *)
754 odr_malloc(o, sizeof(*sr->u.response));
755 sr->u.response->numberOfRecords = 0;
756 sr->u.response->resultSetId = 0;
757 sr->u.response->resultSetIdleTime = 0;
758 sr->u.response->records = 0;
759 sr->u.response->num_records = 0;
760 sr->u.response->diagnostics = 0;
761 sr->u.response->num_diagnostics = 0;
762 sr->u.response->nextRecordPosition = 0;
763 sr->u.response->extra_records = 0;
764 sr->u.response->facetList = 0;
766 case Z_SRW_explain_request:
767 sr->u.explain_request = (Z_SRW_explainRequest *)
768 odr_malloc(o, sizeof(*sr->u.explain_request));
769 sr->u.explain_request->recordPacking = 0;
770 sr->u.explain_request->database = 0;
771 sr->u.explain_request->stylesheet = 0;
773 case Z_SRW_explain_response:
774 sr->u.explain_response = (Z_SRW_explainResponse *)
775 odr_malloc(o, sizeof(*sr->u.explain_response));
776 sr->u.explain_response->record.recordData_buf = 0;
777 sr->u.explain_response->record.recordData_len = 0;
778 sr->u.explain_response->record.recordSchema = 0;
779 sr->u.explain_response->record.recordPosition = 0;
780 sr->u.explain_response->record.recordPacking =
781 Z_SRW_recordPacking_string;
782 sr->u.explain_response->diagnostics = 0;
783 sr->u.explain_response->num_diagnostics = 0;
784 sr->u.explain_response->extra_record = 0;
786 case Z_SRW_scan_request:
787 sr->u.scan_request = (Z_SRW_scanRequest *)
788 odr_malloc(o, sizeof(*sr->u.scan_request));
789 sr->u.scan_request->database = 0;
790 sr->u.scan_request->stylesheet = 0;
791 sr->u.scan_request->maximumTerms = 0;
792 sr->u.scan_request->responsePosition = 0;
793 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
794 sr->u.scan_request->scanClause.cql = 0;
796 case Z_SRW_scan_response:
797 sr->u.scan_response = (Z_SRW_scanResponse *)
798 odr_malloc(o, sizeof(*sr->u.scan_response));
799 sr->u.scan_response->terms = 0;
800 sr->u.scan_response->num_terms = 0;
801 sr->u.scan_response->diagnostics = 0;
802 sr->u.scan_response->num_diagnostics = 0;
804 case Z_SRW_update_request:
805 sr->u.update_request = (Z_SRW_updateRequest *)
806 odr_malloc(o, sizeof(*sr->u.update_request));
807 sr->u.update_request->database = 0;
808 sr->u.update_request->stylesheet = 0;
809 sr->u.update_request->record = 0;
810 sr->u.update_request->recordId = 0;
811 sr->u.update_request->recordVersions = 0;
812 sr->u.update_request->num_recordVersions = 0;
813 sr->u.update_request->extra_record = 0;
814 sr->u.update_request->extraRequestData_buf = 0;
815 sr->u.update_request->extraRequestData_len = 0;
816 sr->u.request->database = 0;
818 case Z_SRW_update_response:
819 sr->u.update_response = (Z_SRW_updateResponse *)
820 odr_malloc(o, sizeof(*sr->u.update_response));
821 sr->u.update_response->operationStatus = 0;
822 sr->u.update_response->recordId = 0;
823 sr->u.update_response->recordVersions = 0;
824 sr->u.update_response->num_recordVersions = 0;
825 sr->u.update_response->record = 0;
826 sr->u.update_response->extra_record = 0;
827 sr->u.update_response->extraResponseData_buf = 0;
828 sr->u.update_response->extraResponseData_len = 0;
829 sr->u.update_response->diagnostics = 0;
830 sr->u.update_response->num_diagnostics = 0;
836 static int bib1_srw_map[] = {
846 108, 10, /* Malformed query : Syntax error */
876 100, 1, /* bad map */
924 205, 1, /* bad map */
925 206, 1, /* bad map */
927 208, 1, /* bad map */
938 218, 1, /* bad map */
939 219, 1, /* bad map */
940 220, 1, /* bad map */
941 221, 1, /* bad map */
943 223, 1, /* bad map */
944 224, 1, /* bad map */
945 225, 1, /* bad map */
946 226, 1, /* bad map */
948 228, 1, /* bad map */
953 233, 1, /* bad map */
954 234, 1, /* bad map */
960 240, 1, /* bad map */
961 241, 1, /* bad map */
963 243, 1, /* bad map */
968 1001, 1, /* bad map */
969 1002, 1, /* bad map */
970 1003, 1, /* bad map */
971 1004, 1, /* bad map */
972 1005, 1, /* bad map */
973 1006, 1, /* bad map */
1006 * This array contains overrides for when the first occurrence of a
1007 * particular SRW error in the array above does not correspond with
1008 * the best back-translation of that SRW error.
1010 static int srw_bib1_map[] = {
1012 /* No doubt there are many more */
1017 int yaz_diag_bib1_to_srw (int code)
1019 const int *p = bib1_srw_map;
1029 int yaz_diag_srw_to_bib1(int code)
1031 /* Check explicit reverse-map first */
1032 const int *p = srw_bib1_map;
1040 /* Fall back on reverse lookup in main map */
1051 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1052 char *a_name, Odr_int *val)
1057 value[*i] = (char *) odr_malloc(o, 40);
1058 sprintf(value[*i], ODR_INT_PRINTF, *val);
1063 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1064 char *a_name, char *val)
1074 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1075 char **name, char **value, int max_names)
1078 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1079 name[i] = "operation";
1080 switch(srw_pdu->which)
1082 case Z_SRW_searchRetrieve_request:
1083 value[i++] = "searchRetrieve";
1084 switch(srw_pdu->u.request->query_type)
1086 case Z_SRW_query_type_cql:
1087 yaz_add_name_value_str(encode, name, value, &i, "query",
1088 srw_pdu->u.request->query.cql);
1090 case Z_SRW_query_type_pqf:
1091 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1092 srw_pdu->u.request->query.pqf);
1094 case Z_SRW_query_type_xcql:
1095 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1096 srw_pdu->u.request->query.xcql);
1099 switch(srw_pdu->u.request->sort_type)
1101 case Z_SRW_sort_type_none:
1103 case Z_SRW_sort_type_sort:
1104 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1105 srw_pdu->u.request->sort.sortKeys);
1108 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1109 srw_pdu->u.request->startRecord);
1110 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1111 srw_pdu->u.request->maximumRecords);
1112 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1113 srw_pdu->u.request->recordSchema);
1114 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1115 srw_pdu->u.request->recordPacking);
1116 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1117 srw_pdu->u.request->recordXPath);
1118 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1119 srw_pdu->u.request->stylesheet);
1120 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1121 srw_pdu->u.request->resultSetTTL);
1123 case Z_SRW_explain_request:
1124 value[i++] = "explain";
1125 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1126 srw_pdu->u.explain_request->stylesheet);
1128 case Z_SRW_scan_request:
1129 value[i++] = "scan";
1131 switch(srw_pdu->u.scan_request->query_type)
1133 case Z_SRW_query_type_cql:
1134 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1135 srw_pdu->u.scan_request->scanClause.cql);
1137 case Z_SRW_query_type_pqf:
1138 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1139 srw_pdu->u.scan_request->scanClause.pqf);
1141 case Z_SRW_query_type_xcql:
1142 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1143 srw_pdu->u.scan_request->scanClause.xcql);
1146 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1147 srw_pdu->u.scan_request->responsePosition);
1148 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1149 srw_pdu->u.scan_request->maximumTerms);
1150 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1151 srw_pdu->u.scan_request->stylesheet);
1153 case Z_SRW_update_request:
1154 value[i++] = "update";
1159 if (srw_pdu->extra_args)
1161 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1162 for (; ea && i < max_names-1; ea = ea->next)
1165 value[i] = ea->value;
1174 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1175 ODR encode, const char *charset)
1177 char *name[30], *value[30]; /* definite upper limit for SRU params */
1181 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1182 srw_pdu->username, srw_pdu->password);
1183 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1185 yaz_array_to_uri(&uri_args, encode, name, value);
1187 hreq->method = "GET";
1190 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1192 sprintf(path, "%s?%s", hreq->path, uri_args);
1195 z_HTTP_header_add_content_type(encode, &hreq->headers,
1196 "text/xml", charset);
1200 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1201 ODR encode, const char *charset)
1203 char *name[30], *value[30]; /* definite upper limit for SRU params */
1206 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1207 srw_pdu->username, srw_pdu->password);
1208 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1211 yaz_array_to_uri(&uri_args, encode, name, value);
1213 hreq->method = "POST";
1215 hreq->content_buf = uri_args;
1216 hreq->content_len = strlen(uri_args);
1218 z_HTTP_header_add_content_type(encode, &hreq->headers,
1219 "application/x-www-form-urlencoded",
1224 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1225 ODR odr, const char *charset)
1227 Z_SOAP_Handler handlers[3] = {
1229 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1230 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1234 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1236 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1237 srw_pdu->username, srw_pdu->password);
1238 z_HTTP_header_add_content_type(odr,
1240 "text/xml", charset);
1242 z_HTTP_header_add(odr, &hreq->headers,
1243 "SOAPAction", "\"\"");
1244 p->which = Z_SOAP_generic;
1245 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1246 p->u.generic->no = 0;
1247 p->u.generic->ns = 0;
1248 p->u.generic->p = srw_pdu;
1249 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1252 if (srw_pdu->which == Z_SRW_update_request ||
1253 srw_pdu->which == Z_SRW_update_response)
1254 p->u.generic->no = 1; /* second handler */
1256 return z_soap_codec_enc(odr, &p,
1258 &hreq->content_len, handlers,
1262 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1264 Z_SRW_recordVersion *ver
1265 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1267 for ( i=0; i < num; ++i ){
1268 ver[i].versionType = 0;
1269 ver[i].versionValue = 0;
1274 const char *yaz_srw_pack_to_str(int pack)
1278 case Z_SRW_recordPacking_string:
1280 case Z_SRW_recordPacking_XML:
1282 case Z_SRW_recordPacking_URL:
1288 int yaz_srw_str_to_pack(const char *str)
1290 if (!yaz_matchstr(str, "string"))
1291 return Z_SRW_recordPacking_string;
1292 if (!yaz_matchstr(str, "xml"))
1293 return Z_SRW_recordPacking_XML;
1294 if (!yaz_matchstr(str, "url"))
1295 return Z_SRW_recordPacking_URL;
1299 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1305 Z_SRW_extra_arg **ea = &sr->extra_args;
1306 yaz_uri_to_array(extra_args, odr, &name, &val);
1310 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1311 (*ea)->name = *name;
1312 (*ea)->value = *val;
1325 * c-file-style: "Stroustrup"
1326 * indent-tabs-mode: nil
1328 * vim: shiftwidth=4 tabstop=8 expandtab