1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2011 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SRW/SRU utilities.
16 #include <yaz/matchstr.h>
17 #include <yaz/yaz-iconv.h>
20 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
22 return odr_strdupn(n, uri, len);
25 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
32 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
34 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
35 yaz_encode_sru_dbpath_buf(dst, db);
40 static int yaz_base64decode(const char *in, char *out)
42 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
43 "abcdefghijklmnopqrstuvwxyz0123456789+/";
52 if (!(p = strchr(map, in[0])))
56 if (!(p = strchr(map, in[1])))
60 *(out++) = i0 << 2 | i1 >> 4;
64 if (!(p = strchr(map, in[2])))
68 *(out++) = i1 << 4 | i2 >> 2;
72 if (!(p = strchr(map, in[3])))
76 *(out++) = i2 << 6 | i3;
87 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
89 const char *content_type = z_HTTP_header_lookup(hres->headers,
93 if (!yaz_strcmp_del("text/xml", content_type, "; "))
95 if (!yaz_strcmp_del("application/xml", content_type, "; "))
102 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
103 * parameters. Added by SH.
106 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
107 char *username, char *password, ODR decode)
109 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
112 sr->username = username;
114 sr->password = password;
119 char ubuf[256] = "", pbuf[256] = "", *p;
120 if (strncmp(basic, "Basic ", 6))
124 if (!len || len > 256)
126 olen = yaz_base64decode(basic, out);
127 /* Format of out should be username:password at this point */
129 if ((p = strchr(ubuf, ':'))) {
135 sr->username = odr_strdup(decode, ubuf);
137 sr->password = odr_strdup(decode, pbuf);
142 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
144 const char *v = yaz_uri_val(path, name, o);
146 *intp = odr_intdup(o, atoi(v));
149 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
150 const char *uri, const char *message,
153 d->uri = odr_strdup(o, uri);
155 d->message = odr_strdup(o, message);
159 d->details = odr_strdup(o, details);
164 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
165 int code, const char *details)
169 sprintf(uri, "info:srw/diagnostic/1/%d", code);
170 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
173 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
174 int *num, const char *uri,
175 const char *message, const char *details)
177 Z_SRW_diagnostic *d_new;
178 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
180 memcpy (d_new, *d, *num *sizeof(**d));
183 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
187 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
188 int *num, int code, const char *addinfo)
192 sprintf(uri, "info:srw/diagnostic/1/%d", code);
193 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
197 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
198 int *num, int code, const char *addinfo)
202 sprintf(uri, "info:srw/diagnostic/12/%d", code);
203 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
207 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
208 int code, const char *details)
210 const char *message = yaz_diag_srw_str(code);
213 len += strlen(message);
215 len += strlen(details);
217 record->recordData_buf = (char *) odr_malloc(o, len);
219 sprintf(record->recordData_buf, "<diagnostic "
220 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
221 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
223 sprintf(record->recordData_buf + strlen(record->recordData_buf),
224 " <details>%s</details>\n", details);
226 sprintf(record->recordData_buf + strlen(record->recordData_buf),
227 " <message>%s</message>\n", message);
228 sprintf(record->recordData_buf + strlen(record->recordData_buf),
230 record->recordData_len = strlen(record->recordData_buf);
231 record->recordPosition = odr_intdup(o, pos);
232 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
235 static void grab_charset(ODR o, const char *content_type, char **charset)
239 const char *charset_p = 0;
240 if (content_type && (charset_p = strstr(content_type, "; charset=")))
244 while (i < 20 && charset_p[i] &&
245 !strchr("; \n\r", charset_p[i]))
247 *charset = (char*) odr_malloc(o, i+1);
248 memcpy(*charset, charset_p, i);
249 (*charset)[i] = '\0';
254 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
255 Z_SOAP **soap_package, ODR decode, char **charset)
257 if (!strcmp(hreq->method, "POST"))
259 const char *content_type = z_HTTP_header_lookup(hreq->headers,
262 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
263 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
264 !yaz_strcmp_del("text/plain", content_type, "; ")))
266 char *db = "Default";
267 const char *p0 = hreq->path, *p1;
270 static Z_SOAP_Handler soap_handlers[4] = {
272 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
273 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
274 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
281 p1 = strchr(p0, '?');
283 p1 = p0 + strlen(p0);
285 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
286 grab_charset(decode, content_type, charset);
288 ret = z_soap_codec(decode, soap_package,
289 &hreq->content_buf, &hreq->content_len,
291 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
293 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
295 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
296 (*srw_pdu)->u.request->database == 0)
297 (*srw_pdu)->u.request->database = db;
299 if ((*srw_pdu)->which == Z_SRW_explain_request &&
300 (*srw_pdu)->u.explain_request->database == 0)
301 (*srw_pdu)->u.explain_request->database = db;
303 if ((*srw_pdu)->which == Z_SRW_scan_request &&
304 (*srw_pdu)->u.scan_request->database == 0)
305 (*srw_pdu)->u.scan_request->database = db;
307 if ((*srw_pdu)->which == Z_SRW_update_request &&
308 (*srw_pdu)->u.update_request->database == 0)
309 (*srw_pdu)->u.update_request->database = db;
320 static int yaz_sru_decode_integer(ODR odr, const char *pname,
321 const char *valstr, Odr_int **valp,
322 Z_SRW_diagnostic **diag, int *num_diag,
328 if (sscanf(valstr, "%d", &ival) != 1)
330 yaz_add_srw_diagnostic(odr, diag, num_diag,
331 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
334 if (min_value >= 0 && ival < min_value)
336 yaz_add_srw_diagnostic(odr, diag, num_diag,
337 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
340 *valp = odr_intdup(odr, ival);
346 http://www.loc.gov/z3950/agency/zing/srw/service.html
348 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
349 Z_SOAP **soap_package, ODR decode, char **charset,
350 Z_SRW_diagnostic **diag, int *num_diag)
353 static Z_SOAP_Handler soap_handlers[2] = {
354 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
358 const char *content_type = z_HTTP_header_lookup(hreq->headers,
362 SRU GET: ignore content type.
363 SRU POST: we support "application/x-www-form-urlencoded";
364 not "multipart/form-data" .
366 if (!strcmp(hreq->method, "GET")
368 (!strcmp(hreq->method, "POST") && content_type &&
369 !yaz_strcmp_del("application/x-www-form-urlencoded",
370 content_type, "; ")))
372 char *db = "Default";
373 const char *p0 = hreq->path, *p1;
375 const char *operation = 0;
382 char *stylesheet = 0;
383 char *scanClause = 0;
384 char *pScanClause = 0;
385 char *recordXPath = 0;
386 char *recordSchema = 0;
387 char *recordPacking = "xml"; /* xml packing is default for SRU */
388 char *maximumRecords = 0;
389 char *startRecord = 0;
390 char *maximumTerms = 0;
391 char *responsePosition = 0;
392 char *extraRequestData = 0;
393 Z_SRW_extra_arg *extra_args = 0;
398 grab_charset(decode, content_type, charset);
399 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
404 p1 = strchr(p0, '?');
406 p1 = p0 + strlen(p0);
408 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
409 if (!strcmp(hreq->method, "POST"))
410 p1 = hreq->content_buf;
411 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
416 for (i = 0; uri_name[i]; i++)
418 char *n = uri_name[i];
419 char *v = uri_val[i];
420 if (!strcmp(n, "query"))
422 else if (!strcmp(n, "x-pquery"))
424 else if (!strcmp(n, "x-username"))
426 else if (!strcmp(n, "x-password"))
428 else if (!strcmp(n, "operation"))
430 else if (!strcmp(n, "stylesheet"))
432 else if (!strcmp(n, "sortKeys"))
434 else if (!strcmp(n, "recordXPath"))
436 else if (!strcmp(n, "recordSchema"))
438 else if (!strcmp(n, "recordPacking"))
440 else if (!strcmp(n, "version"))
442 else if (!strcmp(n, "scanClause"))
444 else if (!strcmp(n, "x-pScanClause"))
446 else if (!strcmp(n, "maximumRecords"))
448 else if (!strcmp(n, "startRecord"))
450 else if (!strcmp(n, "maximumTerms"))
452 else if (!strcmp(n, "responsePosition"))
453 responsePosition = v;
454 else if (!strcmp(n, "extraRequestData"))
455 extraRequestData = v;
456 else if (n[0] == 'x' && n[1] == '-')
458 Z_SRW_extra_arg **l = &extra_args;
461 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
462 (*l)->name = odr_strdup(decode, n);
463 (*l)->value = odr_strdup(decode, v);
467 yaz_add_srw_diagnostic(decode, diag, num_diag,
468 YAZ_SRW_UNSUPP_PARAMETER, n);
474 yaz_add_srw_diagnostic(
475 decode, diag, num_diag,
476 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
480 version = yaz_negotiate_sru_version(version);
483 { /* negotiation failed. */
484 yaz_add_srw_diagnostic(decode, diag, num_diag,
485 YAZ_SRW_UNSUPP_VERSION, "1.2");
492 yaz_add_srw_diagnostic(
493 decode, diag, num_diag,
494 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
495 operation = "explain";
497 if (!strcmp(operation, "searchRetrieve"))
499 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
501 sr->srw_version = version;
502 sr->extra_args = extra_args;
504 yaz_srw_decodeauth(sr, hreq, username, password, decode);
507 sr->u.request->query_type = Z_SRW_query_type_cql;
508 sr->u.request->query.cql = query;
512 sr->u.request->query_type = Z_SRW_query_type_pqf;
513 sr->u.request->query.pqf = pQuery;
516 yaz_add_srw_diagnostic(
517 decode, diag, num_diag,
518 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
522 sr->u.request->sort_type = Z_SRW_sort_type_sort;
523 sr->u.request->sort.sortKeys = sortKeys;
525 sr->u.request->recordXPath = recordXPath;
526 sr->u.request->recordSchema = recordSchema;
527 sr->u.request->recordPacking = recordPacking;
528 sr->u.request->stylesheet = stylesheet;
530 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
531 &sr->u.request->maximumRecords,
534 yaz_sru_decode_integer(decode, "startRecord", startRecord,
535 &sr->u.request->startRecord,
538 sr->u.request->database = db;
540 (*soap_package) = (Z_SOAP *)
541 odr_malloc(decode, sizeof(**soap_package));
542 (*soap_package)->which = Z_SOAP_generic;
544 (*soap_package)->u.generic = (Z_SOAP_Generic *)
545 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
547 (*soap_package)->u.generic->p = sr;
548 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
549 (*soap_package)->u.generic->no = 0;
551 (*soap_package)->ns = "SRU";
555 else if (!strcmp(operation, "explain"))
557 /* Transfer SRU explain parameters to common struct */
558 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
559 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
561 sr->srw_version = version;
562 sr->extra_args = extra_args;
563 yaz_srw_decodeauth(sr, hreq, username, password, decode);
565 sr->u.explain_request->recordPacking = recordPacking;
566 sr->u.explain_request->database = db;
568 sr->u.explain_request->stylesheet = stylesheet;
570 (*soap_package) = (Z_SOAP *)
571 odr_malloc(decode, sizeof(**soap_package));
572 (*soap_package)->which = Z_SOAP_generic;
574 (*soap_package)->u.generic = (Z_SOAP_Generic *)
575 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
577 (*soap_package)->u.generic->p = sr;
578 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
579 (*soap_package)->u.generic->no = 0;
581 (*soap_package)->ns = "SRU";
585 else if (!strcmp(operation, "scan"))
587 /* Transfer SRU scan parameters to common struct */
588 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
589 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
591 sr->srw_version = version;
592 sr->extra_args = extra_args;
594 yaz_srw_decodeauth(sr, hreq, username, password, decode);
598 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
599 sr->u.scan_request->scanClause.cql = scanClause;
601 else if (pScanClause)
603 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
604 sr->u.scan_request->scanClause.pqf = pScanClause;
607 yaz_add_srw_diagnostic(
608 decode, diag, num_diag,
609 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
610 sr->u.scan_request->database = db;
612 yaz_sru_decode_integer(decode, "maximumTerms",
614 &sr->u.scan_request->maximumTerms,
617 yaz_sru_decode_integer(decode, "responsePosition",
619 &sr->u.scan_request->responsePosition,
622 sr->u.scan_request->stylesheet = stylesheet;
624 (*soap_package) = (Z_SOAP *)
625 odr_malloc(decode, sizeof(**soap_package));
626 (*soap_package)->which = Z_SOAP_generic;
628 (*soap_package)->u.generic = (Z_SOAP_Generic *)
629 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
631 (*soap_package)->u.generic->p = sr;
632 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
633 (*soap_package)->u.generic->no = 0;
635 (*soap_package)->ns = "SRU";
641 /* unsupported operation ... */
642 /* Act as if we received a explain request and throw diagnostic. */
644 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
646 sr->srw_version = version;
648 sr->u.explain_request->recordPacking = recordPacking;
649 sr->u.explain_request->database = db;
651 sr->u.explain_request->stylesheet = stylesheet;
653 (*soap_package) = (Z_SOAP *)
654 odr_malloc(decode, sizeof(**soap_package));
655 (*soap_package)->which = Z_SOAP_generic;
657 (*soap_package)->u.generic = (Z_SOAP_Generic *)
658 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
660 (*soap_package)->u.generic->p = sr;
661 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
662 (*soap_package)->u.generic->no = 0;
664 (*soap_package)->ns = "SRU";
666 yaz_add_srw_diagnostic(decode, diag, num_diag,
667 YAZ_SRW_UNSUPP_OPERATION, operation);
676 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
678 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
679 odr_malloc(o, sizeof(*res));
681 res->extraRecordData_buf = 0;
682 res->extraRecordData_len = 0;
683 res->recordIdentifier = 0;
688 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
690 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
693 for (i = 0; i<n; i++)
695 res[i].recordSchema = 0;
696 res[i].recordPacking = Z_SRW_recordPacking_string;
697 res[i].recordData_buf = 0;
698 res[i].recordData_len = 0;
699 res[i].recordPosition = 0;
704 Z_SRW_record *yaz_srw_get_record(ODR o)
706 return yaz_srw_get_records(o, 1);
709 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
711 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
712 p->srw_version = odr_strdup(o, version);
716 p->extraResponseData_buf = 0;
717 p->extraResponseData_len = 0;
721 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
723 return yaz_srw_get_core_ver(o, "1.1");
726 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
728 return yaz_srw_get_pdu(o, which, "1.1");
731 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
733 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
738 case Z_SRW_searchRetrieve_request:
739 sr->u.request = (Z_SRW_searchRetrieveRequest *)
740 odr_malloc(o, sizeof(*sr->u.request));
741 sr->u.request->query_type = Z_SRW_query_type_cql;
742 sr->u.request->query.cql = 0;
743 sr->u.request->sort_type = Z_SRW_sort_type_none;
744 sr->u.request->sort.none = 0;
745 sr->u.request->startRecord = 0;
746 sr->u.request->maximumRecords = 0;
747 sr->u.request->recordSchema = 0;
748 sr->u.request->recordPacking = 0;
749 sr->u.request->recordXPath = 0;
750 sr->u.request->database = 0;
751 sr->u.request->resultSetTTL = 0;
752 sr->u.request->stylesheet = 0;
753 sr->u.request->facetList = 0;
755 case Z_SRW_searchRetrieve_response:
756 sr->u.response = (Z_SRW_searchRetrieveResponse *)
757 odr_malloc(o, sizeof(*sr->u.response));
758 sr->u.response->numberOfRecords = 0;
759 sr->u.response->resultSetId = 0;
760 sr->u.response->resultSetIdleTime = 0;
761 sr->u.response->records = 0;
762 sr->u.response->num_records = 0;
763 sr->u.response->diagnostics = 0;
764 sr->u.response->num_diagnostics = 0;
765 sr->u.response->nextRecordPosition = 0;
766 sr->u.response->extra_records = 0;
767 sr->u.response->facetList = 0;
769 case Z_SRW_explain_request:
770 sr->u.explain_request = (Z_SRW_explainRequest *)
771 odr_malloc(o, sizeof(*sr->u.explain_request));
772 sr->u.explain_request->recordPacking = 0;
773 sr->u.explain_request->database = 0;
774 sr->u.explain_request->stylesheet = 0;
776 case Z_SRW_explain_response:
777 sr->u.explain_response = (Z_SRW_explainResponse *)
778 odr_malloc(o, sizeof(*sr->u.explain_response));
779 sr->u.explain_response->record.recordData_buf = 0;
780 sr->u.explain_response->record.recordData_len = 0;
781 sr->u.explain_response->record.recordSchema = 0;
782 sr->u.explain_response->record.recordPosition = 0;
783 sr->u.explain_response->record.recordPacking =
784 Z_SRW_recordPacking_string;
785 sr->u.explain_response->diagnostics = 0;
786 sr->u.explain_response->num_diagnostics = 0;
787 sr->u.explain_response->extra_record = 0;
789 case Z_SRW_scan_request:
790 sr->u.scan_request = (Z_SRW_scanRequest *)
791 odr_malloc(o, sizeof(*sr->u.scan_request));
792 sr->u.scan_request->database = 0;
793 sr->u.scan_request->stylesheet = 0;
794 sr->u.scan_request->maximumTerms = 0;
795 sr->u.scan_request->responsePosition = 0;
796 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
797 sr->u.scan_request->scanClause.cql = 0;
799 case Z_SRW_scan_response:
800 sr->u.scan_response = (Z_SRW_scanResponse *)
801 odr_malloc(o, sizeof(*sr->u.scan_response));
802 sr->u.scan_response->terms = 0;
803 sr->u.scan_response->num_terms = 0;
804 sr->u.scan_response->diagnostics = 0;
805 sr->u.scan_response->num_diagnostics = 0;
807 case Z_SRW_update_request:
808 sr->u.update_request = (Z_SRW_updateRequest *)
809 odr_malloc(o, sizeof(*sr->u.update_request));
810 sr->u.update_request->database = 0;
811 sr->u.update_request->stylesheet = 0;
812 sr->u.update_request->record = 0;
813 sr->u.update_request->recordId = 0;
814 sr->u.update_request->recordVersions = 0;
815 sr->u.update_request->num_recordVersions = 0;
816 sr->u.update_request->extra_record = 0;
817 sr->u.update_request->extraRequestData_buf = 0;
818 sr->u.update_request->extraRequestData_len = 0;
819 sr->u.request->database = 0;
821 case Z_SRW_update_response:
822 sr->u.update_response = (Z_SRW_updateResponse *)
823 odr_malloc(o, sizeof(*sr->u.update_response));
824 sr->u.update_response->operationStatus = 0;
825 sr->u.update_response->recordId = 0;
826 sr->u.update_response->recordVersions = 0;
827 sr->u.update_response->num_recordVersions = 0;
828 sr->u.update_response->record = 0;
829 sr->u.update_response->extra_record = 0;
830 sr->u.update_response->extraResponseData_buf = 0;
831 sr->u.update_response->extraResponseData_len = 0;
832 sr->u.update_response->diagnostics = 0;
833 sr->u.update_response->num_diagnostics = 0;
839 static int bib1_srw_map[] = {
849 108, 10, /* Malformed query : Syntax error */
879 100, 1, /* bad map */
927 205, 1, /* bad map */
928 206, 1, /* bad map */
930 208, 1, /* bad map */
941 218, 1, /* bad map */
942 219, 1, /* bad map */
943 220, 1, /* bad map */
944 221, 1, /* bad map */
946 223, 1, /* bad map */
947 224, 1, /* bad map */
948 225, 1, /* bad map */
949 226, 1, /* bad map */
951 228, 1, /* bad map */
956 233, 1, /* bad map */
957 234, 1, /* bad map */
963 240, 1, /* bad map */
964 241, 1, /* bad map */
966 243, 1, /* bad map */
971 1001, 1, /* bad map */
972 1002, 1, /* bad map */
973 1003, 1, /* bad map */
974 1004, 1, /* bad map */
975 1005, 1, /* bad map */
976 1006, 1, /* bad map */
1009 * This array contains overrides for when the first occurrence of a
1010 * particular SRW error in the array above does not correspond with
1011 * the best back-translation of that SRW error.
1013 static int srw_bib1_map[] = {
1015 /* No doubt there are many more */
1020 int yaz_diag_bib1_to_srw (int code)
1022 const int *p = bib1_srw_map;
1032 int yaz_diag_srw_to_bib1(int code)
1034 /* Check explicit reverse-map first */
1035 const int *p = srw_bib1_map;
1043 /* Fall back on reverse lookup in main map */
1054 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
1055 char *a_name, Odr_int *val)
1060 value[*i] = (char *) odr_malloc(o, 40);
1061 sprintf(value[*i], ODR_INT_PRINTF, *val);
1066 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
1067 char *a_name, char *val)
1077 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1078 char **name, char **value, int max_names)
1081 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1082 name[i] = "operation";
1083 switch(srw_pdu->which)
1085 case Z_SRW_searchRetrieve_request:
1086 value[i++] = "searchRetrieve";
1087 switch(srw_pdu->u.request->query_type)
1089 case Z_SRW_query_type_cql:
1090 yaz_add_name_value_str(encode, name, value, &i, "query",
1091 srw_pdu->u.request->query.cql);
1093 case Z_SRW_query_type_pqf:
1094 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
1095 srw_pdu->u.request->query.pqf);
1097 case Z_SRW_query_type_xcql:
1098 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
1099 srw_pdu->u.request->query.xcql);
1102 switch(srw_pdu->u.request->sort_type)
1104 case Z_SRW_sort_type_none:
1106 case Z_SRW_sort_type_sort:
1107 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
1108 srw_pdu->u.request->sort.sortKeys);
1111 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
1112 srw_pdu->u.request->startRecord);
1113 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
1114 srw_pdu->u.request->maximumRecords);
1115 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
1116 srw_pdu->u.request->recordSchema);
1117 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
1118 srw_pdu->u.request->recordPacking);
1119 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
1120 srw_pdu->u.request->recordXPath);
1121 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1122 srw_pdu->u.request->stylesheet);
1123 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
1124 srw_pdu->u.request->resultSetTTL);
1126 case Z_SRW_explain_request:
1127 value[i++] = "explain";
1128 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1129 srw_pdu->u.explain_request->stylesheet);
1131 case Z_SRW_scan_request:
1132 value[i++] = "scan";
1134 switch(srw_pdu->u.scan_request->query_type)
1136 case Z_SRW_query_type_cql:
1137 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
1138 srw_pdu->u.scan_request->scanClause.cql);
1140 case Z_SRW_query_type_pqf:
1141 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
1142 srw_pdu->u.scan_request->scanClause.pqf);
1144 case Z_SRW_query_type_xcql:
1145 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
1146 srw_pdu->u.scan_request->scanClause.xcql);
1149 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
1150 srw_pdu->u.scan_request->responsePosition);
1151 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
1152 srw_pdu->u.scan_request->maximumTerms);
1153 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
1154 srw_pdu->u.scan_request->stylesheet);
1156 case Z_SRW_update_request:
1157 value[i++] = "update";
1162 if (srw_pdu->extra_args)
1164 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1165 for (; ea && i < max_names-1; ea = ea->next)
1168 value[i] = ea->value;
1177 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1178 ODR encode, const char *charset)
1180 char *name[30], *value[30]; /* definite upper limit for SRU params */
1184 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1185 srw_pdu->username, srw_pdu->password);
1186 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1188 yaz_array_to_uri(&uri_args, encode, name, value);
1190 hreq->method = "GET";
1193 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1195 sprintf(path, "%s?%s", hreq->path, uri_args);
1198 z_HTTP_header_add_content_type(encode, &hreq->headers,
1199 "text/xml", charset);
1203 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1204 ODR encode, const char *charset)
1206 char *name[30], *value[30]; /* definite upper limit for SRU params */
1209 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1210 srw_pdu->username, srw_pdu->password);
1211 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1214 yaz_array_to_uri(&uri_args, encode, name, value);
1216 hreq->method = "POST";
1218 hreq->content_buf = uri_args;
1219 hreq->content_len = strlen(uri_args);
1221 z_HTTP_header_add_content_type(encode, &hreq->headers,
1222 "application/x-www-form-urlencoded",
1227 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1228 ODR odr, const char *charset)
1230 Z_SOAP_Handler handlers[3] = {
1232 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1233 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1237 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1239 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1240 srw_pdu->username, srw_pdu->password);
1241 z_HTTP_header_add_content_type(odr,
1243 "text/xml", charset);
1245 z_HTTP_header_add(odr, &hreq->headers,
1246 "SOAPAction", "\"\"");
1247 p->which = Z_SOAP_generic;
1248 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1249 p->u.generic->no = 0;
1250 p->u.generic->ns = 0;
1251 p->u.generic->p = srw_pdu;
1252 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1255 if (srw_pdu->which == Z_SRW_update_request ||
1256 srw_pdu->which == Z_SRW_update_response)
1257 p->u.generic->no = 1; /* second handler */
1259 return z_soap_codec_enc(odr, &p,
1261 &hreq->content_len, handlers,
1265 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1267 Z_SRW_recordVersion *ver
1268 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1270 for ( i=0; i < num; ++i ){
1271 ver[i].versionType = 0;
1272 ver[i].versionValue = 0;
1277 const char *yaz_srw_pack_to_str(int pack)
1281 case Z_SRW_recordPacking_string:
1283 case Z_SRW_recordPacking_XML:
1285 case Z_SRW_recordPacking_URL:
1291 int yaz_srw_str_to_pack(const char *str)
1293 if (!yaz_matchstr(str, "string"))
1294 return Z_SRW_recordPacking_string;
1295 if (!yaz_matchstr(str, "xml"))
1296 return Z_SRW_recordPacking_XML;
1297 if (!yaz_matchstr(str, "url"))
1298 return Z_SRW_recordPacking_URL;
1302 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1308 Z_SRW_extra_arg **ea = &sr->extra_args;
1309 yaz_uri_to_array(extra_args, odr, &name, &val);
1313 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1314 (*ea)->name = *name;
1315 (*ea)->value = *val;
1328 * c-file-style: "Stroustrup"
1329 * indent-tabs-mode: nil
1331 * vim: shiftwidth=4 tabstop=8 expandtab