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.
13 #include <yaz/matchstr.h>
14 #include <yaz/yaz-iconv.h>
16 /** \brief decodes HTTP path (which should hold SRU database)
17 \param o memory for returned result
18 \param uri URI path (up to but not including ?)
19 \returns ODR allocated database
21 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
23 char *ret = odr_malloc(n, strlen(uri) + 1);
24 yaz_decode_uri_component(ret, uri, len);
28 void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
32 yaz_encode_uri_component(dst+1, db);
35 char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
37 char *dst = odr_malloc(out, 3 * strlen(db) + 2);
38 yaz_encode_sru_dbpath_buf(dst, db);
43 static int yaz_base64decode(const char *in, char *out)
45 const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
46 "abcdefghijklmnopqrstuvwxyz0123456789+/";
55 if (!(p = strchr(map, in[0])))
59 if (!(p = strchr(map, in[1])))
63 *(out++) = i0 << 2 | i1 >> 4;
67 if (!(p = strchr(map, in[2])))
71 *(out++) = i1 << 4 | i2 >> 2;
75 if (!(p = strchr(map, in[3])))
79 *(out++) = i2 << 6 | i3;
90 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
92 const char *content_type = z_HTTP_header_lookup(hres->headers,
96 if (!yaz_strcmp_del("text/xml", content_type, "; "))
98 if (!yaz_strcmp_del("application/xml", content_type, "; "))
105 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
106 * parameters. Added by SH.
109 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
110 char *username, char *password, ODR decode)
112 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
115 sr->username = username;
117 sr->password = password;
122 char ubuf[256] = "", pbuf[256] = "", *p;
123 if (strncmp(basic, "Basic ", 6))
127 if (!len || len > 256)
129 olen = yaz_base64decode(basic, out);
130 /* Format of out should be username:password at this point */
132 if ((p = strchr(ubuf, ':'))) {
138 sr->username = odr_strdup(decode, ubuf);
140 sr->password = odr_strdup(decode, pbuf);
145 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
147 const char *v = yaz_uri_val(path, name, o);
149 *intp = odr_intdup(o, atoi(v));
152 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
153 const char *uri, const char *message,
156 d->uri = odr_strdup(o, uri);
158 d->message = odr_strdup(o, message);
162 d->details = odr_strdup(o, details);
167 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
168 int code, const char *details)
172 sprintf(uri, "info:srw/diagnostic/1/%d", code);
173 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
176 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
177 int *num, const char *uri,
178 const char *message, const char *details)
180 Z_SRW_diagnostic *d_new;
181 d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
183 memcpy (d_new, *d, *num *sizeof(**d));
186 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
190 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
191 int *num, int code, const char *addinfo)
195 sprintf(uri, "info:srw/diagnostic/1/%d", code);
196 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
200 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
201 int *num, int code, const char *addinfo)
205 sprintf(uri, "info:srw/diagnostic/12/%d", code);
206 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
210 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
211 int code, const char *details)
213 const char *message = yaz_diag_srw_str(code);
216 len += strlen(message);
218 len += strlen(details);
220 record->recordData_buf = (char *) odr_malloc(o, len);
222 sprintf(record->recordData_buf, "<diagnostic "
223 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
224 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
226 sprintf(record->recordData_buf + strlen(record->recordData_buf),
227 " <details>%s</details>\n", details);
229 sprintf(record->recordData_buf + strlen(record->recordData_buf),
230 " <message>%s</message>\n", message);
231 sprintf(record->recordData_buf + strlen(record->recordData_buf),
233 record->recordData_len = strlen(record->recordData_buf);
234 record->recordPosition = odr_intdup(o, pos);
235 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
238 static void grab_charset(ODR o, const char *content_type, char **charset)
242 const char *charset_p = 0;
243 if (content_type && (charset_p = strstr(content_type, "; charset=")))
247 while (i < 20 && charset_p[i] &&
248 !strchr("; \n\r", charset_p[i]))
250 *charset = (char*) odr_malloc(o, i+1);
251 memcpy(*charset, charset_p, i);
252 (*charset)[i] = '\0';
257 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
258 Z_SOAP **soap_package, ODR decode, char **charset)
260 if (!strcmp(hreq->method, "POST"))
262 const char *content_type = z_HTTP_header_lookup(hreq->headers,
265 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
266 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
267 !yaz_strcmp_del("text/plain", content_type, "; ")))
269 char *db = "Default";
270 const char *p0 = hreq->path, *p1;
273 static Z_SOAP_Handler soap_handlers[4] = {
275 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
276 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
277 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
284 p1 = strchr(p0, '?');
286 p1 = p0 + strlen(p0);
288 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
289 grab_charset(decode, content_type, charset);
291 ret = z_soap_codec(decode, soap_package,
292 &hreq->content_buf, &hreq->content_len,
294 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
296 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
298 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
299 (*srw_pdu)->u.request->database == 0)
300 (*srw_pdu)->u.request->database = db;
302 if ((*srw_pdu)->which == Z_SRW_explain_request &&
303 (*srw_pdu)->u.explain_request->database == 0)
304 (*srw_pdu)->u.explain_request->database = db;
306 if ((*srw_pdu)->which == Z_SRW_scan_request &&
307 (*srw_pdu)->u.scan_request->database == 0)
308 (*srw_pdu)->u.scan_request->database = db;
310 if ((*srw_pdu)->which == Z_SRW_update_request &&
311 (*srw_pdu)->u.update_request->database == 0)
312 (*srw_pdu)->u.update_request->database = db;
323 static int yaz_sru_decode_integer(ODR odr, const char *pname,
324 const char *valstr, Odr_int **valp,
325 Z_SRW_diagnostic **diag, int *num_diag,
331 if (sscanf(valstr, "%d", &ival) != 1)
333 yaz_add_srw_diagnostic(odr, diag, num_diag,
334 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
337 if (min_value >= 0 && ival < min_value)
339 yaz_add_srw_diagnostic(odr, diag, num_diag,
340 YAZ_SRW_UNSUPP_PARAMETER_VALUE, pname);
343 *valp = odr_intdup(odr, ival);
349 http://www.loc.gov/z3950/agency/zing/srw/service.html
351 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
352 Z_SOAP **soap_package, ODR decode, char **charset,
353 Z_SRW_diagnostic **diag, int *num_diag)
356 static Z_SOAP_Handler soap_handlers[2] = {
357 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
361 const char *content_type = z_HTTP_header_lookup(hreq->headers,
365 SRU GET: ignore content type.
366 SRU POST: we support "application/x-www-form-urlencoded";
367 not "multipart/form-data" .
369 if (!strcmp(hreq->method, "GET")
371 (!strcmp(hreq->method, "POST") && content_type &&
372 !yaz_strcmp_del("application/x-www-form-urlencoded",
373 content_type, "; ")))
375 char *db = "Default";
376 const char *p0 = hreq->path, *p1;
378 const char *operation = 0;
385 char *stylesheet = 0;
386 char *scanClause = 0;
387 char *pScanClause = 0;
388 char *recordXPath = 0;
389 char *recordSchema = 0;
390 char *recordPacking = "xml"; /* xml packing is default for SRU */
391 char *maximumRecords = 0;
392 char *startRecord = 0;
393 char *maximumTerms = 0;
394 char *responsePosition = 0;
395 char *extraRequestData = 0;
396 Z_SRW_extra_arg *extra_args = 0;
401 grab_charset(decode, content_type, charset);
402 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
407 p1 = strchr(p0, '?');
409 p1 = p0 + strlen(p0);
411 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
412 if (!strcmp(hreq->method, "POST"))
413 p1 = hreq->content_buf;
414 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
419 for (i = 0; uri_name[i]; i++)
421 char *n = uri_name[i];
422 char *v = uri_val[i];
423 if (!strcmp(n, "query"))
425 else if (!strcmp(n, "x-pquery"))
427 else if (!strcmp(n, "x-username"))
429 else if (!strcmp(n, "x-password"))
431 else if (!strcmp(n, "operation"))
433 else if (!strcmp(n, "stylesheet"))
435 else if (!strcmp(n, "sortKeys"))
437 else if (!strcmp(n, "recordXPath"))
439 else if (!strcmp(n, "recordSchema"))
441 else if (!strcmp(n, "recordPacking"))
443 else if (!strcmp(n, "version"))
445 else if (!strcmp(n, "scanClause"))
447 else if (!strcmp(n, "x-pScanClause"))
449 else if (!strcmp(n, "maximumRecords"))
451 else if (!strcmp(n, "startRecord"))
453 else if (!strcmp(n, "maximumTerms"))
455 else if (!strcmp(n, "responsePosition"))
456 responsePosition = v;
457 else if (!strcmp(n, "extraRequestData"))
458 extraRequestData = v;
459 else if (n[0] == 'x' && n[1] == '-')
461 Z_SRW_extra_arg **l = &extra_args;
464 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
465 (*l)->name = odr_strdup(decode, n);
466 (*l)->value = odr_strdup(decode, v);
470 yaz_add_srw_diagnostic(decode, diag, num_diag,
471 YAZ_SRW_UNSUPP_PARAMETER, n);
477 yaz_add_srw_diagnostic(
478 decode, diag, num_diag,
479 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
483 version = yaz_negotiate_sru_version(version);
486 { /* negotiation failed. */
487 yaz_add_srw_diagnostic(decode, diag, num_diag,
488 YAZ_SRW_UNSUPP_VERSION, "1.2");
495 yaz_add_srw_diagnostic(
496 decode, diag, num_diag,
497 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
498 operation = "explain";
500 if (!strcmp(operation, "searchRetrieve"))
502 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
504 sr->srw_version = version;
505 sr->extra_args = extra_args;
507 yaz_srw_decodeauth(sr, hreq, username, password, decode);
510 sr->u.request->query_type = Z_SRW_query_type_cql;
511 sr->u.request->query.cql = query;
515 sr->u.request->query_type = Z_SRW_query_type_pqf;
516 sr->u.request->query.pqf = pQuery;
519 yaz_add_srw_diagnostic(
520 decode, diag, num_diag,
521 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
525 sr->u.request->sort_type = Z_SRW_sort_type_sort;
526 sr->u.request->sort.sortKeys = sortKeys;
528 sr->u.request->recordXPath = recordXPath;
529 sr->u.request->recordSchema = recordSchema;
530 sr->u.request->recordPacking = recordPacking;
531 sr->u.request->stylesheet = stylesheet;
533 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
534 &sr->u.request->maximumRecords,
537 yaz_sru_decode_integer(decode, "startRecord", startRecord,
538 &sr->u.request->startRecord,
541 sr->u.request->database = db;
543 (*soap_package) = (Z_SOAP *)
544 odr_malloc(decode, sizeof(**soap_package));
545 (*soap_package)->which = Z_SOAP_generic;
547 (*soap_package)->u.generic = (Z_SOAP_Generic *)
548 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
550 (*soap_package)->u.generic->p = sr;
551 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
552 (*soap_package)->u.generic->no = 0;
554 (*soap_package)->ns = "SRU";
558 else if (!strcmp(operation, "explain"))
560 /* Transfer SRU explain parameters to common struct */
561 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
562 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
564 sr->srw_version = version;
565 sr->extra_args = extra_args;
566 yaz_srw_decodeauth(sr, hreq, username, password, decode);
568 sr->u.explain_request->recordPacking = recordPacking;
569 sr->u.explain_request->database = db;
571 sr->u.explain_request->stylesheet = stylesheet;
573 (*soap_package) = (Z_SOAP *)
574 odr_malloc(decode, sizeof(**soap_package));
575 (*soap_package)->which = Z_SOAP_generic;
577 (*soap_package)->u.generic = (Z_SOAP_Generic *)
578 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
580 (*soap_package)->u.generic->p = sr;
581 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
582 (*soap_package)->u.generic->no = 0;
584 (*soap_package)->ns = "SRU";
588 else if (!strcmp(operation, "scan"))
590 /* Transfer SRU scan parameters to common struct */
591 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
592 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
594 sr->srw_version = version;
595 sr->extra_args = extra_args;
597 yaz_srw_decodeauth(sr, hreq, username, password, decode);
601 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
602 sr->u.scan_request->scanClause.cql = scanClause;
604 else if (pScanClause)
606 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
607 sr->u.scan_request->scanClause.pqf = pScanClause;
610 yaz_add_srw_diagnostic(
611 decode, diag, num_diag,
612 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
613 sr->u.scan_request->database = db;
615 yaz_sru_decode_integer(decode, "maximumTerms",
617 &sr->u.scan_request->maximumTerms,
620 yaz_sru_decode_integer(decode, "responsePosition",
622 &sr->u.scan_request->responsePosition,
625 sr->u.scan_request->stylesheet = stylesheet;
627 (*soap_package) = (Z_SOAP *)
628 odr_malloc(decode, sizeof(**soap_package));
629 (*soap_package)->which = Z_SOAP_generic;
631 (*soap_package)->u.generic = (Z_SOAP_Generic *)
632 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
634 (*soap_package)->u.generic->p = sr;
635 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
636 (*soap_package)->u.generic->no = 0;
638 (*soap_package)->ns = "SRU";
644 /* unsupported operation ... */
645 /* Act as if we received a explain request and throw diagnostic. */
647 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
649 sr->srw_version = version;
651 sr->u.explain_request->recordPacking = recordPacking;
652 sr->u.explain_request->database = db;
654 sr->u.explain_request->stylesheet = stylesheet;
656 (*soap_package) = (Z_SOAP *)
657 odr_malloc(decode, sizeof(**soap_package));
658 (*soap_package)->which = Z_SOAP_generic;
660 (*soap_package)->u.generic = (Z_SOAP_Generic *)
661 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
663 (*soap_package)->u.generic->p = sr;
664 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
665 (*soap_package)->u.generic->no = 0;
667 (*soap_package)->ns = "SRU";
669 yaz_add_srw_diagnostic(decode, diag, num_diag,
670 YAZ_SRW_UNSUPP_OPERATION, operation);
679 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
681 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
682 odr_malloc(o, sizeof(*res));
684 res->extraRecordData_buf = 0;
685 res->extraRecordData_len = 0;
686 res->recordIdentifier = 0;
691 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
693 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
696 for (i = 0; i<n; i++)
698 res[i].recordSchema = 0;
699 res[i].recordPacking = Z_SRW_recordPacking_string;
700 res[i].recordData_buf = 0;
701 res[i].recordData_len = 0;
702 res[i].recordPosition = 0;
707 Z_SRW_record *yaz_srw_get_record(ODR o)
709 return yaz_srw_get_records(o, 1);
712 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
714 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
715 p->srw_version = odr_strdup(o, version);
719 p->extraResponseData_buf = 0;
720 p->extraResponseData_len = 0;
724 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
726 return yaz_srw_get_core_ver(o, "1.1");
729 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
731 return yaz_srw_get_pdu(o, which, "1.1");
734 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
736 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
741 case Z_SRW_searchRetrieve_request:
742 sr->u.request = (Z_SRW_searchRetrieveRequest *)
743 odr_malloc(o, sizeof(*sr->u.request));
744 sr->u.request->query_type = Z_SRW_query_type_cql;
745 sr->u.request->query.cql = 0;
746 sr->u.request->sort_type = Z_SRW_sort_type_none;
747 sr->u.request->sort.none = 0;
748 sr->u.request->startRecord = 0;
749 sr->u.request->maximumRecords = 0;
750 sr->u.request->recordSchema = 0;
751 sr->u.request->recordPacking = 0;
752 sr->u.request->recordXPath = 0;
753 sr->u.request->database = 0;
754 sr->u.request->resultSetTTL = 0;
755 sr->u.request->stylesheet = 0;
757 case Z_SRW_searchRetrieve_response:
758 sr->u.response = (Z_SRW_searchRetrieveResponse *)
759 odr_malloc(o, sizeof(*sr->u.response));
760 sr->u.response->numberOfRecords = 0;
761 sr->u.response->resultSetId = 0;
762 sr->u.response->resultSetIdleTime = 0;
763 sr->u.response->records = 0;
764 sr->u.response->num_records = 0;
765 sr->u.response->diagnostics = 0;
766 sr->u.response->num_diagnostics = 0;
767 sr->u.response->nextRecordPosition = 0;
768 sr->u.response->extra_records = 0;
770 case Z_SRW_explain_request:
771 sr->u.explain_request = (Z_SRW_explainRequest *)
772 odr_malloc(o, sizeof(*sr->u.explain_request));
773 sr->u.explain_request->recordPacking = 0;
774 sr->u.explain_request->database = 0;
775 sr->u.explain_request->stylesheet = 0;
777 case Z_SRW_explain_response:
778 sr->u.explain_response = (Z_SRW_explainResponse *)
779 odr_malloc(o, sizeof(*sr->u.explain_response));
780 sr->u.explain_response->record.recordData_buf = 0;
781 sr->u.explain_response->record.recordData_len = 0;
782 sr->u.explain_response->record.recordSchema = 0;
783 sr->u.explain_response->record.recordPosition = 0;
784 sr->u.explain_response->record.recordPacking =
785 Z_SRW_recordPacking_string;
786 sr->u.explain_response->diagnostics = 0;
787 sr->u.explain_response->num_diagnostics = 0;
788 sr->u.explain_response->extra_record = 0;
790 case Z_SRW_scan_request:
791 sr->u.scan_request = (Z_SRW_scanRequest *)
792 odr_malloc(o, sizeof(*sr->u.scan_request));
793 sr->u.scan_request->database = 0;
794 sr->u.scan_request->stylesheet = 0;
795 sr->u.scan_request->maximumTerms = 0;
796 sr->u.scan_request->responsePosition = 0;
797 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
798 sr->u.scan_request->scanClause.cql = 0;
800 case Z_SRW_scan_response:
801 sr->u.scan_response = (Z_SRW_scanResponse *)
802 odr_malloc(o, sizeof(*sr->u.scan_response));
803 sr->u.scan_response->terms = 0;
804 sr->u.scan_response->num_terms = 0;
805 sr->u.scan_response->diagnostics = 0;
806 sr->u.scan_response->num_diagnostics = 0;
808 case Z_SRW_update_request:
809 sr->u.update_request = (Z_SRW_updateRequest *)
810 odr_malloc(o, sizeof(*sr->u.update_request));
811 sr->u.update_request->database = 0;
812 sr->u.update_request->stylesheet = 0;
813 sr->u.update_request->record = 0;
814 sr->u.update_request->recordId = 0;
815 sr->u.update_request->recordVersions = 0;
816 sr->u.update_request->num_recordVersions = 0;
817 sr->u.update_request->extra_record = 0;
818 sr->u.update_request->extraRequestData_buf = 0;
819 sr->u.update_request->extraRequestData_len = 0;
820 sr->u.request->database = 0;
822 case Z_SRW_update_response:
823 sr->u.update_response = (Z_SRW_updateResponse *)
824 odr_malloc(o, sizeof(*sr->u.update_response));
825 sr->u.update_response->operationStatus = 0;
826 sr->u.update_response->recordId = 0;
827 sr->u.update_response->recordVersions = 0;
828 sr->u.update_response->num_recordVersions = 0;
829 sr->u.update_response->record = 0;
830 sr->u.update_response->extra_record = 0;
831 sr->u.update_response->extraResponseData_buf = 0;
832 sr->u.update_response->extraResponseData_len = 0;
833 sr->u.update_response->diagnostics = 0;
834 sr->u.update_response->num_diagnostics = 0;
840 static int bib1_srw_map[] = {
850 108, 10, /* Malformed query : Syntax error */
880 100, 1, /* bad map */
928 205, 1, /* bad map */
929 206, 1, /* bad map */
931 208, 1, /* bad map */
942 218, 1, /* bad map */
943 219, 1, /* bad map */
944 220, 1, /* bad map */
945 221, 1, /* bad map */
947 223, 1, /* bad map */
948 224, 1, /* bad map */
949 225, 1, /* bad map */
950 226, 1, /* bad map */
952 228, 1, /* bad map */
957 233, 1, /* bad map */
958 234, 1, /* bad map */
964 240, 1, /* bad map */
965 241, 1, /* bad map */
967 243, 1, /* bad map */
972 1001, 1, /* bad map */
973 1002, 1, /* bad map */
974 1003, 1, /* bad map */
975 1004, 1, /* bad map */
976 1005, 1, /* bad map */
977 1006, 1, /* bad map */
1010 * This array contains overrides for when the first occurrence of a
1011 * particular SRW error in the array above does not correspond with
1012 * the best back-translation of that SRW error.
1014 static int srw_bib1_map[] = {
1016 /* No doubt there are many more */
1021 int yaz_diag_bib1_to_srw (int code)
1023 const int *p = bib1_srw_map;
1033 int yaz_diag_srw_to_bib1(int code)
1035 /* Check explicit reverse-map first */
1036 const int *p = srw_bib1_map;
1044 /* Fall back on reverse lookup in main map */
1055 static void add_val_int(ODR o, char **name, char **value, int *i,
1056 char *a_name, Odr_int *val)
1061 value[*i] = (char *) odr_malloc(o, 40);
1062 sprintf(value[*i], ODR_INT_PRINTF, *val);
1067 static void add_val_str(ODR o, char **name, char **value, int *i,
1068 char *a_name, char *val)
1078 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
1079 char **name, char **value, int max_names)
1082 add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version);
1083 name[i] = "operation";
1084 switch(srw_pdu->which)
1086 case Z_SRW_searchRetrieve_request:
1087 value[i++] = "searchRetrieve";
1088 switch(srw_pdu->u.request->query_type)
1090 case Z_SRW_query_type_cql:
1091 add_val_str(encode, name, value, &i, "query",
1092 srw_pdu->u.request->query.cql);
1094 case Z_SRW_query_type_pqf:
1095 add_val_str(encode, name, value, &i, "x-pquery",
1096 srw_pdu->u.request->query.pqf);
1098 case Z_SRW_query_type_xcql:
1099 add_val_str(encode, name, value, &i, "x-cql",
1100 srw_pdu->u.request->query.xcql);
1103 switch(srw_pdu->u.request->sort_type)
1105 case Z_SRW_sort_type_none:
1107 case Z_SRW_sort_type_sort:
1108 add_val_str(encode, name, value, &i, "sortKeys",
1109 srw_pdu->u.request->sort.sortKeys);
1112 add_val_int(encode, name, value, &i, "startRecord",
1113 srw_pdu->u.request->startRecord);
1114 add_val_int(encode, name, value, &i, "maximumRecords",
1115 srw_pdu->u.request->maximumRecords);
1116 add_val_str(encode, name, value, &i, "recordSchema",
1117 srw_pdu->u.request->recordSchema);
1118 add_val_str(encode, name, value, &i, "recordPacking",
1119 srw_pdu->u.request->recordPacking);
1120 add_val_str(encode, name, value, &i, "recordXPath",
1121 srw_pdu->u.request->recordXPath);
1122 add_val_str(encode, name, value, &i, "stylesheet",
1123 srw_pdu->u.request->stylesheet);
1124 add_val_int(encode, name, value, &i, "resultSetTTL",
1125 srw_pdu->u.request->resultSetTTL);
1127 case Z_SRW_explain_request:
1128 value[i++] = "explain";
1129 add_val_str(encode, name, value, &i, "stylesheet",
1130 srw_pdu->u.explain_request->stylesheet);
1132 case Z_SRW_scan_request:
1133 value[i++] = "scan";
1135 switch(srw_pdu->u.scan_request->query_type)
1137 case Z_SRW_query_type_cql:
1138 add_val_str(encode, name, value, &i, "scanClause",
1139 srw_pdu->u.scan_request->scanClause.cql);
1141 case Z_SRW_query_type_pqf:
1142 add_val_str(encode, name, value, &i, "x-pScanClause",
1143 srw_pdu->u.scan_request->scanClause.pqf);
1145 case Z_SRW_query_type_xcql:
1146 add_val_str(encode, name, value, &i, "x-cqlScanClause",
1147 srw_pdu->u.scan_request->scanClause.xcql);
1150 add_val_int(encode, name, value, &i, "responsePosition",
1151 srw_pdu->u.scan_request->responsePosition);
1152 add_val_int(encode, name, value, &i, "maximumTerms",
1153 srw_pdu->u.scan_request->maximumTerms);
1154 add_val_str(encode, name, value, &i, "stylesheet",
1155 srw_pdu->u.scan_request->stylesheet);
1157 case Z_SRW_update_request:
1158 value[i++] = "update";
1163 if (srw_pdu->extra_args)
1165 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
1166 for (; ea && i < max_names-1; ea = ea->next)
1169 value[i] = ea->value;
1178 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1179 ODR encode, const char *charset)
1181 char *name[30], *value[30]; /* definite upper limit for SRU params */
1185 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1186 srw_pdu->username, srw_pdu->password);
1187 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1189 yaz_array_to_uri(&uri_args, encode, name, value);
1191 hreq->method = "GET";
1194 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
1196 sprintf(path, "%s?%s", hreq->path, uri_args);
1199 z_HTTP_header_add_content_type(encode, &hreq->headers,
1200 "text/xml", charset);
1204 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1205 ODR encode, const char *charset)
1207 char *name[30], *value[30]; /* definite upper limit for SRU params */
1210 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1211 srw_pdu->username, srw_pdu->password);
1212 if (yaz_get_sru_parms(srw_pdu, encode, name, value, 30))
1215 yaz_array_to_uri(&uri_args, encode, name, value);
1217 hreq->method = "POST";
1219 hreq->content_buf = uri_args;
1220 hreq->content_len = strlen(uri_args);
1222 z_HTTP_header_add_content_type(encode, &hreq->headers,
1223 "application/x-www-form-urlencoded",
1228 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1229 ODR odr, const char *charset)
1231 Z_SOAP_Handler handlers[3] = {
1233 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1234 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1238 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1240 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1241 srw_pdu->username, srw_pdu->password);
1242 z_HTTP_header_add_content_type(odr,
1244 "text/xml", charset);
1246 z_HTTP_header_add(odr, &hreq->headers,
1247 "SOAPAction", "\"\"");
1248 p->which = Z_SOAP_generic;
1249 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1250 p->u.generic->no = 0;
1251 p->u.generic->ns = 0;
1252 p->u.generic->p = srw_pdu;
1253 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1256 if (srw_pdu->which == Z_SRW_update_request ||
1257 srw_pdu->which == Z_SRW_update_response)
1258 p->u.generic->no = 1; /* second handler */
1260 return z_soap_codec_enc(odr, &p,
1262 &hreq->content_len, handlers,
1266 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num )
1268 Z_SRW_recordVersion *ver
1269 = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) );
1271 for ( i=0; i < num; ++i ){
1272 ver[i].versionType = 0;
1273 ver[i].versionValue = 0;
1278 const char *yaz_srw_pack_to_str(int pack)
1282 case Z_SRW_recordPacking_string:
1284 case Z_SRW_recordPacking_XML:
1286 case Z_SRW_recordPacking_URL:
1292 int yaz_srw_str_to_pack(const char *str)
1294 if (!yaz_matchstr(str, "string"))
1295 return Z_SRW_recordPacking_string;
1296 if (!yaz_matchstr(str, "xml"))
1297 return Z_SRW_recordPacking_XML;
1298 if (!yaz_matchstr(str, "url"))
1299 return Z_SRW_recordPacking_URL;
1303 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1309 Z_SRW_extra_arg **ea = &sr->extra_args;
1310 yaz_uri_to_array(extra_args, odr, &name, &val);
1314 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1315 (*ea)->name = *name;
1316 (*ea)->value = *val;
1329 * c-file-style: "Stroustrup"
1330 * indent-tabs-mode: nil
1332 * vim: shiftwidth=4 tabstop=8 expandtab