1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2009 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SRW/SRU utilities.
12 #include <yaz/matchstr.h>
13 #include <yaz/yaz-iconv.h>
16 static int yaz_base64decode(const char *in, char *out)
18 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
19 "abcdefghijklmnopqrstuvwxyz0123456789+/";
28 if (!(p = strchr(map, in[0])))
32 if (!(p = strchr(map, in[1])))
36 *(out++) = i0 << 2 | i1 >> 4;
40 if (!(p = strchr(map, in[2])))
44 *(out++) = i1 << 4 | i2 >> 2;
48 if (!(p = strchr(map, in[3])))
52 *(out++) = i2 << 6 | i3;
63 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
65 const char *content_type = z_HTTP_header_lookup(hres->headers,
69 if (!yaz_strcmp_del("text/xml", content_type, "; "))
71 if (!yaz_strcmp_del("application/xml", content_type, "; "))
78 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
79 * parameters. Added by SH.
82 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
83 char *username, char *password, ODR decode)
85 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
88 sr->username = username;
90 sr->password = password;
95 char ubuf[256] = "", pbuf[256] = "", *p;
96 if (strncmp(basic, "Basic ", 6))
100 if (!len || len > 256)
102 olen = yaz_base64decode(basic, out);
103 /* Format of out should be username:password at this point */
105 if ((p = strchr(ubuf, ':'))) {
111 sr->username = odr_strdup(decode, ubuf);
113 sr->password = odr_strdup(decode, pbuf);
118 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
120 const char *v = yaz_uri_val(path, name, o);
122 *intp = odr_intdup(o, atoi(v));
125 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
126 const char *uri, const char *message,
129 d->uri = odr_strdup(o, uri);
131 d->message = odr_strdup(o, message);
135 d->details = odr_strdup(o, details);
140 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
141 int code, const char *details)
145 sprintf(uri, "info:srw/diagnostic/1/%d", code);
146 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
149 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
150 int *num, const char *uri,
151 const char *message, const char *details)
153 Z_SRW_diagnostic *d_new;
154 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
156 memcpy (d_new, *d, *num *sizeof(**d));
159 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
163 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
164 int *num, int code, const char *addinfo)
168 sprintf(uri, "info:srw/diagnostic/1/%d", code);
169 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
173 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
174 int *num, int code, const char *addinfo)
178 sprintf(uri, "info:srw/diagnostic/12/%d", code);
179 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
183 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
184 int code, const char *details)
186 const char *message = yaz_diag_srw_str(code);
189 len += strlen(message);
191 len += strlen(details);
193 record->recordData_buf = (char *) odr_malloc(o, len);
195 sprintf(record->recordData_buf, "<diagnostic "
196 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
197 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
199 sprintf(record->recordData_buf + strlen(record->recordData_buf),
200 " <details>%s</details>\n", details);
202 sprintf(record->recordData_buf + strlen(record->recordData_buf),
203 " <message>%s</message>\n", message);
204 sprintf(record->recordData_buf + strlen(record->recordData_buf),
206 record->recordData_len = strlen(record->recordData_buf);
207 record->recordPosition = odr_intdup(o, pos);
208 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
211 static void grab_charset(ODR o, const char *content_type, char **charset)
215 const char *charset_p = 0;
216 if (content_type && (charset_p = strstr(content_type, "; charset=")))
220 while (i < 20 && charset_p[i] &&
221 !strchr("; \n\r", charset_p[i]))
223 *charset = (char*) odr_malloc(o, i+1);
224 memcpy(*charset, charset_p, i);
225 (*charset)[i] = '\0';
230 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
231 Z_SOAP **soap_package, ODR decode, char **charset)
233 if (!strcmp(hreq->method, "POST"))
235 const char *content_type = z_HTTP_header_lookup(hreq->headers,
238 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
239 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
240 !yaz_strcmp_del("text/plain", content_type, "; ")))
242 char *db = "Default";
243 const char *p0 = hreq->path, *p1;
246 static Z_SOAP_Handler soap_handlers[4] = {
248 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
249 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
250 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
257 p1 = strchr(p0, '?');
259 p1 = p0 + strlen(p0);
262 db = (char*) odr_malloc(decode, p1 - p0 + 1);
263 memcpy (db, p0, p1 - p0);
267 grab_charset(decode, content_type, charset);
269 ret = z_soap_codec(decode, soap_package,
270 &hreq->content_buf, &hreq->content_len,
272 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
274 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
276 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
277 (*srw_pdu)->u.request->database == 0)
278 (*srw_pdu)->u.request->database = db;
280 if ((*srw_pdu)->which == Z_SRW_explain_request &&
281 (*srw_pdu)->u.explain_request->database == 0)
282 (*srw_pdu)->u.explain_request->database = db;
284 if ((*srw_pdu)->which == Z_SRW_scan_request &&
285 (*srw_pdu)->u.scan_request->database == 0)
286 (*srw_pdu)->u.scan_request->database = db;
288 if ((*srw_pdu)->which == Z_SRW_update_request &&
289 (*srw_pdu)->u.update_request->database == 0)
290 (*srw_pdu)->u.update_request->database = db;
301 static int yaz_sru_decode_integer(ODR odr, const char *pname,
302 const char *valstr, Odr_int **valp,
303 Z_SRW_diagnostic **diag, int *num_diag,
309 if (sscanf(valstr, "%d", &ival) != 1)
311 yaz_add_srw_diagnostic(odr, diag, num_diag,
312 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
315 if (min_value >= 0 && ival < min_value)
317 yaz_add_srw_diagnostic(odr, diag, num_diag,
318 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
321 *valp = odr_intdup(odr, ival);
327 http://www.loc.gov/z3950/agency/zing/srw/service.html
329 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
330 Z_SOAP **soap_package, ODR decode, char **charset,
331 Z_SRW_diagnostic **diag, int *num_diag)
334 static Z_SOAP_Handler soap_handlers[2] = {
335 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
339 const char *content_type = z_HTTP_header_lookup(hreq->headers,
343 SRU GET: ignore content type.
344 SRU POST: we support "application/x-www-form-urlencoded";
345 not "multipart/form-data" .
347 if (!strcmp(hreq->method, "GET")
349 (!strcmp(hreq->method, "POST") && content_type &&
350 !yaz_strcmp_del("application/x-www-form-urlencoded",
351 content_type, "; ")))
353 char *db = "Default";
354 const char *p0 = hreq->path, *p1;
356 const char *operation = 0;
363 char *stylesheet = 0;
364 char *scanClause = 0;
365 char *pScanClause = 0;
366 char *recordXPath = 0;
367 char *recordSchema = 0;
368 char *recordPacking = "xml"; /* xml packing is default for SRU */
369 char *maximumRecords = 0;
370 char *startRecord = 0;
371 char *maximumTerms = 0;
372 char *responsePosition = 0;
373 char *extraRequestData = 0;
374 Z_SRW_extra_arg *extra_args = 0;
379 grab_charset(decode, content_type, charset);
380 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
385 p1 = strchr(p0, '?');
387 p1 = p0 + strlen(p0);
390 db = (char*) odr_malloc(decode, p1 - p0 + 1);
391 memcpy (db, p0, p1 - p0);
394 if (!strcmp(hreq->method, "POST"))
395 p1 = hreq->content_buf;
396 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
401 for (i = 0; uri_name[i]; i++)
403 char *n = uri_name[i];
404 char *v = uri_val[i];
405 if (!strcmp(n, "query"))
407 else if (!strcmp(n, "x-pquery"))
409 else if (!strcmp(n, "x-username"))
411 else if (!strcmp(n, "x-password"))
413 else if (!strcmp(n, "operation"))
415 else if (!strcmp(n, "stylesheet"))
417 else if (!strcmp(n, "sortKeys"))
419 else if (!strcmp(n, "recordXPath"))
421 else if (!strcmp(n, "recordSchema"))
423 else if (!strcmp(n, "recordPacking"))
425 else if (!strcmp(n, "version"))
427 else if (!strcmp(n, "scanClause"))
429 else if (!strcmp(n, "x-pScanClause"))
431 else if (!strcmp(n, "maximumRecords"))
433 else if (!strcmp(n, "startRecord"))
435 else if (!strcmp(n, "maximumTerms"))
437 else if (!strcmp(n, "responsePosition"))
438 responsePosition = v;
439 else if (!strcmp(n, "extraRequestData"))
440 extraRequestData = v;
441 else if (n[0] == 'x' && n[1] == '-')
443 Z_SRW_extra_arg **l = &extra_args;
446 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
447 (*l)->name = odr_strdup(decode, n);
448 (*l)->value = odr_strdup(decode, v);
452 yaz_add_srw_diagnostic(decode, diag, num_diag,
453 YAZ_SRW_UNSUPP_PARAMETER, n);
459 yaz_add_srw_diagnostic(
460 decode, diag, num_diag,
461 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
465 version = yaz_negotiate_sru_version(version);
468 { /* negotiation failed. */
469 yaz_add_srw_diagnostic(decode, diag, num_diag,
470 YAZ_SRW_UNSUPP_VERSION, "1.2");
477 yaz_add_srw_diagnostic(
478 decode, diag, num_diag,
479 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
480 operation = "explain";
482 if (!strcmp(operation, "searchRetrieve"))
484 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
486 sr->srw_version = version;
487 sr->extra_args = extra_args;
489 yaz_srw_decodeauth(sr, hreq, username, password, decode);
492 sr->u.request->query_type = Z_SRW_query_type_cql;
493 sr->u.request->query.cql = query;
497 sr->u.request->query_type = Z_SRW_query_type_pqf;
498 sr->u.request->query.pqf = pQuery;
501 yaz_add_srw_diagnostic(
502 decode, diag, num_diag,
503 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
507 sr->u.request->sort_type = Z_SRW_sort_type_sort;
508 sr->u.request->sort.sortKeys = sortKeys;
510 sr->u.request->recordXPath = recordXPath;
511 sr->u.request->recordSchema = recordSchema;
512 sr->u.request->recordPacking = recordPacking;
513 sr->u.request->stylesheet = stylesheet;
515 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
516 &sr->u.request->maximumRecords,
519 yaz_sru_decode_integer(decode, "startRecord", startRecord,
520 &sr->u.request->startRecord,
523 sr->u.request->database = db;
525 (*soap_package) = (Z_SOAP *)
526 odr_malloc(decode, sizeof(**soap_package));
527 (*soap_package)->which = Z_SOAP_generic;
529 (*soap_package)->u.generic = (Z_SOAP_Generic *)
530 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
532 (*soap_package)->u.generic->p = sr;
533 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
534 (*soap_package)->u.generic->no = 0;
536 (*soap_package)->ns = "SRU";
540 else if (!strcmp(operation, "explain"))
542 /* Transfer SRU explain parameters to common struct */
543 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
544 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
546 sr->srw_version = version;
547 sr->extra_args = extra_args;
548 yaz_srw_decodeauth(sr, hreq, username, password, decode);
550 sr->u.explain_request->recordPacking = recordPacking;
551 sr->u.explain_request->database = db;
553 sr->u.explain_request->stylesheet = stylesheet;
555 (*soap_package) = (Z_SOAP *)
556 odr_malloc(decode, sizeof(**soap_package));
557 (*soap_package)->which = Z_SOAP_generic;
559 (*soap_package)->u.generic = (Z_SOAP_Generic *)
560 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
562 (*soap_package)->u.generic->p = sr;
563 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
564 (*soap_package)->u.generic->no = 0;
566 (*soap_package)->ns = "SRU";
570 else if (!strcmp(operation, "scan"))
572 /* Transfer SRU scan parameters to common struct */
573 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
574 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
576 sr->srw_version = version;
577 sr->extra_args = extra_args;
579 yaz_srw_decodeauth(sr, hreq, username, password, decode);
583 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
584 sr->u.scan_request->scanClause.cql = scanClause;
586 else if (pScanClause)
588 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
589 sr->u.scan_request->scanClause.pqf = pScanClause;
592 yaz_add_srw_diagnostic(
593 decode, diag, num_diag,
594 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
595 sr->u.scan_request->database = db;
597 yaz_sru_decode_integer(decode, "maximumTerms",
599 &sr->u.scan_request->maximumTerms,
602 yaz_sru_decode_integer(decode, "responsePosition",
604 &sr->u.scan_request->responsePosition,
607 sr->u.scan_request->stylesheet = stylesheet;
609 (*soap_package) = (Z_SOAP *)
610 odr_malloc(decode, sizeof(**soap_package));
611 (*soap_package)->which = Z_SOAP_generic;
613 (*soap_package)->u.generic = (Z_SOAP_Generic *)
614 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
616 (*soap_package)->u.generic->p = sr;
617 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
618 (*soap_package)->u.generic->no = 0;
620 (*soap_package)->ns = "SRU";
626 /* unsupported operation ... */
627 /* Act as if we received a explain request and throw diagnostic. */
629 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
631 sr->srw_version = version;
633 sr->u.explain_request->recordPacking = recordPacking;
634 sr->u.explain_request->database = db;
636 sr->u.explain_request->stylesheet = stylesheet;
638 (*soap_package) = (Z_SOAP *)
639 odr_malloc(decode, sizeof(**soap_package));
640 (*soap_package)->which = Z_SOAP_generic;
642 (*soap_package)->u.generic = (Z_SOAP_Generic *)
643 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
645 (*soap_package)->u.generic->p = sr;
646 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
647 (*soap_package)->u.generic->no = 0;
649 (*soap_package)->ns = "SRU";
651 yaz_add_srw_diagnostic(decode, diag, num_diag,
652 YAZ_SRW_UNSUPP_OPERATION, operation);
661 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
663 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
664 odr_malloc(o, sizeof(*res));
666 res->extraRecordData_buf = 0;
667 res->extraRecordData_len = 0;
668 res->recordIdentifier = 0;
673 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
675 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
678 for (i = 0; i<n; i++)
680 res[i].recordSchema = 0;
681 res[i].recordPacking = Z_SRW_recordPacking_string;
682 res[i].recordData_buf = 0;
683 res[i].recordData_len = 0;
684 res[i].recordPosition = 0;
689 Z_SRW_record *yaz_srw_get_record(ODR o)
691 return yaz_srw_get_records(o, 1);
694 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
696 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
697 p->srw_version = odr_strdup(o, version);
701 p->extraResponseData_buf = 0;
702 p->extraResponseData_len = 0;
706 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
708 return yaz_srw_get_core_ver(o, "1.1");
711 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
713 return yaz_srw_get_pdu(o, which, "1.1");
716 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
718 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
723 case Z_SRW_searchRetrieve_request:
724 sr->u.request = (Z_SRW_searchRetrieveRequest *)
725 odr_malloc(o, sizeof(*sr->u.request));
726 sr->u.request->query_type = Z_SRW_query_type_cql;
727 sr->u.request->query.cql = 0;
728 sr->u.request->sort_type = Z_SRW_sort_type_none;
729 sr->u.request->sort.none = 0;
730 sr->u.request->startRecord = 0;
731 sr->u.request->maximumRecords = 0;
732 sr->u.request->recordSchema = 0;
733 sr->u.request->recordPacking = 0;
734 sr->u.request->recordXPath = 0;
735 sr->u.request->database = 0;
736 sr->u.request->resultSetTTL = 0;
737 sr->u.request->stylesheet = 0;
739 case Z_SRW_searchRetrieve_response:
740 sr->u.response = (Z_SRW_searchRetrieveResponse *)
741 odr_malloc(o, sizeof(*sr->u.response));
742 sr->u.response->numberOfRecords = 0;
743 sr->u.response->resultSetId = 0;
744 sr->u.response->resultSetIdleTime = 0;
745 sr->u.response->records = 0;
746 sr->u.response->num_records = 0;
747 sr->u.response->diagnostics = 0;
748 sr->u.response->num_diagnostics = 0;
749 sr->u.response->nextRecordPosition = 0;
750 sr->u.response->extra_records = 0;
752 case Z_SRW_explain_request:
753 sr->u.explain_request = (Z_SRW_explainRequest *)
754 odr_malloc(o, sizeof(*sr->u.explain_request));
755 sr->u.explain_request->recordPacking = 0;
756 sr->u.explain_request->database = 0;
757 sr->u.explain_request->stylesheet = 0;
759 case Z_SRW_explain_response:
760 sr->u.explain_response = (Z_SRW_explainResponse *)
761 odr_malloc(o, sizeof(*sr->u.explain_response));
762 sr->u.explain_response->record.recordData_buf = 0;
763 sr->u.explain_response->record.recordData_len = 0;
764 sr->u.explain_response->record.recordSchema = 0;
765 sr->u.explain_response->record.recordPosition = 0;
766 sr->u.explain_response->record.recordPacking =
767 Z_SRW_recordPacking_string;
768 sr->u.explain_response->diagnostics = 0;
769 sr->u.explain_response->num_diagnostics = 0;
770 sr->u.explain_response->extra_record = 0;
772 case Z_SRW_scan_request:
773 sr->u.scan_request = (Z_SRW_scanRequest *)
774 odr_malloc(o, sizeof(*sr->u.scan_request));
775 sr->u.scan_request->database = 0;
776 sr->u.scan_request->stylesheet = 0;
777 sr->u.scan_request->maximumTerms = 0;
778 sr->u.scan_request->responsePosition = 0;
779 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
780 sr->u.scan_request->scanClause.cql = 0;
782 case Z_SRW_scan_response:
783 sr->u.scan_response = (Z_SRW_scanResponse *)
784 odr_malloc(o, sizeof(*sr->u.scan_response));
785 sr->u.scan_response->terms = 0;
786 sr->u.scan_response->num_terms = 0;
787 sr->u.scan_response->diagnostics = 0;
788 sr->u.scan_response->num_diagnostics = 0;
790 case Z_SRW_update_request:
791 sr->u.update_request = (Z_SRW_updateRequest *)
792 odr_malloc(o, sizeof(*sr->u.update_request));
793 sr->u.update_request->database = 0;
794 sr->u.update_request->stylesheet = 0;
795 sr->u.update_request->record = 0;
796 sr->u.update_request->recordId = 0;
797 sr->u.update_request->recordVersions = 0;
798 sr->u.update_request->num_recordVersions = 0;
799 sr->u.update_request->extra_record = 0;
800 sr->u.update_request->extraRequestData_buf = 0;
801 sr->u.update_request->extraRequestData_len = 0;
802 sr->u.request->database = 0;
804 case Z_SRW_update_response:
805 sr->u.update_response = (Z_SRW_updateResponse *)
806 odr_malloc(o, sizeof(*sr->u.update_response));
807 sr->u.update_response->operationStatus = 0;
808 sr->u.update_response->recordId = 0;
809 sr->u.update_response->recordVersions = 0;
810 sr->u.update_response->num_recordVersions = 0;
811 sr->u.update_response->record = 0;
812 sr->u.update_response->extra_record = 0;
813 sr->u.update_response->extraResponseData_buf = 0;
814 sr->u.update_response->extraResponseData_len = 0;
815 sr->u.update_response->diagnostics = 0;
816 sr->u.update_response->num_diagnostics = 0;
822 static int bib1_srw_map[] = {
832 108, 10, /* Malformed query : Syntax error */
862 100, 1, /* bad map */
910 205, 1, /* bad map */
911 206, 1, /* bad map */
913 208, 1, /* bad map */
924 218, 1, /* bad map */
925 219, 1, /* bad map */
926 220, 1, /* bad map */
927 221, 1, /* bad map */
929 223, 1, /* bad map */
930 224, 1, /* bad map */
931 225, 1, /* bad map */
932 226, 1, /* bad map */
934 228, 1, /* bad map */
939 233, 1, /* bad map */
940 234, 1, /* bad map */
946 240, 1, /* bad map */
947 241, 1, /* bad map */
949 243, 1, /* bad map */
954 1001, 1, /* bad map */
955 1002, 1, /* bad map */
956 1003, 1, /* bad map */
957 1004, 1, /* bad map */
958 1005, 1, /* bad map */
959 1006, 1, /* bad map */
992 * This array contains overrides for when the first occurrence of a
993 * particular SRW error in the array above does not correspond with
994 * the best back-translation of that SRW error.
996 static int srw_bib1_map[] = {
998 /* No doubt there are many more */
1003 int yaz_diag_bib1_to_srw (int code)
1005 const int *p = bib1_srw_map;
1015 int yaz_diag_srw_to_bib1(int code)
1017 /* Check explicit reverse-map first */
1018 const int *p = srw_bib1_map;
1026 /* Fall back on reverse lookup in main map */
1037 static void add_val_int(ODR o, char **name, char **value, int *i,
1038 char *a_name, Odr_int *val)
1043 value[*i] = (char *) odr_malloc(o, 40);
1044 sprintf(value[*i], ODR_INT_PRINTF, *val);
1049 static void add_val_str(ODR o, char **name, char **value, int *i,
1050 char *a_name, char *val)
1060 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1061 char **name, char **value, int max_names)
1064 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1065 name[i] = "operation";
1066 switch(srw_pdu->which)
1068 case Z_SRW_searchRetrieve_request:
1069 value[i++] = "searchRetrieve";
1070 switch(srw_pdu->u.request->query_type)
1072 case Z_SRW_query_type_cql:
1073 add_val_str(encode, name, value, &i, "query",
1074 srw_pdu->u.request->query.cql);
1076 case Z_SRW_query_type_pqf:
1077 add_val_str(encode, name, value, &i, "x-pquery",
1078 srw_pdu->u.request->query.pqf);
1080 case Z_SRW_query_type_xcql:
1081 add_val_str(encode, name, value, &i, "x-cql",
1082 srw_pdu->u.request->query.xcql);
1085 switch(srw_pdu->u.request->sort_type)
1087 case Z_SRW_sort_type_none:
1089 case Z_SRW_sort_type_sort:
1090 add_val_str(encode, name, value, &i, "sortKeys",
1091 srw_pdu->u.request->sort.sortKeys);
1094 add_val_int(encode, name, value, &i, "startRecord",
1095 srw_pdu->u.request->startRecord);
1096 add_val_int(encode, name, value, &i, "maximumRecords",
1097 srw_pdu->u.request->maximumRecords);
1098 add_val_str(encode, name, value, &i, "recordSchema",
1099 srw_pdu->u.request->recordSchema);
1100 add_val_str(encode, name, value, &i, "recordPacking",
1101 srw_pdu->u.request->recordPacking);
1102 add_val_str(encode, name, value, &i, "recordXPath",
1103 srw_pdu->u.request->recordXPath);
1104 add_val_str(encode, name, value, &i, "stylesheet",
1105 srw_pdu->u.request->stylesheet);
1106 add_val_int(encode, name, value, &i, "resultSetTTL",
1107 srw_pdu->u.request->resultSetTTL);
1109 case Z_SRW_explain_request:
1110 value[i++] = "explain";
1111 add_val_str(encode, name, value, &i, "stylesheet",
1112 srw_pdu->u.explain_request->stylesheet);
1114 case Z_SRW_scan_request:
1115 value[i++] = "scan";
1117 switch(srw_pdu->u.scan_request->query_type)
1119 case Z_SRW_query_type_cql:
1120 add_val_str(encode, name, value, &i, "scanClause",
1121 srw_pdu->u.scan_request->scanClause.cql);
1123 case Z_SRW_query_type_pqf:
1124 add_val_str(encode, name, value, &i, "x-pScanClause",
1125 srw_pdu->u.scan_request->scanClause.pqf);
1127 case Z_SRW_query_type_xcql:
1128 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1129 srw_pdu->u.scan_request->scanClause.xcql);
1132 add_val_int(encode, name, value, &i, "responsePosition",
1133 srw_pdu->u.scan_request->responsePosition);
1134 add_val_int(encode, name, value, &i, "maximumTerms",
1135 srw_pdu->u.scan_request->maximumTerms);
1136 add_val_str(encode, name, value, &i, "stylesheet",
1137 srw_pdu->u.scan_request->stylesheet);
1139 case Z_SRW_update_request:
1140 value[i++] = "update";
1145 if (srw_pdu->extra_args)
1147 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1148 for (; ea && i < max_names-1; ea = ea->next)
1151 value[i] = ea->value;
1160 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1161 ODR encode, const char *charset)
1163 char *name[30], *value[30]; /* definite upper limit for SRU params */
1167 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1168 srw_pdu->username, srw_pdu->password);
1169 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1171 yaz_array_to_uri(&uri_args, encode, name, value);
1173 hreq->method = "GET";
1176 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1178 sprintf(path, "%s?%s", hreq->path, uri_args);
1181 z_HTTP_header_add_content_type(encode, &hreq->headers,
1182 "text/xml", charset);
1186 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1187 ODR encode, const char *charset)
1189 char *name[30], *value[30]; /* definite upper limit for SRU params */
1192 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1193 srw_pdu->username, srw_pdu->password);
1194 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1197 yaz_array_to_uri(&uri_args, encode, name, value);
1199 hreq->method = "POST";
1201 hreq->content_buf = uri_args;
1202 hreq->content_len = strlen(uri_args);
1204 z_HTTP_header_add_content_type(encode, &hreq->headers,
1205 "application/x-www-form-urlencoded",
1210 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1211 ODR odr, const char *charset)
1213 Z_SOAP_Handler handlers[3] = {
1215 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1216 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1220 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1222 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1223 srw_pdu->username, srw_pdu->password);
1224 z_HTTP_header_add_content_type(odr,
1226 "text/xml", charset);
1228 z_HTTP_header_add(odr, &hreq->headers,
1229 "SOAPAction", "\"\"");
1230 p->which = Z_SOAP_generic;
1231 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1232 p->u.generic->no = 0;
1233 p->u.generic->ns = 0;
1234 p->u.generic->p = srw_pdu;
1235 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1238 if (srw_pdu->which == Z_SRW_update_request ||
1239 srw_pdu->which == Z_SRW_update_response)
1240 p->u.generic->no = 1; /* second handler */
1242 return z_soap_codec_enc(odr, &p,
1244 &hreq->content_len, handlers,
1248 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1250 Z_SRW_recordVersion *ver
1251 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1253 for ( i=0; i < num; ++i ){
1254 ver[i].versionType = 0;
1255 ver[i].versionValue = 0;
1260 const char *yaz_srw_pack_to_str(int pack)
1264 case Z_SRW_recordPacking_string:
1266 case Z_SRW_recordPacking_XML:
1268 case Z_SRW_recordPacking_URL:
1274 int yaz_srw_str_to_pack(const char *str)
1276 if (!yaz_matchstr(str, "string"))
1277 return Z_SRW_recordPacking_string;
1278 if (!yaz_matchstr(str, "xml"))
1279 return Z_SRW_recordPacking_XML;
1280 if (!yaz_matchstr(str, "url"))
1281 return Z_SRW_recordPacking_URL;
1285 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1291 Z_SRW_extra_arg **ea = &sr->extra_args;
1292 yaz_uri_to_array(extra_args, odr, &name, &val);
1296 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1297 (*ea)->name = *name;
1298 (*ea)->value = *val;
1312 * c-file-style: "Stroustrup"
1313 * indent-tabs-mode: nil
1315 * vim: shiftwidth=4 tabstop=8 expandtab