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/base64.h>
18 #include <yaz/yaz-iconv.h>
21 #define MAX_SRU_PARAMETERS 30
23 static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
25 return odr_strdupn(n, uri, len);
28 void yaz_encode_sru_dbpath_buf(char *dst, const char *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);
42 Z_AttributeList *yaz_use_attribute_create(ODR o, const char *name)
44 Z_AttributeList *attributes= (Z_AttributeList *)
45 odr_malloc(o, sizeof(*attributes));
46 Z_AttributeElement ** elements;
47 attributes->num_attributes = 1;
48 elements = (Z_AttributeElement**)
49 odr_malloc(o, attributes->num_attributes * sizeof(*elements));
50 elements[0] = (Z_AttributeElement*) odr_malloc(o,sizeof(**elements));
51 elements[0]->attributeType = odr_intdup(o, 1);
52 elements[0]->attributeSet = odr_nullval();
53 elements[0]->which = Z_AttributeValue_complex;
54 elements[0]->value.complex = (Z_ComplexAttribute *)
55 odr_malloc(o, sizeof(Z_ComplexAttribute));
56 elements[0]->value.complex->num_list = 1;
57 elements[0]->value.complex->list = (Z_StringOrNumeric **)
58 odr_malloc(o, 1 * sizeof(Z_StringOrNumeric *));
59 elements[0]->value.complex->list[0] = (Z_StringOrNumeric *)
60 odr_malloc(o, sizeof(Z_StringOrNumeric));
61 elements[0]->value.complex->list[0]->which = Z_StringOrNumeric_string;
62 elements[0]->value.complex->list[0]->u.string = odr_strdup(o, name);
63 elements[0]->value.complex->semanticAction = 0;
64 elements[0]->value.complex->num_semanticAction = 0;
65 attributes->attributes = elements;
70 const char *yaz_element_attribute_value_get(xmlNodePtr ptr,
71 const char *node_name,
72 const char *attribute_name)
74 struct _xmlAttr *attr;
75 // check if the node name matches
76 if (strcmp((const char*) ptr->name, node_name))
78 // check if the attribute name and return the value
79 for (attr = ptr->properties; attr; attr = attr->next)
80 if (attr->children && attr->children->type == XML_TEXT_NODE)
82 if (!strcmp((const char *) attr->name, attribute_name))
83 return (const char *) attr->children->content;
89 int yaz_srw_check_content_type(Z_HTTP_Response *hres)
91 const char *content_type = z_HTTP_header_lookup(hres->headers,
95 if (!yaz_strcmp_del("text/xml", content_type, "; "))
97 if (!yaz_strcmp_del("application/xml", content_type, "; "))
104 * Look for authentication tokens in HTTP Basic parameters or in x-username/x-password
105 * parameters. Added by SH.
107 static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
108 char *username, char *password, ODR decode)
110 const char *basic = z_HTTP_header_lookup(hreq->headers, "Authorization");
113 sr->username = username;
115 sr->password = password;
121 char ubuf[256] = "", pbuf[256] = "", *p;
122 if (strncmp(basic, "Basic ", 6))
126 if (!len || len > 256)
128 yaz_base64decode(basic, out);
129 /* Format of out should be username:password at this point */
131 if ((p = strchr(ubuf, ':')))
138 sr->username = odr_strdup(decode, ubuf);
140 sr->password = odr_strdup(decode, pbuf);
144 void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
146 const char *v = yaz_uri_val(path, name, o);
148 *intp = odr_intdup(o, atoi(v));
151 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d,
152 const char *uri, const char *message,
155 d->uri = odr_strdup(o, uri);
157 d->message = odr_strdup(o, message);
161 d->details = odr_strdup(o, details);
166 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d,
167 int code, const char *details)
171 sprintf(uri, "info:srw/diagnostic/1/%d", code);
172 yaz_mk_srw_diagnostic(o, d, uri, 0, details);
175 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
176 int *num, const char *uri,
177 const char *message, const char *details)
179 Z_SRW_diagnostic *d_new;
180 d_new = (Z_SRW_diagnostic *) odr_malloc(o, (*num + 1)* sizeof(**d));
182 memcpy(d_new, *d, *num *sizeof(**d));
185 yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
189 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
190 int *num, int code, const char *addinfo)
194 sprintf(uri, "info:srw/diagnostic/1/%d", code);
195 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
199 void yaz_add_sru_update_diagnostic(ODR o, Z_SRW_diagnostic **d,
200 int *num, int code, const char *addinfo)
204 sprintf(uri, "info:srw/diagnostic/12/%d", code);
205 yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
209 void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
210 int code, const char *details)
212 const char *message = yaz_diag_srw_str(code);
215 len += strlen(message);
217 len += strlen(details);
219 record->recordData_buf = (char *) odr_malloc(o, len);
221 sprintf(record->recordData_buf, "<diagnostic "
222 "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
223 " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
225 sprintf(record->recordData_buf + strlen(record->recordData_buf),
226 " <details>%s</details>\n", details);
228 sprintf(record->recordData_buf + strlen(record->recordData_buf),
229 " <message>%s</message>\n", message);
230 sprintf(record->recordData_buf + strlen(record->recordData_buf),
232 record->recordData_len = strlen(record->recordData_buf);
233 record->recordPosition = odr_intdup(o, pos);
234 record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
237 static void grab_charset(ODR o, const char *content_type, char **charset)
241 const char *charset_p = 0;
242 if (content_type && (charset_p = strstr(content_type, "; charset=")))
246 while (i < 20 && charset_p[i] &&
247 !strchr("; \n\r", charset_p[i]))
249 *charset = (char*) odr_malloc(o, i+1);
250 memcpy(*charset, charset_p, i);
251 (*charset)[i] = '\0';
256 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
257 Z_SOAP **soap_package, ODR decode, char **charset)
259 if (!strcmp(hreq->method, "POST"))
261 const char *content_type = z_HTTP_header_lookup(hreq->headers,
264 (!yaz_strcmp_del("text/xml", content_type, "; ") ||
265 !yaz_strcmp_del("application/soap+xml", content_type, "; ") ||
266 !yaz_strcmp_del("text/plain", content_type, "; ")))
268 char *db = "Default";
269 const char *p0 = hreq->path, *p1;
272 static Z_SOAP_Handler soap_handlers[4] = {
274 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec },
275 { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec },
276 { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec },
283 p1 = strchr(p0, '?');
285 p1 = p0 + strlen(p0);
287 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
288 grab_charset(decode, content_type, charset);
290 ret = z_soap_codec(decode, soap_package,
291 &hreq->content_buf, &hreq->content_len,
293 if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
295 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
296 yaz_srw_decodeauth(*srw_pdu, hreq, 0, 0, decode);
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 Z_SRW_extra_arg *extra_args = 0;
400 grab_charset(decode, content_type, charset);
401 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
406 p1 = strchr(p0, '?');
408 p1 = p0 + strlen(p0);
410 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
411 if (!strcmp(hreq->method, "POST"))
412 p1 = hreq->content_buf;
413 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
418 for (i = 0; uri_name[i]; i++)
420 char *n = uri_name[i];
421 char *v = uri_val[i];
422 if (!strcmp(n, "query"))
424 else if (!strcmp(n, "x-pquery"))
426 else if (!strcmp(n, "x-username"))
428 else if (!strcmp(n, "x-password"))
430 else if (!strcmp(n, "operation"))
432 else if (!strcmp(n, "stylesheet"))
434 else if (!strcmp(n, "sortKeys"))
436 else if (!strcmp(n, "recordXPath"))
438 else if (!strcmp(n, "recordSchema"))
440 else if (!strcmp(n, "recordPacking"))
442 else if (!strcmp(n, "version"))
444 else if (!strcmp(n, "scanClause"))
446 else if (!strcmp(n, "x-pScanClause"))
448 else if (!strcmp(n, "maximumRecords"))
450 else if (!strcmp(n, "startRecord"))
452 else if (!strcmp(n, "maximumTerms"))
454 else if (!strcmp(n, "responsePosition"))
455 responsePosition = v;
456 else if (!strcmp(n, "extraRequestData"))
457 ; /* ignoring extraRequestData */
458 else if (n[0] == 'x' && n[1] == '-')
460 Z_SRW_extra_arg **l = &extra_args;
463 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
464 (*l)->name = odr_strdup(decode, n);
465 (*l)->value = odr_strdup(decode, v);
469 yaz_add_srw_diagnostic(decode, diag, num_diag,
470 YAZ_SRW_UNSUPP_PARAMETER, n);
476 yaz_add_srw_diagnostic(
477 decode, diag, num_diag,
478 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
482 version = yaz_negotiate_sru_version(version);
485 { /* negotiation failed. */
486 yaz_add_srw_diagnostic(decode, diag, num_diag,
487 YAZ_SRW_UNSUPP_VERSION, "1.2");
494 yaz_add_srw_diagnostic(
495 decode, diag, num_diag,
496 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
497 operation = "explain";
499 if (!strcmp(operation, "searchRetrieve"))
501 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
503 sr->srw_version = version;
504 sr->extra_args = extra_args;
506 yaz_srw_decodeauth(sr, hreq, username, password, decode);
509 sr->u.request->query_type = Z_SRW_query_type_cql;
510 sr->u.request->query.cql = query;
514 sr->u.request->query_type = Z_SRW_query_type_pqf;
515 sr->u.request->query.pqf = pQuery;
518 yaz_add_srw_diagnostic(
519 decode, diag, num_diag,
520 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
524 sr->u.request->sort_type = Z_SRW_sort_type_sort;
525 sr->u.request->sort.sortKeys = sortKeys;
527 sr->u.request->recordXPath = recordXPath;
528 sr->u.request->recordSchema = recordSchema;
529 sr->u.request->recordPacking = recordPacking;
530 sr->u.request->stylesheet = stylesheet;
532 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
533 &sr->u.request->maximumRecords,
536 yaz_sru_decode_integer(decode, "startRecord", startRecord,
537 &sr->u.request->startRecord,
540 sr->u.request->database = db;
542 (*soap_package) = (Z_SOAP *)
543 odr_malloc(decode, sizeof(**soap_package));
544 (*soap_package)->which = Z_SOAP_generic;
546 (*soap_package)->u.generic = (Z_SOAP_Generic *)
547 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
549 (*soap_package)->u.generic->p = sr;
550 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
551 (*soap_package)->u.generic->no = 0;
553 (*soap_package)->ns = "SRU";
557 else if (!strcmp(operation, "explain"))
559 /* Transfer SRU explain parameters to common struct */
560 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
561 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
563 sr->srw_version = version;
564 sr->extra_args = extra_args;
565 yaz_srw_decodeauth(sr, hreq, username, password, decode);
567 sr->u.explain_request->recordPacking = recordPacking;
568 sr->u.explain_request->database = db;
570 sr->u.explain_request->stylesheet = stylesheet;
572 (*soap_package) = (Z_SOAP *)
573 odr_malloc(decode, sizeof(**soap_package));
574 (*soap_package)->which = Z_SOAP_generic;
576 (*soap_package)->u.generic = (Z_SOAP_Generic *)
577 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
579 (*soap_package)->u.generic->p = sr;
580 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
581 (*soap_package)->u.generic->no = 0;
583 (*soap_package)->ns = "SRU";
587 else if (!strcmp(operation, "scan"))
589 /* Transfer SRU scan parameters to common struct */
590 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
591 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
593 sr->srw_version = version;
594 sr->extra_args = extra_args;
596 yaz_srw_decodeauth(sr, hreq, username, password, decode);
600 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
601 sr->u.scan_request->scanClause.cql = scanClause;
603 else if (pScanClause)
605 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
606 sr->u.scan_request->scanClause.pqf = pScanClause;
609 yaz_add_srw_diagnostic(
610 decode, diag, num_diag,
611 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
612 sr->u.scan_request->database = db;
614 yaz_sru_decode_integer(decode, "maximumTerms",
616 &sr->u.scan_request->maximumTerms,
619 yaz_sru_decode_integer(decode, "responsePosition",
621 &sr->u.scan_request->responsePosition,
624 sr->u.scan_request->stylesheet = stylesheet;
626 (*soap_package) = (Z_SOAP *)
627 odr_malloc(decode, sizeof(**soap_package));
628 (*soap_package)->which = Z_SOAP_generic;
630 (*soap_package)->u.generic = (Z_SOAP_Generic *)
631 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
633 (*soap_package)->u.generic->p = sr;
634 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
635 (*soap_package)->u.generic->no = 0;
637 (*soap_package)->ns = "SRU";
643 /* unsupported operation ... */
644 /* Act as if we received a explain request and throw diagnostic. */
646 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
648 sr->srw_version = version;
650 sr->u.explain_request->recordPacking = recordPacking;
651 sr->u.explain_request->database = db;
653 sr->u.explain_request->stylesheet = stylesheet;
655 (*soap_package) = (Z_SOAP *)
656 odr_malloc(decode, sizeof(**soap_package));
657 (*soap_package)->which = Z_SOAP_generic;
659 (*soap_package)->u.generic = (Z_SOAP_Generic *)
660 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
662 (*soap_package)->u.generic->p = sr;
663 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
664 (*soap_package)->u.generic->no = 0;
666 (*soap_package)->ns = "SRU";
668 yaz_add_srw_diagnostic(decode, diag, num_diag,
669 YAZ_SRW_UNSUPP_OPERATION, operation);
678 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
680 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
681 odr_malloc(o, sizeof(*res));
683 res->extraRecordData_buf = 0;
684 res->extraRecordData_len = 0;
685 res->recordIdentifier = 0;
690 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
692 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
695 for (i = 0; i<n; i++)
697 res[i].recordSchema = 0;
698 res[i].recordPacking = Z_SRW_recordPacking_string;
699 res[i].recordData_buf = 0;
700 res[i].recordData_len = 0;
701 res[i].recordPosition = 0;
706 Z_SRW_record *yaz_srw_get_record(ODR o)
708 return yaz_srw_get_records(o, 1);
711 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
713 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
714 p->srw_version = odr_strdup(o, version);
718 p->extraResponseData_buf = 0;
719 p->extraResponseData_len = 0;
723 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
725 return yaz_srw_get_core_ver(o, "1.1");
728 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
730 return yaz_srw_get_pdu(o, which, "1.1");
733 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
735 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
740 case Z_SRW_searchRetrieve_request:
741 sr->u.request = (Z_SRW_searchRetrieveRequest *)
742 odr_malloc(o, sizeof(*sr->u.request));
743 sr->u.request->query_type = Z_SRW_query_type_cql;
744 sr->u.request->query.cql = 0;
745 sr->u.request->sort_type = Z_SRW_sort_type_none;
746 sr->u.request->sort.none = 0;
747 sr->u.request->startRecord = 0;
748 sr->u.request->maximumRecords = 0;
749 sr->u.request->recordSchema = 0;
750 sr->u.request->recordPacking = 0;
751 sr->u.request->recordXPath = 0;
752 sr->u.request->database = 0;
753 sr->u.request->resultSetTTL = 0;
754 sr->u.request->stylesheet = 0;
755 sr->u.request->facetList = 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;
769 sr->u.response->facetList = 0;
770 sr->u.response->suggestions = 0;
772 case Z_SRW_explain_request:
773 sr->u.explain_request = (Z_SRW_explainRequest *)
774 odr_malloc(o, sizeof(*sr->u.explain_request));
775 sr->u.explain_request->recordPacking = 0;
776 sr->u.explain_request->database = 0;
777 sr->u.explain_request->stylesheet = 0;
779 case Z_SRW_explain_response:
780 sr->u.explain_response = (Z_SRW_explainResponse *)
781 odr_malloc(o, sizeof(*sr->u.explain_response));
782 sr->u.explain_response->record.recordData_buf = 0;
783 sr->u.explain_response->record.recordData_len = 0;
784 sr->u.explain_response->record.recordSchema = 0;
785 sr->u.explain_response->record.recordPosition = 0;
786 sr->u.explain_response->record.recordPacking =
787 Z_SRW_recordPacking_string;
788 sr->u.explain_response->diagnostics = 0;
789 sr->u.explain_response->num_diagnostics = 0;
790 sr->u.explain_response->extra_record = 0;
792 case Z_SRW_scan_request:
793 sr->u.scan_request = (Z_SRW_scanRequest *)
794 odr_malloc(o, sizeof(*sr->u.scan_request));
795 sr->u.scan_request->database = 0;
796 sr->u.scan_request->stylesheet = 0;
797 sr->u.scan_request->maximumTerms = 0;
798 sr->u.scan_request->responsePosition = 0;
799 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
800 sr->u.scan_request->scanClause.cql = 0;
802 case Z_SRW_scan_response:
803 sr->u.scan_response = (Z_SRW_scanResponse *)
804 odr_malloc(o, sizeof(*sr->u.scan_response));
805 sr->u.scan_response->terms = 0;
806 sr->u.scan_response->num_terms = 0;
807 sr->u.scan_response->diagnostics = 0;
808 sr->u.scan_response->num_diagnostics = 0;
810 case Z_SRW_update_request:
811 sr->u.update_request = (Z_SRW_updateRequest *)
812 odr_malloc(o, sizeof(*sr->u.update_request));
813 sr->u.update_request->database = 0;
814 sr->u.update_request->stylesheet = 0;
815 sr->u.update_request->record = 0;
816 sr->u.update_request->recordId = 0;
817 sr->u.update_request->recordVersions = 0;
818 sr->u.update_request->num_recordVersions = 0;
819 sr->u.update_request->extra_record = 0;
820 sr->u.update_request->extraRequestData_buf = 0;
821 sr->u.update_request->extraRequestData_len = 0;
822 sr->u.request->database = 0;
824 case Z_SRW_update_response:
825 sr->u.update_response = (Z_SRW_updateResponse *)
826 odr_malloc(o, sizeof(*sr->u.update_response));
827 sr->u.update_response->operationStatus = 0;
828 sr->u.update_response->recordId = 0;
829 sr->u.update_response->recordVersions = 0;
830 sr->u.update_response->num_recordVersions = 0;
831 sr->u.update_response->record = 0;
832 sr->u.update_response->extra_record = 0;
833 sr->u.update_response->extraResponseData_buf = 0;
834 sr->u.update_response->extraResponseData_len = 0;
835 sr->u.update_response->diagnostics = 0;
836 sr->u.update_response->num_diagnostics = 0;
841 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
842 char *a_name, Odr_int *val)
847 value[*i] = (char *) odr_malloc(o, 40);
848 sprintf(value[*i], ODR_INT_PRINTF, *val);
853 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
854 char *a_name, char *val)
864 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
865 char **name, char **value, int max_names)
868 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
869 name[i] = "operation";
870 switch(srw_pdu->which)
872 case Z_SRW_searchRetrieve_request:
873 value[i++] = "searchRetrieve";
874 switch(srw_pdu->u.request->query_type)
876 case Z_SRW_query_type_cql:
877 yaz_add_name_value_str(encode, name, value, &i, "query",
878 srw_pdu->u.request->query.cql);
880 case Z_SRW_query_type_pqf:
881 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
882 srw_pdu->u.request->query.pqf);
884 case Z_SRW_query_type_xcql:
885 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
886 srw_pdu->u.request->query.xcql);
889 switch(srw_pdu->u.request->sort_type)
891 case Z_SRW_sort_type_none:
893 case Z_SRW_sort_type_sort:
894 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
895 srw_pdu->u.request->sort.sortKeys);
898 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
899 srw_pdu->u.request->startRecord);
900 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
901 srw_pdu->u.request->maximumRecords);
902 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
903 srw_pdu->u.request->recordSchema);
904 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
905 srw_pdu->u.request->recordPacking);
906 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
907 srw_pdu->u.request->recordXPath);
908 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
909 srw_pdu->u.request->stylesheet);
910 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
911 srw_pdu->u.request->resultSetTTL);
913 case Z_SRW_explain_request:
914 value[i++] = "explain";
915 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
916 srw_pdu->u.explain_request->stylesheet);
918 case Z_SRW_scan_request:
921 switch(srw_pdu->u.scan_request->query_type)
923 case Z_SRW_query_type_cql:
924 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
925 srw_pdu->u.scan_request->scanClause.cql);
927 case Z_SRW_query_type_pqf:
928 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
929 srw_pdu->u.scan_request->scanClause.pqf);
931 case Z_SRW_query_type_xcql:
932 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
933 srw_pdu->u.scan_request->scanClause.xcql);
936 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
937 srw_pdu->u.scan_request->responsePosition);
938 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
939 srw_pdu->u.scan_request->maximumTerms);
940 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
941 srw_pdu->u.scan_request->stylesheet);
943 case Z_SRW_update_request:
944 value[i++] = "update";
949 if (srw_pdu->extra_args)
951 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
952 for (; ea && i < max_names-1; ea = ea->next)
955 value[i] = ea->value;
964 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
965 ODR encode, const char *charset)
967 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
971 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
972 srw_pdu->username, srw_pdu->password);
973 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
975 yaz_array_to_uri(&uri_args, encode, name, value);
977 hreq->method = "GET";
980 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
982 sprintf(path, "%s?%s", hreq->path, uri_args);
983 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
986 z_HTTP_header_add_content_type(encode, &hreq->headers,
987 "text/xml", charset);
991 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
992 ODR encode, const char *charset)
994 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
997 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
998 srw_pdu->username, srw_pdu->password);
999 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1002 yaz_array_to_uri(&uri_args, encode, name, value);
1004 hreq->method = "POST";
1006 hreq->content_buf = uri_args;
1007 hreq->content_len = strlen(uri_args);
1009 z_HTTP_header_add_content_type(encode, &hreq->headers,
1010 "application/x-www-form-urlencoded",
1015 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1016 ODR odr, const char *charset)
1018 Z_SOAP_Handler handlers[3] = {
1020 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1021 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1025 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1027 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1028 srw_pdu->username, srw_pdu->password);
1029 z_HTTP_header_add_content_type(odr,
1031 "text/xml", charset);
1033 z_HTTP_header_add(odr, &hreq->headers,
1034 "SOAPAction", "\"\"");
1035 p->which = Z_SOAP_generic;
1036 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1037 p->u.generic->no = 0;
1038 p->u.generic->ns = 0;
1039 p->u.generic->p = srw_pdu;
1040 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1043 if (srw_pdu->which == Z_SRW_update_request ||
1044 srw_pdu->which == Z_SRW_update_response)
1045 p->u.generic->no = 1; /* second handler */
1047 return z_soap_codec_enc(odr, &p,
1049 &hreq->content_len, handlers,
1053 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1055 Z_SRW_recordVersion *ver
1056 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1058 for (i = 0; i < num; ++i)
1060 ver[i].versionType = 0;
1061 ver[i].versionValue = 0;
1066 const char *yaz_srw_pack_to_str(int pack)
1070 case Z_SRW_recordPacking_string:
1072 case Z_SRW_recordPacking_XML:
1074 case Z_SRW_recordPacking_URL:
1080 int yaz_srw_str_to_pack(const char *str)
1082 if (!yaz_matchstr(str, "string"))
1083 return Z_SRW_recordPacking_string;
1084 if (!yaz_matchstr(str, "xml"))
1085 return Z_SRW_recordPacking_XML;
1086 if (!yaz_matchstr(str, "url"))
1087 return Z_SRW_recordPacking_URL;
1091 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1097 Z_SRW_extra_arg **ea = &sr->extra_args;
1098 yaz_uri_to_array(extra_args, odr, &name, &val);
1102 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1103 (*ea)->name = *name;
1104 (*ea)->value = *val;
1117 * c-file-style: "Stroustrup"
1118 * indent-tabs-mode: nil
1120 * vim: shiftwidth=4 tabstop=8 expandtab