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 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
18 return odr_strdupn(n, uri, len);
21 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
28 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
30 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
31 yaz_encode_sru_dbpath_buf(dst, db);
36 static int yaz_base64decode(const char *in, char *out)
38 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
39 "abcdefghijklmnopqrstuvwxyz0123456789+/";
48 if (!(p = strchr(map, in[0])))
52 if (!(p = strchr(map, in[1])))
56 *(out++) = i0 << 2 | i1 >> 4;
60 if (!(p = strchr(map, in[2])))
64 *(out++) = i1 << 4 | i2 >> 2;
68 if (!(p = strchr(map, in[3])))
72 *(out++) = i2 << 6 | i3;
83 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
85 const char *content_type = z_HTTP_header_lookup(hres->headers,
89 if (!yaz_strcmp_del("text/xml", content_type, "; "))
91 if (!yaz_strcmp_del("application/xml", content_type, "; "))
98 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
99 * parameters. Added by SH.
102 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
103 char *username, char *password, ODR decode)
105 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
108 sr->username = username;
110 sr->password = password;
115 char ubuf[256] = "", pbuf[256] = "", *p;
116 if (strncmp(basic, "Basic ", 6))
120 if (!len || len > 256)
122 olen = yaz_base64decode(basic, out);
123 /* Format of out should be username:password at this point */
125 if ((p = strchr(ubuf, ':'))) {
131 sr->username = odr_strdup(decode, ubuf);
133 sr->password = odr_strdup(decode, pbuf);
138 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
140 const char *v = yaz_uri_val(path, name, o);
142 *intp = odr_intdup(o, atoi(v));
145 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
146 const char *uri, const char *message,
149 d->uri = odr_strdup(o, uri);
151 d->message = odr_strdup(o, message);
155 d->details = odr_strdup(o, details);
160 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
161 int code, const char *details)
165 sprintf(uri, "info:srw/diagnostic/1/%d", code);
166 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
169 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
170 int *num, const char *uri,
171 const char *message, const char *details)
173 Z_SRW_diagnostic *d_new;
174 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
176 memcpy (d_new, *d, *num *sizeof(**d));
179 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
183 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
184 int *num, int code, const char *addinfo)
188 sprintf(uri, "info:srw/diagnostic/1/%d", code);
189 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
193 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
194 int *num, int code, const char *addinfo)
198 sprintf(uri, "info:srw/diagnostic/12/%d", code);
199 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
203 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
204 int code, const char *details)
206 const char *message = yaz_diag_srw_str(code);
209 len += strlen(message);
211 len += strlen(details);
213 record->recordData_buf = (char *) odr_malloc(o, len);
215 sprintf(record->recordData_buf, "<diagnostic "
216 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
217 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
219 sprintf(record->recordData_buf + strlen(record->recordData_buf),
220 " <details>%s</details>\n", details);
222 sprintf(record->recordData_buf + strlen(record->recordData_buf),
223 " <message>%s</message>\n", message);
224 sprintf(record->recordData_buf + strlen(record->recordData_buf),
226 record->recordData_len = strlen(record->recordData_buf);
227 record->recordPosition = odr_intdup(o, pos);
228 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
231 static void grab_charset(ODR o, const char *content_type, char **charset)
235 const char *charset_p = 0;
236 if (content_type && (charset_p = strstr(content_type, "; charset=")))
240 while (i < 20 && charset_p[i] &&
241 !strchr("; \n\r", charset_p[i]))
243 *charset = (char*) odr_malloc(o, i+1);
244 memcpy(*charset, charset_p, i);
245 (*charset)[i] = '\0';
250 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
251 Z_SOAP **soap_package, ODR decode, char **charset)
253 if (!strcmp(hreq->method, "POST"))
255 const char *content_type = z_HTTP_header_lookup(hreq->headers,
258 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
259 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
260 !yaz_strcmp_del("text/plain", content_type, "; ")))
262 char *db = "Default";
263 const char *p0 = hreq->path, *p1;
266 static Z_SOAP_Handler soap_handlers[4] = {
268 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
269 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
270 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
277 p1 = strchr(p0, '?');
279 p1 = p0 + strlen(p0);
281 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
282 grab_charset(decode, content_type, charset);
284 ret = z_soap_codec(decode, soap_package,
285 &hreq->content_buf, &hreq->content_len,
287 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
289 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
291 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
292 (*srw_pdu)->u.request->database == 0)
293 (*srw_pdu)->u.request->database = db;
295 if ((*srw_pdu)->which == Z_SRW_explain_request &&
296 (*srw_pdu)->u.explain_request->database == 0)
297 (*srw_pdu)->u.explain_request->database = db;
299 if ((*srw_pdu)->which == Z_SRW_scan_request &&
300 (*srw_pdu)->u.scan_request->database == 0)
301 (*srw_pdu)->u.scan_request->database = db;
303 if ((*srw_pdu)->which == Z_SRW_update_request &&
304 (*srw_pdu)->u.update_request->database == 0)
305 (*srw_pdu)->u.update_request->database = db;
316 static int yaz_sru_decode_integer(ODR odr, const char *pname,
317 const char *valstr, Odr_int **valp,
318 Z_SRW_diagnostic **diag, int *num_diag,
324 if (sscanf(valstr, "%d", &ival) != 1)
326 yaz_add_srw_diagnostic(odr, diag, num_diag,
327 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
330 if (min_value >= 0 && ival < min_value)
332 yaz_add_srw_diagnostic(odr, diag, num_diag,
333 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
336 *valp = odr_intdup(odr, ival);
342 http://www.loc.gov/z3950/agency/zing/srw/service.html
344 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
345 Z_SOAP **soap_package, ODR decode, char **charset,
346 Z_SRW_diagnostic **diag, int *num_diag)
349 static Z_SOAP_Handler soap_handlers[2] = {
350 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
354 const char *content_type = z_HTTP_header_lookup(hreq->headers,
358 SRU GET: ignore content type.
359 SRU POST: we support "application/x-www-form-urlencoded";
360 not "multipart/form-data" .
362 if (!strcmp(hreq->method, "GET")
364 (!strcmp(hreq->method, "POST") && content_type &&
365 !yaz_strcmp_del("application/x-www-form-urlencoded",
366 content_type, "; ")))
368 char *db = "Default";
369 const char *p0 = hreq->path, *p1;
371 const char *operation = 0;
378 char *stylesheet = 0;
379 char *scanClause = 0;
380 char *pScanClause = 0;
381 char *recordXPath = 0;
382 char *recordSchema = 0;
383 char *recordPacking = "xml"; /* xml packing is default for SRU */
384 char *maximumRecords = 0;
385 char *startRecord = 0;
386 char *maximumTerms = 0;
387 char *responsePosition = 0;
388 char *extraRequestData = 0;
389 Z_SRW_extra_arg *extra_args = 0;
394 grab_charset(decode, content_type, charset);
395 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
400 p1 = strchr(p0, '?');
402 p1 = p0 + strlen(p0);
404 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
405 if (!strcmp(hreq->method, "POST"))
406 p1 = hreq->content_buf;
407 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
412 for (i = 0; uri_name[i]; i++)
414 char *n = uri_name[i];
415 char *v = uri_val[i];
416 if (!strcmp(n, "query"))
418 else if (!strcmp(n, "x-pquery"))
420 else if (!strcmp(n, "x-username"))
422 else if (!strcmp(n, "x-password"))
424 else if (!strcmp(n, "operation"))
426 else if (!strcmp(n, "stylesheet"))
428 else if (!strcmp(n, "sortKeys"))
430 else if (!strcmp(n, "recordXPath"))
432 else if (!strcmp(n, "recordSchema"))
434 else if (!strcmp(n, "recordPacking"))
436 else if (!strcmp(n, "version"))
438 else if (!strcmp(n, "scanClause"))
440 else if (!strcmp(n, "x-pScanClause"))
442 else if (!strcmp(n, "maximumRecords"))
444 else if (!strcmp(n, "startRecord"))
446 else if (!strcmp(n, "maximumTerms"))
448 else if (!strcmp(n, "responsePosition"))
449 responsePosition = v;
450 else if (!strcmp(n, "extraRequestData"))
451 extraRequestData = v;
452 else if (n[0] == 'x' && n[1] == '-')
454 Z_SRW_extra_arg **l = &extra_args;
457 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
458 (*l)->name = odr_strdup(decode, n);
459 (*l)->value = odr_strdup(decode, v);
463 yaz_add_srw_diagnostic(decode, diag, num_diag,
464 YAZ_SRW_UNSUPP_PARAMETER, n);
470 yaz_add_srw_diagnostic(
471 decode, diag, num_diag,
472 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
476 version = yaz_negotiate_sru_version(version);
479 { /* negotiation failed. */
480 yaz_add_srw_diagnostic(decode, diag, num_diag,
481 YAZ_SRW_UNSUPP_VERSION, "1.2");
488 yaz_add_srw_diagnostic(
489 decode, diag, num_diag,
490 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
491 operation = "explain";
493 if (!strcmp(operation, "searchRetrieve"))
495 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
497 sr->srw_version = version;
498 sr->extra_args = extra_args;
500 yaz_srw_decodeauth(sr, hreq, username, password, decode);
503 sr->u.request->query_type = Z_SRW_query_type_cql;
504 sr->u.request->query.cql = query;
508 sr->u.request->query_type = Z_SRW_query_type_pqf;
509 sr->u.request->query.pqf = pQuery;
512 yaz_add_srw_diagnostic(
513 decode, diag, num_diag,
514 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
518 sr->u.request->sort_type = Z_SRW_sort_type_sort;
519 sr->u.request->sort.sortKeys = sortKeys;
521 sr->u.request->recordXPath = recordXPath;
522 sr->u.request->recordSchema = recordSchema;
523 sr->u.request->recordPacking = recordPacking;
524 sr->u.request->stylesheet = stylesheet;
526 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
527 &sr->u.request->maximumRecords,
530 yaz_sru_decode_integer(decode, "startRecord", startRecord,
531 &sr->u.request->startRecord,
534 sr->u.request->database = db;
536 (*soap_package) = (Z_SOAP *)
537 odr_malloc(decode, sizeof(**soap_package));
538 (*soap_package)->which = Z_SOAP_generic;
540 (*soap_package)->u.generic = (Z_SOAP_Generic *)
541 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
543 (*soap_package)->u.generic->p = sr;
544 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
545 (*soap_package)->u.generic->no = 0;
547 (*soap_package)->ns = "SRU";
551 else if (!strcmp(operation, "explain"))
553 /* Transfer SRU explain parameters to common struct */
554 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
555 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
557 sr->srw_version = version;
558 sr->extra_args = extra_args;
559 yaz_srw_decodeauth(sr, hreq, username, password, decode);
561 sr->u.explain_request->recordPacking = recordPacking;
562 sr->u.explain_request->database = db;
564 sr->u.explain_request->stylesheet = stylesheet;
566 (*soap_package) = (Z_SOAP *)
567 odr_malloc(decode, sizeof(**soap_package));
568 (*soap_package)->which = Z_SOAP_generic;
570 (*soap_package)->u.generic = (Z_SOAP_Generic *)
571 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
573 (*soap_package)->u.generic->p = sr;
574 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
575 (*soap_package)->u.generic->no = 0;
577 (*soap_package)->ns = "SRU";
581 else if (!strcmp(operation, "scan"))
583 /* Transfer SRU scan parameters to common struct */
584 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
585 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
587 sr->srw_version = version;
588 sr->extra_args = extra_args;
590 yaz_srw_decodeauth(sr, hreq, username, password, decode);
594 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
595 sr->u.scan_request->scanClause.cql = scanClause;
597 else if (pScanClause)
599 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
600 sr->u.scan_request->scanClause.pqf = pScanClause;
603 yaz_add_srw_diagnostic(
604 decode, diag, num_diag,
605 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
606 sr->u.scan_request->database = db;
608 yaz_sru_decode_integer(decode, "maximumTerms",
610 &sr->u.scan_request->maximumTerms,
613 yaz_sru_decode_integer(decode, "responsePosition",
615 &sr->u.scan_request->responsePosition,
618 sr->u.scan_request->stylesheet = stylesheet;
620 (*soap_package) = (Z_SOAP *)
621 odr_malloc(decode, sizeof(**soap_package));
622 (*soap_package)->which = Z_SOAP_generic;
624 (*soap_package)->u.generic = (Z_SOAP_Generic *)
625 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
627 (*soap_package)->u.generic->p = sr;
628 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
629 (*soap_package)->u.generic->no = 0;
631 (*soap_package)->ns = "SRU";
637 /* unsupported operation ... */
638 /* Act as if we received a explain request and throw diagnostic. */
640 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
642 sr->srw_version = version;
644 sr->u.explain_request->recordPacking = recordPacking;
645 sr->u.explain_request->database = db;
647 sr->u.explain_request->stylesheet = stylesheet;
649 (*soap_package) = (Z_SOAP *)
650 odr_malloc(decode, sizeof(**soap_package));
651 (*soap_package)->which = Z_SOAP_generic;
653 (*soap_package)->u.generic = (Z_SOAP_Generic *)
654 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
656 (*soap_package)->u.generic->p = sr;
657 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
658 (*soap_package)->u.generic->no = 0;
660 (*soap_package)->ns = "SRU";
662 yaz_add_srw_diagnostic(decode, diag, num_diag,
663 YAZ_SRW_UNSUPP_OPERATION, operation);
672 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
674 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
675 odr_malloc(o, sizeof(*res));
677 res->extraRecordData_buf = 0;
678 res->extraRecordData_len = 0;
679 res->recordIdentifier = 0;
684 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
686 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
689 for (i = 0; i<n; i++)
691 res[i].recordSchema = 0;
692 res[i].recordPacking = Z_SRW_recordPacking_string;
693 res[i].recordData_buf = 0;
694 res[i].recordData_len = 0;
695 res[i].recordPosition = 0;
700 Z_SRW_record *yaz_srw_get_record(ODR o)
702 return yaz_srw_get_records(o, 1);
705 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
707 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
708 p->srw_version = odr_strdup(o, version);
712 p->extraResponseData_buf = 0;
713 p->extraResponseData_len = 0;
717 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
719 return yaz_srw_get_core_ver(o, "1.1");
722 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
724 return yaz_srw_get_pdu(o, which, "1.1");
727 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
729 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
734 case Z_SRW_searchRetrieve_request:
735 sr->u.request = (Z_SRW_searchRetrieveRequest *)
736 odr_malloc(o, sizeof(*sr->u.request));
737 sr->u.request->query_type = Z_SRW_query_type_cql;
738 sr->u.request->query.cql = 0;
739 sr->u.request->sort_type = Z_SRW_sort_type_none;
740 sr->u.request->sort.none = 0;
741 sr->u.request->startRecord = 0;
742 sr->u.request->maximumRecords = 0;
743 sr->u.request->recordSchema = 0;
744 sr->u.request->recordPacking = 0;
745 sr->u.request->recordXPath = 0;
746 sr->u.request->database = 0;
747 sr->u.request->resultSetTTL = 0;
748 sr->u.request->stylesheet = 0;
750 case Z_SRW_searchRetrieve_response:
751 sr->u.response = (Z_SRW_searchRetrieveResponse *)
752 odr_malloc(o, sizeof(*sr->u.response));
753 sr->u.response->numberOfRecords = 0;
754 sr->u.response->resultSetId = 0;
755 sr->u.response->resultSetIdleTime = 0;
756 sr->u.response->records = 0;
757 sr->u.response->num_records = 0;
758 sr->u.response->diagnostics = 0;
759 sr->u.response->num_diagnostics = 0;
760 sr->u.response->nextRecordPosition = 0;
761 sr->u.response->extra_records = 0;
763 case Z_SRW_explain_request:
764 sr->u.explain_request = (Z_SRW_explainRequest *)
765 odr_malloc(o, sizeof(*sr->u.explain_request));
766 sr->u.explain_request->recordPacking = 0;
767 sr->u.explain_request->database = 0;
768 sr->u.explain_request->stylesheet = 0;
770 case Z_SRW_explain_response:
771 sr->u.explain_response = (Z_SRW_explainResponse *)
772 odr_malloc(o, sizeof(*sr->u.explain_response));
773 sr->u.explain_response->record.recordData_buf = 0;
774 sr->u.explain_response->record.recordData_len = 0;
775 sr->u.explain_response->record.recordSchema = 0;
776 sr->u.explain_response->record.recordPosition = 0;
777 sr->u.explain_response->record.recordPacking =
778 Z_SRW_recordPacking_string;
779 sr->u.explain_response->diagnostics = 0;
780 sr->u.explain_response->num_diagnostics = 0;
781 sr->u.explain_response->extra_record = 0;
783 case Z_SRW_scan_request:
784 sr->u.scan_request = (Z_SRW_scanRequest *)
785 odr_malloc(o, sizeof(*sr->u.scan_request));
786 sr->u.scan_request->database = 0;
787 sr->u.scan_request->stylesheet = 0;
788 sr->u.scan_request->maximumTerms = 0;
789 sr->u.scan_request->responsePosition = 0;
790 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
791 sr->u.scan_request->scanClause.cql = 0;
793 case Z_SRW_scan_response:
794 sr->u.scan_response = (Z_SRW_scanResponse *)
795 odr_malloc(o, sizeof(*sr->u.scan_response));
796 sr->u.scan_response->terms = 0;
797 sr->u.scan_response->num_terms = 0;
798 sr->u.scan_response->diagnostics = 0;
799 sr->u.scan_response->num_diagnostics = 0;
801 case Z_SRW_update_request:
802 sr->u.update_request = (Z_SRW_updateRequest *)
803 odr_malloc(o, sizeof(*sr->u.update_request));
804 sr->u.update_request->database = 0;
805 sr->u.update_request->stylesheet = 0;
806 sr->u.update_request->record = 0;
807 sr->u.update_request->recordId = 0;
808 sr->u.update_request->recordVersions = 0;
809 sr->u.update_request->num_recordVersions = 0;
810 sr->u.update_request->extra_record = 0;
811 sr->u.update_request->extraRequestData_buf = 0;
812 sr->u.update_request->extraRequestData_len = 0;
813 sr->u.request->database = 0;
815 case Z_SRW_update_response:
816 sr->u.update_response = (Z_SRW_updateResponse *)
817 odr_malloc(o, sizeof(*sr->u.update_response));
818 sr->u.update_response->operationStatus = 0;
819 sr->u.update_response->recordId = 0;
820 sr->u.update_response->recordVersions = 0;
821 sr->u.update_response->num_recordVersions = 0;
822 sr->u.update_response->record = 0;
823 sr->u.update_response->extra_record = 0;
824 sr->u.update_response->extraResponseData_buf = 0;
825 sr->u.update_response->extraResponseData_len = 0;
826 sr->u.update_response->diagnostics = 0;
827 sr->u.update_response->num_diagnostics = 0;
833 static int bib1_srw_map[] = {
843 108, 10, /* Malformed query : Syntax error */
873 100, 1, /* bad map */
921 205, 1, /* bad map */
922 206, 1, /* bad map */
924 208, 1, /* bad map */
935 218, 1, /* bad map */
936 219, 1, /* bad map */
937 220, 1, /* bad map */
938 221, 1, /* bad map */
940 223, 1, /* bad map */
941 224, 1, /* bad map */
942 225, 1, /* bad map */
943 226, 1, /* bad map */
945 228, 1, /* bad map */
950 233, 1, /* bad map */
951 234, 1, /* bad map */
957 240, 1, /* bad map */
958 241, 1, /* bad map */
960 243, 1, /* bad map */
965 1001, 1, /* bad map */
966 1002, 1, /* bad map */
967 1003, 1, /* bad map */
968 1004, 1, /* bad map */
969 1005, 1, /* bad map */
970 1006, 1, /* bad map */
1003 * This array contains overrides for when the first occurrence of a
1004 * particular SRW error in the array above does not correspond with
1005 * the best back-translation of that SRW error.
1007 static int srw_bib1_map[] = {
1009 /* No doubt there are many more */
1014 int yaz_diag_bib1_to_srw (int code)
1016 const int *p = bib1_srw_map;
1026 int yaz_diag_srw_to_bib1(int code)
1028 /* Check explicit reverse-map first */
1029 const int *p = srw_bib1_map;
1037 /* Fall back on reverse lookup in main map */
1048 static void add_val_int(ODR o, char **name, char **value, int *i,
1049 char *a_name, Odr_int *val)
1054 value[*i] = (char *) odr_malloc(o, 40);
1055 sprintf(value[*i], ODR_INT_PRINTF, *val);
1060 static void add_val_str(ODR o, char **name, char **value, int *i,
1061 char *a_name, char *val)
1071 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1072 char **name, char **value, int max_names)
1075 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1076 name[i] = "operation";
1077 switch(srw_pdu->which)
1079 case Z_SRW_searchRetrieve_request:
1080 value[i++] = "searchRetrieve";
1081 switch(srw_pdu->u.request->query_type)
1083 case Z_SRW_query_type_cql:
1084 add_val_str(encode, name, value, &i, "query",
1085 srw_pdu->u.request->query.cql);
1087 case Z_SRW_query_type_pqf:
1088 add_val_str(encode, name, value, &i, "x-pquery",
1089 srw_pdu->u.request->query.pqf);
1091 case Z_SRW_query_type_xcql:
1092 add_val_str(encode, name, value, &i, "x-cql",
1093 srw_pdu->u.request->query.xcql);
1096 switch(srw_pdu->u.request->sort_type)
1098 case Z_SRW_sort_type_none:
1100 case Z_SRW_sort_type_sort:
1101 add_val_str(encode, name, value, &i, "sortKeys",
1102 srw_pdu->u.request->sort.sortKeys);
1105 add_val_int(encode, name, value, &i, "startRecord",
1106 srw_pdu->u.request->startRecord);
1107 add_val_int(encode, name, value, &i, "maximumRecords",
1108 srw_pdu->u.request->maximumRecords);
1109 add_val_str(encode, name, value, &i, "recordSchema",
1110 srw_pdu->u.request->recordSchema);
1111 add_val_str(encode, name, value, &i, "recordPacking",
1112 srw_pdu->u.request->recordPacking);
1113 add_val_str(encode, name, value, &i, "recordXPath",
1114 srw_pdu->u.request->recordXPath);
1115 add_val_str(encode, name, value, &i, "stylesheet",
1116 srw_pdu->u.request->stylesheet);
1117 add_val_int(encode, name, value, &i, "resultSetTTL",
1118 srw_pdu->u.request->resultSetTTL);
1120 case Z_SRW_explain_request:
1121 value[i++] = "explain";
1122 add_val_str(encode, name, value, &i, "stylesheet",
1123 srw_pdu->u.explain_request->stylesheet);
1125 case Z_SRW_scan_request:
1126 value[i++] = "scan";
1128 switch(srw_pdu->u.scan_request->query_type)
1130 case Z_SRW_query_type_cql:
1131 add_val_str(encode, name, value, &i, "scanClause",
1132 srw_pdu->u.scan_request->scanClause.cql);
1134 case Z_SRW_query_type_pqf:
1135 add_val_str(encode, name, value, &i, "x-pScanClause",
1136 srw_pdu->u.scan_request->scanClause.pqf);
1138 case Z_SRW_query_type_xcql:
1139 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1140 srw_pdu->u.scan_request->scanClause.xcql);
1143 add_val_int(encode, name, value, &i, "responsePosition",
1144 srw_pdu->u.scan_request->responsePosition);
1145 add_val_int(encode, name, value, &i, "maximumTerms",
1146 srw_pdu->u.scan_request->maximumTerms);
1147 add_val_str(encode, name, value, &i, "stylesheet",
1148 srw_pdu->u.scan_request->stylesheet);
1150 case Z_SRW_update_request:
1151 value[i++] = "update";
1156 if (srw_pdu->extra_args)
1158 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1159 for (; ea && i < max_names-1; ea = ea->next)
1162 value[i] = ea->value;
1171 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1172 ODR encode, const char *charset)
1174 char *name[30], *value[30]; /* definite upper limit for SRU params */
1178 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1179 srw_pdu->username, srw_pdu->password);
1180 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1182 yaz_array_to_uri(&uri_args, encode, name, value);
1184 hreq->method = "GET";
1187 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1189 sprintf(path, "%s?%s", hreq->path, uri_args);
1192 z_HTTP_header_add_content_type(encode, &hreq->headers,
1193 "text/xml", charset);
1197 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1198 ODR encode, const char *charset)
1200 char *name[30], *value[30]; /* definite upper limit for SRU params */
1203 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1204 srw_pdu->username, srw_pdu->password);
1205 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1208 yaz_array_to_uri(&uri_args, encode, name, value);
1210 hreq->method = "POST";
1212 hreq->content_buf = uri_args;
1213 hreq->content_len = strlen(uri_args);
1215 z_HTTP_header_add_content_type(encode, &hreq->headers,
1216 "application/x-www-form-urlencoded",
1221 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1222 ODR odr, const char *charset)
1224 Z_SOAP_Handler handlers[3] = {
1226 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1227 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1231 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1233 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1234 srw_pdu->username, srw_pdu->password);
1235 z_HTTP_header_add_content_type(odr,
1237 "text/xml", charset);
1239 z_HTTP_header_add(odr, &hreq->headers,
1240 "SOAPAction", "\"\"");
1241 p->which = Z_SOAP_generic;
1242 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1243 p->u.generic->no = 0;
1244 p->u.generic->ns = 0;
1245 p->u.generic->p = srw_pdu;
1246 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1249 if (srw_pdu->which == Z_SRW_update_request ||
1250 srw_pdu->which == Z_SRW_update_response)
1251 p->u.generic->no = 1; /* second handler */
1253 return z_soap_codec_enc(odr, &p,
1255 &hreq->content_len, handlers,
1259 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1261 Z_SRW_recordVersion *ver
1262 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1264 for ( i=0; i < num; ++i ){
1265 ver[i].versionType = 0;
1266 ver[i].versionValue = 0;
1271 const char *yaz_srw_pack_to_str(int pack)
1275 case Z_SRW_recordPacking_string:
1277 case Z_SRW_recordPacking_XML:
1279 case Z_SRW_recordPacking_URL:
1285 int yaz_srw_str_to_pack(const char *str)
1287 if (!yaz_matchstr(str, "string"))
1288 return Z_SRW_recordPacking_string;
1289 if (!yaz_matchstr(str, "xml"))
1290 return Z_SRW_recordPacking_XML;
1291 if (!yaz_matchstr(str, "url"))
1292 return Z_SRW_recordPacking_URL;
1296 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1302 Z_SRW_extra_arg **ea = &sr->extra_args;
1303 yaz_uri_to_array(extra_args, odr, &name, &val);
1307 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1308 (*ea)->name = *name;
1309 (*ea)->value = *val;
1322 * c-file-style: "Stroustrup"
1323 * indent-tabs-mode: nil
1325 * vim: shiftwidth=4 tabstop=8 expandtab