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>
16 /** \brief decodes HTTP path (which should hold SRU database)
17 \param n memory for returned result
18 \param uri URI path (up to but not including ?)
19 \param len URI len (up to but not including ?)
20 \returns ODR allocated database
22 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
24 char *ret = odr_malloc(n, strlen(uri) + 1);
25 yaz_decode_uri_component(ret, uri, len);
29 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
33 yaz_encode_uri_component(dst+1, db);
36 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
38 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
39 yaz_encode_sru_dbpath_buf(dst, db);
44 static int yaz_base64decode(const char *in, char *out)
46 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
47 "abcdefghijklmnopqrstuvwxyz0123456789+/";
56 if (!(p = strchr(map, in[0])))
60 if (!(p = strchr(map, in[1])))
64 *(out++) = i0 << 2 | i1 >> 4;
68 if (!(p = strchr(map, in[2])))
72 *(out++) = i1 << 4 | i2 >> 2;
76 if (!(p = strchr(map, in[3])))
80 *(out++) = i2 << 6 | i3;
91 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
93 const char *content_type = z_HTTP_header_lookup(hres->headers,
97 if (!yaz_strcmp_del("text/xml", content_type, "; "))
99 if (!yaz_strcmp_del("application/xml", content_type, "; "))
106 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
107 * parameters. Added by SH.
110 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
111 char *username, char *password, ODR decode)
113 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
116 sr->username = username;
118 sr->password = password;
123 char ubuf[256] = "", pbuf[256] = "", *p;
124 if (strncmp(basic, "Basic ", 6))
128 if (!len || len > 256)
130 olen = yaz_base64decode(basic, out);
131 /* Format of out should be username:password at this point */
133 if ((p = strchr(ubuf, ':'))) {
139 sr->username = odr_strdup(decode, ubuf);
141 sr->password = odr_strdup(decode, pbuf);
146 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
148 const char *v = yaz_uri_val(path, name, o);
150 *intp = odr_intdup(o, atoi(v));
153 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
154 const char *uri, const char *message,
157 d->uri = odr_strdup(o, uri);
159 d->message = odr_strdup(o, message);
163 d->details = odr_strdup(o, details);
168 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
169 int code, const char *details)
173 sprintf(uri, "info:srw/diagnostic/1/%d", code);
174 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
177 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
178 int *num, const char *uri,
179 const char *message, const char *details)
181 Z_SRW_diagnostic *d_new;
182 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
184 memcpy (d_new, *d, *num *sizeof(**d));
187 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
191 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
192 int *num, int code, const char *addinfo)
196 sprintf(uri, "info:srw/diagnostic/1/%d", code);
197 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
201 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
202 int *num, int code, const char *addinfo)
206 sprintf(uri, "info:srw/diagnostic/12/%d", code);
207 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
211 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
212 int code, const char *details)
214 const char *message = yaz_diag_srw_str(code);
217 len += strlen(message);
219 len += strlen(details);
221 record->recordData_buf = (char *) odr_malloc(o, len);
223 sprintf(record->recordData_buf, "<diagnostic "
224 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
225 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
227 sprintf(record->recordData_buf + strlen(record->recordData_buf),
228 " <details>%s</details>\n", details);
230 sprintf(record->recordData_buf + strlen(record->recordData_buf),
231 " <message>%s</message>\n", message);
232 sprintf(record->recordData_buf + strlen(record->recordData_buf),
234 record->recordData_len = strlen(record->recordData_buf);
235 record->recordPosition = odr_intdup(o, pos);
236 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
239 static void grab_charset(ODR o, const char *content_type, char **charset)
243 const char *charset_p = 0;
244 if (content_type && (charset_p = strstr(content_type, "; charset=")))
248 while (i < 20 && charset_p[i] &&
249 !strchr("; \n\r", charset_p[i]))
251 *charset = (char*) odr_malloc(o, i+1);
252 memcpy(*charset, charset_p, i);
253 (*charset)[i] = '\0';
258 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
259 Z_SOAP **soap_package, ODR decode, char **charset)
261 if (!strcmp(hreq->method, "POST"))
263 const char *content_type = z_HTTP_header_lookup(hreq->headers,
266 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
267 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
268 !yaz_strcmp_del("text/plain", content_type, "; ")))
270 char *db = "Default";
271 const char *p0 = hreq->path, *p1;
274 static Z_SOAP_Handler soap_handlers[4] = {
276 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
277 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
278 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
285 p1 = strchr(p0, '?');
287 p1 = p0 + strlen(p0);
289 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
290 grab_charset(decode, content_type, charset);
292 ret = z_soap_codec(decode, soap_package,
293 &hreq->content_buf, &hreq->content_len,
295 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
297 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
299 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
300 (*srw_pdu)->u.request->database == 0)
301 (*srw_pdu)->u.request->database = db;
303 if ((*srw_pdu)->which == Z_SRW_explain_request &&
304 (*srw_pdu)->u.explain_request->database == 0)
305 (*srw_pdu)->u.explain_request->database = db;
307 if ((*srw_pdu)->which == Z_SRW_scan_request &&
308 (*srw_pdu)->u.scan_request->database == 0)
309 (*srw_pdu)->u.scan_request->database = db;
311 if ((*srw_pdu)->which == Z_SRW_update_request &&
312 (*srw_pdu)->u.update_request->database == 0)
313 (*srw_pdu)->u.update_request->database = db;
324 static int yaz_sru_decode_integer(ODR odr, const char *pname,
325 const char *valstr, Odr_int **valp,
326 Z_SRW_diagnostic **diag, int *num_diag,
332 if (sscanf(valstr, "%d", &ival) != 1)
334 yaz_add_srw_diagnostic(odr, diag, num_diag,
335 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
338 if (min_value >= 0 && ival < min_value)
340 yaz_add_srw_diagnostic(odr, diag, num_diag,
341 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
344 *valp = odr_intdup(odr, ival);
350 http://www.loc.gov/z3950/agency/zing/srw/service.html
352 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
353 Z_SOAP **soap_package, ODR decode, char **charset,
354 Z_SRW_diagnostic **diag, int *num_diag)
357 static Z_SOAP_Handler soap_handlers[2] = {
358 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
362 const char *content_type = z_HTTP_header_lookup(hreq->headers,
366 SRU GET: ignore content type.
367 SRU POST: we support "application/x-www-form-urlencoded";
368 not "multipart/form-data" .
370 if (!strcmp(hreq->method, "GET")
372 (!strcmp(hreq->method, "POST") && content_type &&
373 !yaz_strcmp_del("application/x-www-form-urlencoded",
374 content_type, "; ")))
376 char *db = "Default";
377 const char *p0 = hreq->path, *p1;
379 const char *operation = 0;
386 char *stylesheet = 0;
387 char *scanClause = 0;
388 char *pScanClause = 0;
389 char *recordXPath = 0;
390 char *recordSchema = 0;
391 char *recordPacking = "xml"; /* xml packing is default for SRU */
392 char *maximumRecords = 0;
393 char *startRecord = 0;
394 char *maximumTerms = 0;
395 char *responsePosition = 0;
396 char *extraRequestData = 0;
397 Z_SRW_extra_arg *extra_args = 0;
402 grab_charset(decode, content_type, charset);
403 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
408 p1 = strchr(p0, '?');
410 p1 = p0 + strlen(p0);
412 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
413 if (!strcmp(hreq->method, "POST"))
414 p1 = hreq->content_buf;
415 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
420 for (i = 0; uri_name[i]; i++)
422 char *n = uri_name[i];
423 char *v = uri_val[i];
424 if (!strcmp(n, "query"))
426 else if (!strcmp(n, "x-pquery"))
428 else if (!strcmp(n, "x-username"))
430 else if (!strcmp(n, "x-password"))
432 else if (!strcmp(n, "operation"))
434 else if (!strcmp(n, "stylesheet"))
436 else if (!strcmp(n, "sortKeys"))
438 else if (!strcmp(n, "recordXPath"))
440 else if (!strcmp(n, "recordSchema"))
442 else if (!strcmp(n, "recordPacking"))
444 else if (!strcmp(n, "version"))
446 else if (!strcmp(n, "scanClause"))
448 else if (!strcmp(n, "x-pScanClause"))
450 else if (!strcmp(n, "maximumRecords"))
452 else if (!strcmp(n, "startRecord"))
454 else if (!strcmp(n, "maximumTerms"))
456 else if (!strcmp(n, "responsePosition"))
457 responsePosition = v;
458 else if (!strcmp(n, "extraRequestData"))
459 extraRequestData = v;
460 else if (n[0] == 'x' && n[1] == '-')
462 Z_SRW_extra_arg **l = &extra_args;
465 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
466 (*l)->name = odr_strdup(decode, n);
467 (*l)->value = odr_strdup(decode, v);
471 yaz_add_srw_diagnostic(decode, diag, num_diag,
472 YAZ_SRW_UNSUPP_PARAMETER, n);
478 yaz_add_srw_diagnostic(
479 decode, diag, num_diag,
480 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
484 version = yaz_negotiate_sru_version(version);
487 { /* negotiation failed. */
488 yaz_add_srw_diagnostic(decode, diag, num_diag,
489 YAZ_SRW_UNSUPP_VERSION, "1.2");
496 yaz_add_srw_diagnostic(
497 decode, diag, num_diag,
498 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
499 operation = "explain";
501 if (!strcmp(operation, "searchRetrieve"))
503 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
505 sr->srw_version = version;
506 sr->extra_args = extra_args;
508 yaz_srw_decodeauth(sr, hreq, username, password, decode);
511 sr->u.request->query_type = Z_SRW_query_type_cql;
512 sr->u.request->query.cql = query;
516 sr->u.request->query_type = Z_SRW_query_type_pqf;
517 sr->u.request->query.pqf = pQuery;
520 yaz_add_srw_diagnostic(
521 decode, diag, num_diag,
522 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
526 sr->u.request->sort_type = Z_SRW_sort_type_sort;
527 sr->u.request->sort.sortKeys = sortKeys;
529 sr->u.request->recordXPath = recordXPath;
530 sr->u.request->recordSchema = recordSchema;
531 sr->u.request->recordPacking = recordPacking;
532 sr->u.request->stylesheet = stylesheet;
534 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
535 &sr->u.request->maximumRecords,
538 yaz_sru_decode_integer(decode, "startRecord", startRecord,
539 &sr->u.request->startRecord,
542 sr->u.request->database = db;
544 (*soap_package) = (Z_SOAP *)
545 odr_malloc(decode, sizeof(**soap_package));
546 (*soap_package)->which = Z_SOAP_generic;
548 (*soap_package)->u.generic = (Z_SOAP_Generic *)
549 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
551 (*soap_package)->u.generic->p = sr;
552 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
553 (*soap_package)->u.generic->no = 0;
555 (*soap_package)->ns = "SRU";
559 else if (!strcmp(operation, "explain"))
561 /* Transfer SRU explain parameters to common struct */
562 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
563 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
565 sr->srw_version = version;
566 sr->extra_args = extra_args;
567 yaz_srw_decodeauth(sr, hreq, username, password, decode);
569 sr->u.explain_request->recordPacking = recordPacking;
570 sr->u.explain_request->database = db;
572 sr->u.explain_request->stylesheet = stylesheet;
574 (*soap_package) = (Z_SOAP *)
575 odr_malloc(decode, sizeof(**soap_package));
576 (*soap_package)->which = Z_SOAP_generic;
578 (*soap_package)->u.generic = (Z_SOAP_Generic *)
579 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
581 (*soap_package)->u.generic->p = sr;
582 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
583 (*soap_package)->u.generic->no = 0;
585 (*soap_package)->ns = "SRU";
589 else if (!strcmp(operation, "scan"))
591 /* Transfer SRU scan parameters to common struct */
592 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
593 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
595 sr->srw_version = version;
596 sr->extra_args = extra_args;
598 yaz_srw_decodeauth(sr, hreq, username, password, decode);
602 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
603 sr->u.scan_request->scanClause.cql = scanClause;
605 else if (pScanClause)
607 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
608 sr->u.scan_request->scanClause.pqf = pScanClause;
611 yaz_add_srw_diagnostic(
612 decode, diag, num_diag,
613 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
614 sr->u.scan_request->database = db;
616 yaz_sru_decode_integer(decode, "maximumTerms",
618 &sr->u.scan_request->maximumTerms,
621 yaz_sru_decode_integer(decode, "responsePosition",
623 &sr->u.scan_request->responsePosition,
626 sr->u.scan_request->stylesheet = stylesheet;
628 (*soap_package) = (Z_SOAP *)
629 odr_malloc(decode, sizeof(**soap_package));
630 (*soap_package)->which = Z_SOAP_generic;
632 (*soap_package)->u.generic = (Z_SOAP_Generic *)
633 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
635 (*soap_package)->u.generic->p = sr;
636 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
637 (*soap_package)->u.generic->no = 0;
639 (*soap_package)->ns = "SRU";
645 /* unsupported operation ... */
646 /* Act as if we received a explain request and throw diagnostic. */
648 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
650 sr->srw_version = version;
652 sr->u.explain_request->recordPacking = recordPacking;
653 sr->u.explain_request->database = db;
655 sr->u.explain_request->stylesheet = stylesheet;
657 (*soap_package) = (Z_SOAP *)
658 odr_malloc(decode, sizeof(**soap_package));
659 (*soap_package)->which = Z_SOAP_generic;
661 (*soap_package)->u.generic = (Z_SOAP_Generic *)
662 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
664 (*soap_package)->u.generic->p = sr;
665 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
666 (*soap_package)->u.generic->no = 0;
668 (*soap_package)->ns = "SRU";
670 yaz_add_srw_diagnostic(decode, diag, num_diag,
671 YAZ_SRW_UNSUPP_OPERATION, operation);
680 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
682 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
683 odr_malloc(o, sizeof(*res));
685 res->extraRecordData_buf = 0;
686 res->extraRecordData_len = 0;
687 res->recordIdentifier = 0;
692 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
694 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
697 for (i = 0; i<n; i++)
699 res[i].recordSchema = 0;
700 res[i].recordPacking = Z_SRW_recordPacking_string;
701 res[i].recordData_buf = 0;
702 res[i].recordData_len = 0;
703 res[i].recordPosition = 0;
708 Z_SRW_record *yaz_srw_get_record(ODR o)
710 return yaz_srw_get_records(o, 1);
713 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
715 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
716 p->srw_version = odr_strdup(o, version);
720 p->extraResponseData_buf = 0;
721 p->extraResponseData_len = 0;
725 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
727 return yaz_srw_get_core_ver(o, "1.1");
730 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
732 return yaz_srw_get_pdu(o, which, "1.1");
735 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
737 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
742 case Z_SRW_searchRetrieve_request:
743 sr->u.request = (Z_SRW_searchRetrieveRequest *)
744 odr_malloc(o, sizeof(*sr->u.request));
745 sr->u.request->query_type = Z_SRW_query_type_cql;
746 sr->u.request->query.cql = 0;
747 sr->u.request->sort_type = Z_SRW_sort_type_none;
748 sr->u.request->sort.none = 0;
749 sr->u.request->startRecord = 0;
750 sr->u.request->maximumRecords = 0;
751 sr->u.request->recordSchema = 0;
752 sr->u.request->recordPacking = 0;
753 sr->u.request->recordXPath = 0;
754 sr->u.request->database = 0;
755 sr->u.request->resultSetTTL = 0;
756 sr->u.request->stylesheet = 0;
758 case Z_SRW_searchRetrieve_response:
759 sr->u.response = (Z_SRW_searchRetrieveResponse *)
760 odr_malloc(o, sizeof(*sr->u.response));
761 sr->u.response->numberOfRecords = 0;
762 sr->u.response->resultSetId = 0;
763 sr->u.response->resultSetIdleTime = 0;
764 sr->u.response->records = 0;
765 sr->u.response->num_records = 0;
766 sr->u.response->diagnostics = 0;
767 sr->u.response->num_diagnostics = 0;
768 sr->u.response->nextRecordPosition = 0;
769 sr->u.response->extra_records = 0;
771 case Z_SRW_explain_request:
772 sr->u.explain_request = (Z_SRW_explainRequest *)
773 odr_malloc(o, sizeof(*sr->u.explain_request));
774 sr->u.explain_request->recordPacking = 0;
775 sr->u.explain_request->database = 0;
776 sr->u.explain_request->stylesheet = 0;
778 case Z_SRW_explain_response:
779 sr->u.explain_response = (Z_SRW_explainResponse *)
780 odr_malloc(o, sizeof(*sr->u.explain_response));
781 sr->u.explain_response->record.recordData_buf = 0;
782 sr->u.explain_response->record.recordData_len = 0;
783 sr->u.explain_response->record.recordSchema = 0;
784 sr->u.explain_response->record.recordPosition = 0;
785 sr->u.explain_response->record.recordPacking =
786 Z_SRW_recordPacking_string;
787 sr->u.explain_response->diagnostics = 0;
788 sr->u.explain_response->num_diagnostics = 0;
789 sr->u.explain_response->extra_record = 0;
791 case Z_SRW_scan_request:
792 sr->u.scan_request = (Z_SRW_scanRequest *)
793 odr_malloc(o, sizeof(*sr->u.scan_request));
794 sr->u.scan_request->database = 0;
795 sr->u.scan_request->stylesheet = 0;
796 sr->u.scan_request->maximumTerms = 0;
797 sr->u.scan_request->responsePosition = 0;
798 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
799 sr->u.scan_request->scanClause.cql = 0;
801 case Z_SRW_scan_response:
802 sr->u.scan_response = (Z_SRW_scanResponse *)
803 odr_malloc(o, sizeof(*sr->u.scan_response));
804 sr->u.scan_response->terms = 0;
805 sr->u.scan_response->num_terms = 0;
806 sr->u.scan_response->diagnostics = 0;
807 sr->u.scan_response->num_diagnostics = 0;
809 case Z_SRW_update_request:
810 sr->u.update_request = (Z_SRW_updateRequest *)
811 odr_malloc(o, sizeof(*sr->u.update_request));
812 sr->u.update_request->database = 0;
813 sr->u.update_request->stylesheet = 0;
814 sr->u.update_request->record = 0;
815 sr->u.update_request->recordId = 0;
816 sr->u.update_request->recordVersions = 0;
817 sr->u.update_request->num_recordVersions = 0;
818 sr->u.update_request->extra_record = 0;
819 sr->u.update_request->extraRequestData_buf = 0;
820 sr->u.update_request->extraRequestData_len = 0;
821 sr->u.request->database = 0;
823 case Z_SRW_update_response:
824 sr->u.update_response = (Z_SRW_updateResponse *)
825 odr_malloc(o, sizeof(*sr->u.update_response));
826 sr->u.update_response->operationStatus = 0;
827 sr->u.update_response->recordId = 0;
828 sr->u.update_response->recordVersions = 0;
829 sr->u.update_response->num_recordVersions = 0;
830 sr->u.update_response->record = 0;
831 sr->u.update_response->extra_record = 0;
832 sr->u.update_response->extraResponseData_buf = 0;
833 sr->u.update_response->extraResponseData_len = 0;
834 sr->u.update_response->diagnostics = 0;
835 sr->u.update_response->num_diagnostics = 0;
841 static int bib1_srw_map[] = {
851 108, 10, /* Malformed query : Syntax error */
881 100, 1, /* bad map */
929 205, 1, /* bad map */
930 206, 1, /* bad map */
932 208, 1, /* bad map */
943 218, 1, /* bad map */
944 219, 1, /* bad map */
945 220, 1, /* bad map */
946 221, 1, /* bad map */
948 223, 1, /* bad map */
949 224, 1, /* bad map */
950 225, 1, /* bad map */
951 226, 1, /* bad map */
953 228, 1, /* bad map */
958 233, 1, /* bad map */
959 234, 1, /* bad map */
965 240, 1, /* bad map */
966 241, 1, /* bad map */
968 243, 1, /* bad map */
973 1001, 1, /* bad map */
974 1002, 1, /* bad map */
975 1003, 1, /* bad map */
976 1004, 1, /* bad map */
977 1005, 1, /* bad map */
978 1006, 1, /* bad map */
1011 * This array contains overrides for when the first occurrence of a
1012 * particular SRW error in the array above does not correspond with
1013 * the best back-translation of that SRW error.
1015 static int srw_bib1_map[] = {
1017 /* No doubt there are many more */
1022 int yaz_diag_bib1_to_srw (int code)
1024 const int *p = bib1_srw_map;
1034 int yaz_diag_srw_to_bib1(int code)
1036 /* Check explicit reverse-map first */
1037 const int *p = srw_bib1_map;
1045 /* Fall back on reverse lookup in main map */
1056 static void add_val_int(ODR o, char **name, char **value, int *i,
1057 char *a_name, Odr_int *val)
1062 value[*i] = (char *) odr_malloc(o, 40);
1063 sprintf(value[*i], ODR_INT_PRINTF, *val);
1068 static void add_val_str(ODR o, char **name, char **value, int *i,
1069 char *a_name, char *val)
1079 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1080 char **name, char **value, int max_names)
1083 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1084 name[i] = "operation";
1085 switch(srw_pdu->which)
1087 case Z_SRW_searchRetrieve_request:
1088 value[i++] = "searchRetrieve";
1089 switch(srw_pdu->u.request->query_type)
1091 case Z_SRW_query_type_cql:
1092 add_val_str(encode, name, value, &i, "query",
1093 srw_pdu->u.request->query.cql);
1095 case Z_SRW_query_type_pqf:
1096 add_val_str(encode, name, value, &i, "x-pquery",
1097 srw_pdu->u.request->query.pqf);
1099 case Z_SRW_query_type_xcql:
1100 add_val_str(encode, name, value, &i, "x-cql",
1101 srw_pdu->u.request->query.xcql);
1104 switch(srw_pdu->u.request->sort_type)
1106 case Z_SRW_sort_type_none:
1108 case Z_SRW_sort_type_sort:
1109 add_val_str(encode, name, value, &i, "sortKeys",
1110 srw_pdu->u.request->sort.sortKeys);
1113 add_val_int(encode, name, value, &i, "startRecord",
1114 srw_pdu->u.request->startRecord);
1115 add_val_int(encode, name, value, &i, "maximumRecords",
1116 srw_pdu->u.request->maximumRecords);
1117 add_val_str(encode, name, value, &i, "recordSchema",
1118 srw_pdu->u.request->recordSchema);
1119 add_val_str(encode, name, value, &i, "recordPacking",
1120 srw_pdu->u.request->recordPacking);
1121 add_val_str(encode, name, value, &i, "recordXPath",
1122 srw_pdu->u.request->recordXPath);
1123 add_val_str(encode, name, value, &i, "stylesheet",
1124 srw_pdu->u.request->stylesheet);
1125 add_val_int(encode, name, value, &i, "resultSetTTL",
1126 srw_pdu->u.request->resultSetTTL);
1128 case Z_SRW_explain_request:
1129 value[i++] = "explain";
1130 add_val_str(encode, name, value, &i, "stylesheet",
1131 srw_pdu->u.explain_request->stylesheet);
1133 case Z_SRW_scan_request:
1134 value[i++] = "scan";
1136 switch(srw_pdu->u.scan_request->query_type)
1138 case Z_SRW_query_type_cql:
1139 add_val_str(encode, name, value, &i, "scanClause",
1140 srw_pdu->u.scan_request->scanClause.cql);
1142 case Z_SRW_query_type_pqf:
1143 add_val_str(encode, name, value, &i, "x-pScanClause",
1144 srw_pdu->u.scan_request->scanClause.pqf);
1146 case Z_SRW_query_type_xcql:
1147 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1148 srw_pdu->u.scan_request->scanClause.xcql);
1151 add_val_int(encode, name, value, &i, "responsePosition",
1152 srw_pdu->u.scan_request->responsePosition);
1153 add_val_int(encode, name, value, &i, "maximumTerms",
1154 srw_pdu->u.scan_request->maximumTerms);
1155 add_val_str(encode, name, value, &i, "stylesheet",
1156 srw_pdu->u.scan_request->stylesheet);
1158 case Z_SRW_update_request:
1159 value[i++] = "update";
1164 if (srw_pdu->extra_args)
1166 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1167 for (; ea && i < max_names-1; ea = ea->next)
1170 value[i] = ea->value;
1179 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1180 ODR encode, const char *charset)
1182 char *name[30], *value[30]; /* definite upper limit for SRU params */
1186 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1187 srw_pdu->username, srw_pdu->password);
1188 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1190 yaz_array_to_uri(&uri_args, encode, name, value);
1192 hreq->method = "GET";
1195 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1197 sprintf(path, "%s?%s", hreq->path, uri_args);
1200 z_HTTP_header_add_content_type(encode, &hreq->headers,
1201 "text/xml", charset);
1205 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1206 ODR encode, const char *charset)
1208 char *name[30], *value[30]; /* definite upper limit for SRU params */
1211 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1212 srw_pdu->username, srw_pdu->password);
1213 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1216 yaz_array_to_uri(&uri_args, encode, name, value);
1218 hreq->method = "POST";
1220 hreq->content_buf = uri_args;
1221 hreq->content_len = strlen(uri_args);
1223 z_HTTP_header_add_content_type(encode, &hreq->headers,
1224 "application/x-www-form-urlencoded",
1229 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1230 ODR odr, const char *charset)
1232 Z_SOAP_Handler handlers[3] = {
1234 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1235 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1239 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1241 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1242 srw_pdu->username, srw_pdu->password);
1243 z_HTTP_header_add_content_type(odr,
1245 "text/xml", charset);
1247 z_HTTP_header_add(odr, &hreq->headers,
1248 "SOAPAction", "\"\"");
1249 p->which = Z_SOAP_generic;
1250 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1251 p->u.generic->no = 0;
1252 p->u.generic->ns = 0;
1253 p->u.generic->p = srw_pdu;
1254 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1257 if (srw_pdu->which == Z_SRW_update_request ||
1258 srw_pdu->which == Z_SRW_update_response)
1259 p->u.generic->no = 1; /* second handler */
1261 return z_soap_codec_enc(odr, &p,
1263 &hreq->content_len, handlers,
1267 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1269 Z_SRW_recordVersion *ver
1270 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1272 for ( i=0; i < num; ++i ){
1273 ver[i].versionType = 0;
1274 ver[i].versionValue = 0;
1279 const char *yaz_srw_pack_to_str(int pack)
1283 case Z_SRW_recordPacking_string:
1285 case Z_SRW_recordPacking_XML:
1287 case Z_SRW_recordPacking_URL:
1293 int yaz_srw_str_to_pack(const char *str)
1295 if (!yaz_matchstr(str, "string"))
1296 return Z_SRW_recordPacking_string;
1297 if (!yaz_matchstr(str, "xml"))
1298 return Z_SRW_recordPacking_XML;
1299 if (!yaz_matchstr(str, "url"))
1300 return Z_SRW_recordPacking_URL;
1304 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1310 Z_SRW_extra_arg **ea = &sr->extra_args;
1311 yaz_uri_to_array(extra_args, odr, &name, &val);
1315 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1316 (*ea)->name = *name;
1317 (*ea)->value = *val;
1330 * c-file-style: "Stroustrup"
1331 * indent-tabs-mode: nil
1333 * vim: shiftwidth=4 tabstop=8 expandtab