1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2012 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);
471 yaz_add_srw_diagnostic(decode, diag, num_diag,
472 YAZ_SRW_UNSUPP_PARAMETER, n);
479 yaz_add_srw_diagnostic(
480 decode, diag, num_diag,
481 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
485 version = yaz_negotiate_sru_version(version);
488 { /* negotiation failed. */
489 yaz_add_srw_diagnostic(decode, diag, num_diag,
490 YAZ_SRW_UNSUPP_VERSION, "1.2");
497 yaz_add_srw_diagnostic(
498 decode, diag, num_diag,
499 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
500 operation = "explain";
502 if (!strcmp(operation, "searchRetrieve"))
504 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
506 sr->srw_version = version;
507 sr->extra_args = extra_args;
509 yaz_srw_decodeauth(sr, hreq, username, password, decode);
512 sr->u.request->query_type = Z_SRW_query_type_cql;
513 sr->u.request->query.cql = query;
517 sr->u.request->query_type = Z_SRW_query_type_pqf;
518 sr->u.request->query.pqf = pQuery;
521 yaz_add_srw_diagnostic(
522 decode, diag, num_diag,
523 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
527 sr->u.request->sort_type = Z_SRW_sort_type_sort;
528 sr->u.request->sort.sortKeys = sortKeys;
530 sr->u.request->recordXPath = recordXPath;
531 sr->u.request->recordSchema = recordSchema;
532 sr->u.request->recordPacking = recordPacking;
533 sr->u.request->stylesheet = stylesheet;
535 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
536 &sr->u.request->maximumRecords,
539 yaz_sru_decode_integer(decode, "startRecord", startRecord,
540 &sr->u.request->startRecord,
543 sr->u.request->database = db;
545 (*soap_package) = (Z_SOAP *)
546 odr_malloc(decode, sizeof(**soap_package));
547 (*soap_package)->which = Z_SOAP_generic;
549 (*soap_package)->u.generic = (Z_SOAP_Generic *)
550 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
552 (*soap_package)->u.generic->p = sr;
553 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
554 (*soap_package)->u.generic->no = 0;
556 (*soap_package)->ns = "SRU";
560 else if (!strcmp(operation, "explain"))
562 /* Transfer SRU explain parameters to common struct */
563 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
564 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
566 sr->srw_version = version;
567 sr->extra_args = extra_args;
568 yaz_srw_decodeauth(sr, hreq, username, password, decode);
570 sr->u.explain_request->recordPacking = recordPacking;
571 sr->u.explain_request->database = db;
573 sr->u.explain_request->stylesheet = stylesheet;
575 (*soap_package) = (Z_SOAP *)
576 odr_malloc(decode, sizeof(**soap_package));
577 (*soap_package)->which = Z_SOAP_generic;
579 (*soap_package)->u.generic = (Z_SOAP_Generic *)
580 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
582 (*soap_package)->u.generic->p = sr;
583 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
584 (*soap_package)->u.generic->no = 0;
586 (*soap_package)->ns = "SRU";
590 else if (!strcmp(operation, "scan"))
592 /* Transfer SRU scan parameters to common struct */
593 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
594 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
596 sr->srw_version = version;
597 sr->extra_args = extra_args;
599 yaz_srw_decodeauth(sr, hreq, username, password, decode);
603 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
604 sr->u.scan_request->scanClause.cql = scanClause;
606 else if (pScanClause)
608 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
609 sr->u.scan_request->scanClause.pqf = pScanClause;
612 yaz_add_srw_diagnostic(
613 decode, diag, num_diag,
614 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
615 sr->u.scan_request->database = db;
617 yaz_sru_decode_integer(decode, "maximumTerms",
619 &sr->u.scan_request->maximumTerms,
622 yaz_sru_decode_integer(decode, "responsePosition",
624 &sr->u.scan_request->responsePosition,
627 sr->u.scan_request->stylesheet = stylesheet;
629 (*soap_package) = (Z_SOAP *)
630 odr_malloc(decode, sizeof(**soap_package));
631 (*soap_package)->which = Z_SOAP_generic;
633 (*soap_package)->u.generic = (Z_SOAP_Generic *)
634 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
636 (*soap_package)->u.generic->p = sr;
637 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
638 (*soap_package)->u.generic->no = 0;
640 (*soap_package)->ns = "SRU";
646 /* unsupported operation ... */
647 /* Act as if we received a explain request and throw diagnostic. */
649 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
651 sr->srw_version = version;
653 sr->u.explain_request->recordPacking = recordPacking;
654 sr->u.explain_request->database = db;
656 sr->u.explain_request->stylesheet = stylesheet;
658 (*soap_package) = (Z_SOAP *)
659 odr_malloc(decode, sizeof(**soap_package));
660 (*soap_package)->which = Z_SOAP_generic;
662 (*soap_package)->u.generic = (Z_SOAP_Generic *)
663 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
665 (*soap_package)->u.generic->p = sr;
666 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
667 (*soap_package)->u.generic->no = 0;
669 (*soap_package)->ns = "SRU";
671 yaz_add_srw_diagnostic(decode, diag, num_diag,
672 YAZ_SRW_UNSUPP_OPERATION, operation);
681 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
683 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
684 odr_malloc(o, sizeof(*res));
686 res->extraRecordData_buf = 0;
687 res->extraRecordData_len = 0;
688 res->recordIdentifier = 0;
693 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
695 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
698 for (i = 0; i<n; i++)
700 res[i].recordSchema = 0;
701 res[i].recordPacking = Z_SRW_recordPacking_string;
702 res[i].recordData_buf = 0;
703 res[i].recordData_len = 0;
704 res[i].recordPosition = 0;
709 Z_SRW_record *yaz_srw_get_record(ODR o)
711 return yaz_srw_get_records(o, 1);
714 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
716 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
717 p->srw_version = odr_strdup(o, version);
721 p->extraResponseData_buf = 0;
722 p->extraResponseData_len = 0;
726 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
728 return yaz_srw_get_core_ver(o, "1.1");
731 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
733 return yaz_srw_get_pdu(o, which, "1.1");
736 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
738 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
743 case Z_SRW_searchRetrieve_request:
744 sr->u.request = (Z_SRW_searchRetrieveRequest *)
745 odr_malloc(o, sizeof(*sr->u.request));
746 sr->u.request->query_type = Z_SRW_query_type_cql;
747 sr->u.request->query.cql = 0;
748 sr->u.request->sort_type = Z_SRW_sort_type_none;
749 sr->u.request->sort.none = 0;
750 sr->u.request->startRecord = 0;
751 sr->u.request->maximumRecords = 0;
752 sr->u.request->recordSchema = 0;
753 sr->u.request->recordPacking = 0;
754 sr->u.request->recordXPath = 0;
755 sr->u.request->database = 0;
756 sr->u.request->resultSetTTL = 0;
757 sr->u.request->stylesheet = 0;
758 sr->u.request->facetList = 0;
760 case Z_SRW_searchRetrieve_response:
761 sr->u.response = (Z_SRW_searchRetrieveResponse *)
762 odr_malloc(o, sizeof(*sr->u.response));
763 sr->u.response->numberOfRecords = 0;
764 sr->u.response->resultSetId = 0;
765 sr->u.response->resultSetIdleTime = 0;
766 sr->u.response->records = 0;
767 sr->u.response->num_records = 0;
768 sr->u.response->diagnostics = 0;
769 sr->u.response->num_diagnostics = 0;
770 sr->u.response->nextRecordPosition = 0;
771 sr->u.response->extra_records = 0;
772 sr->u.response->facetList = 0;
773 sr->u.response->suggestions = 0;
775 case Z_SRW_explain_request:
776 sr->u.explain_request = (Z_SRW_explainRequest *)
777 odr_malloc(o, sizeof(*sr->u.explain_request));
778 sr->u.explain_request->recordPacking = 0;
779 sr->u.explain_request->database = 0;
780 sr->u.explain_request->stylesheet = 0;
782 case Z_SRW_explain_response:
783 sr->u.explain_response = (Z_SRW_explainResponse *)
784 odr_malloc(o, sizeof(*sr->u.explain_response));
785 sr->u.explain_response->record.recordData_buf = 0;
786 sr->u.explain_response->record.recordData_len = 0;
787 sr->u.explain_response->record.recordSchema = 0;
788 sr->u.explain_response->record.recordPosition = 0;
789 sr->u.explain_response->record.recordPacking =
790 Z_SRW_recordPacking_string;
791 sr->u.explain_response->diagnostics = 0;
792 sr->u.explain_response->num_diagnostics = 0;
793 sr->u.explain_response->extra_record = 0;
795 case Z_SRW_scan_request:
796 sr->u.scan_request = (Z_SRW_scanRequest *)
797 odr_malloc(o, sizeof(*sr->u.scan_request));
798 sr->u.scan_request->database = 0;
799 sr->u.scan_request->stylesheet = 0;
800 sr->u.scan_request->maximumTerms = 0;
801 sr->u.scan_request->responsePosition = 0;
802 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
803 sr->u.scan_request->scanClause.cql = 0;
805 case Z_SRW_scan_response:
806 sr->u.scan_response = (Z_SRW_scanResponse *)
807 odr_malloc(o, sizeof(*sr->u.scan_response));
808 sr->u.scan_response->terms = 0;
809 sr->u.scan_response->num_terms = 0;
810 sr->u.scan_response->diagnostics = 0;
811 sr->u.scan_response->num_diagnostics = 0;
813 case Z_SRW_update_request:
814 sr->u.update_request = (Z_SRW_updateRequest *)
815 odr_malloc(o, sizeof(*sr->u.update_request));
816 sr->u.update_request->database = 0;
817 sr->u.update_request->stylesheet = 0;
818 sr->u.update_request->record = 0;
819 sr->u.update_request->recordId = 0;
820 sr->u.update_request->recordVersions = 0;
821 sr->u.update_request->num_recordVersions = 0;
822 sr->u.update_request->extra_record = 0;
823 sr->u.update_request->extraRequestData_buf = 0;
824 sr->u.update_request->extraRequestData_len = 0;
825 sr->u.request->database = 0;
827 case Z_SRW_update_response:
828 sr->u.update_response = (Z_SRW_updateResponse *)
829 odr_malloc(o, sizeof(*sr->u.update_response));
830 sr->u.update_response->operationStatus = 0;
831 sr->u.update_response->recordId = 0;
832 sr->u.update_response->recordVersions = 0;
833 sr->u.update_response->num_recordVersions = 0;
834 sr->u.update_response->record = 0;
835 sr->u.update_response->extra_record = 0;
836 sr->u.update_response->extraResponseData_buf = 0;
837 sr->u.update_response->extraResponseData_len = 0;
838 sr->u.update_response->diagnostics = 0;
839 sr->u.update_response->num_diagnostics = 0;
844 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
845 char *a_name, Odr_int *val)
850 value[*i] = (char *) odr_malloc(o, 40);
851 sprintf(value[*i], ODR_INT_PRINTF, *val);
856 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
857 char *a_name, char *val)
867 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
868 char **name, char **value, int max_names)
871 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
872 name[i] = "operation";
873 switch(srw_pdu->which)
875 case Z_SRW_searchRetrieve_request:
876 value[i++] = "searchRetrieve";
877 switch(srw_pdu->u.request->query_type)
879 case Z_SRW_query_type_cql:
880 yaz_add_name_value_str(encode, name, value, &i, "query",
881 srw_pdu->u.request->query.cql);
883 case Z_SRW_query_type_pqf:
884 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
885 srw_pdu->u.request->query.pqf);
887 case Z_SRW_query_type_xcql:
888 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
889 srw_pdu->u.request->query.xcql);
892 switch(srw_pdu->u.request->sort_type)
894 case Z_SRW_sort_type_none:
896 case Z_SRW_sort_type_sort:
897 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
898 srw_pdu->u.request->sort.sortKeys);
901 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
902 srw_pdu->u.request->startRecord);
903 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
904 srw_pdu->u.request->maximumRecords);
905 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
906 srw_pdu->u.request->recordSchema);
907 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
908 srw_pdu->u.request->recordPacking);
909 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
910 srw_pdu->u.request->recordXPath);
911 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
912 srw_pdu->u.request->stylesheet);
913 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
914 srw_pdu->u.request->resultSetTTL);
916 case Z_SRW_explain_request:
917 value[i++] = "explain";
918 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
919 srw_pdu->u.explain_request->stylesheet);
921 case Z_SRW_scan_request:
924 switch(srw_pdu->u.scan_request->query_type)
926 case Z_SRW_query_type_cql:
927 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
928 srw_pdu->u.scan_request->scanClause.cql);
930 case Z_SRW_query_type_pqf:
931 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
932 srw_pdu->u.scan_request->scanClause.pqf);
934 case Z_SRW_query_type_xcql:
935 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
936 srw_pdu->u.scan_request->scanClause.xcql);
939 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
940 srw_pdu->u.scan_request->responsePosition);
941 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
942 srw_pdu->u.scan_request->maximumTerms);
943 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
944 srw_pdu->u.scan_request->stylesheet);
946 case Z_SRW_update_request:
947 value[i++] = "update";
952 if (srw_pdu->extra_args)
954 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
955 for (; ea && i < max_names-1; ea = ea->next)
958 value[i] = ea->value;
967 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
968 ODR encode, const char *charset)
970 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
974 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
975 srw_pdu->username, srw_pdu->password);
976 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
978 yaz_array_to_uri(&uri_args, encode, name, value);
980 hreq->method = "GET";
983 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
985 sprintf(path, "%s?%s", hreq->path, uri_args);
986 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
989 z_HTTP_header_add_content_type(encode, &hreq->headers,
990 "text/xml", charset);
994 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
995 ODR encode, const char *charset)
997 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1000 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1001 srw_pdu->username, srw_pdu->password);
1002 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1005 yaz_array_to_uri(&uri_args, encode, name, value);
1007 hreq->method = "POST";
1009 hreq->content_buf = uri_args;
1010 hreq->content_len = strlen(uri_args);
1012 z_HTTP_header_add_content_type(encode, &hreq->headers,
1013 "application/x-www-form-urlencoded",
1018 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1019 ODR odr, const char *charset)
1021 Z_SOAP_Handler handlers[3] = {
1023 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1024 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1028 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1030 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1031 srw_pdu->username, srw_pdu->password);
1032 z_HTTP_header_add_content_type(odr,
1034 "text/xml", charset);
1036 z_HTTP_header_add(odr, &hreq->headers,
1037 "SOAPAction", "\"\"");
1038 p->which = Z_SOAP_generic;
1039 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1040 p->u.generic->no = 0;
1041 p->u.generic->ns = 0;
1042 p->u.generic->p = srw_pdu;
1043 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1046 if (srw_pdu->which == Z_SRW_update_request ||
1047 srw_pdu->which == Z_SRW_update_response)
1048 p->u.generic->no = 1; /* second handler */
1050 return z_soap_codec_enc(odr, &p,
1052 &hreq->content_len, handlers,
1056 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1058 Z_SRW_recordVersion *ver
1059 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1061 for (i = 0; i < num; ++i)
1063 ver[i].versionType = 0;
1064 ver[i].versionValue = 0;
1069 const char *yaz_srw_pack_to_str(int pack)
1073 case Z_SRW_recordPacking_string:
1075 case Z_SRW_recordPacking_XML:
1077 case Z_SRW_recordPacking_URL:
1083 int yaz_srw_str_to_pack(const char *str)
1085 if (!yaz_matchstr(str, "string"))
1086 return Z_SRW_recordPacking_string;
1087 if (!yaz_matchstr(str, "xml"))
1088 return Z_SRW_recordPacking_XML;
1089 if (!yaz_matchstr(str, "url"))
1090 return Z_SRW_recordPacking_URL;
1094 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1100 Z_SRW_extra_arg **ea = &sr->extra_args;
1101 yaz_uri_to_array(extra_args, odr, &name, &val);
1105 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1106 (*ea)->name = *name;
1107 (*ea)->value = *val;
1120 * c-file-style: "Stroustrup"
1121 * indent-tabs-mode: nil
1123 * vim: shiftwidth=4 tabstop=8 expandtab