1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2013 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);
682 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
684 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
685 odr_malloc(o, sizeof(*res));
687 res->extraRecordData_buf = 0;
688 res->extraRecordData_len = 0;
689 res->recordIdentifier = 0;
694 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
696 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
699 for (i = 0; i<n; i++)
701 res[i].recordSchema = 0;
702 res[i].recordPacking = Z_SRW_recordPacking_string;
703 res[i].recordData_buf = 0;
704 res[i].recordData_len = 0;
705 res[i].recordPosition = 0;
710 Z_SRW_record *yaz_srw_get_record(ODR o)
712 return yaz_srw_get_records(o, 1);
715 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
717 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
718 p->srw_version = odr_strdup(o, version);
722 p->extraResponseData_buf = 0;
723 p->extraResponseData_len = 0;
727 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
729 return yaz_srw_get_core_ver(o, "1.1");
732 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
734 return yaz_srw_get_pdu(o, which, "1.1");
737 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
739 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
744 case Z_SRW_searchRetrieve_request:
745 sr->u.request = (Z_SRW_searchRetrieveRequest *)
746 odr_malloc(o, sizeof(*sr->u.request));
747 sr->u.request->query_type = Z_SRW_query_type_cql;
748 sr->u.request->query.cql = 0;
749 sr->u.request->sort_type = Z_SRW_sort_type_none;
750 sr->u.request->sort.none = 0;
751 sr->u.request->startRecord = 0;
752 sr->u.request->maximumRecords = 0;
753 sr->u.request->recordSchema = 0;
754 sr->u.request->recordPacking = 0;
755 sr->u.request->recordXPath = 0;
756 sr->u.request->database = 0;
757 sr->u.request->resultSetTTL = 0;
758 sr->u.request->stylesheet = 0;
759 sr->u.request->facetList = 0;
761 case Z_SRW_searchRetrieve_response:
762 sr->u.response = (Z_SRW_searchRetrieveResponse *)
763 odr_malloc(o, sizeof(*sr->u.response));
764 sr->u.response->numberOfRecords = 0;
765 sr->u.response->resultSetId = 0;
766 sr->u.response->resultSetIdleTime = 0;
767 sr->u.response->records = 0;
768 sr->u.response->num_records = 0;
769 sr->u.response->diagnostics = 0;
770 sr->u.response->num_diagnostics = 0;
771 sr->u.response->nextRecordPosition = 0;
772 sr->u.response->extra_records = 0;
773 sr->u.response->facetList = 0;
774 sr->u.response->suggestions = 0;
776 case Z_SRW_explain_request:
777 sr->u.explain_request = (Z_SRW_explainRequest *)
778 odr_malloc(o, sizeof(*sr->u.explain_request));
779 sr->u.explain_request->recordPacking = 0;
780 sr->u.explain_request->database = 0;
781 sr->u.explain_request->stylesheet = 0;
783 case Z_SRW_explain_response:
784 sr->u.explain_response = (Z_SRW_explainResponse *)
785 odr_malloc(o, sizeof(*sr->u.explain_response));
786 sr->u.explain_response->record.recordData_buf = 0;
787 sr->u.explain_response->record.recordData_len = 0;
788 sr->u.explain_response->record.recordSchema = 0;
789 sr->u.explain_response->record.recordPosition = 0;
790 sr->u.explain_response->record.recordPacking =
791 Z_SRW_recordPacking_string;
792 sr->u.explain_response->diagnostics = 0;
793 sr->u.explain_response->num_diagnostics = 0;
794 sr->u.explain_response->extra_record = 0;
796 case Z_SRW_scan_request:
797 sr->u.scan_request = (Z_SRW_scanRequest *)
798 odr_malloc(o, sizeof(*sr->u.scan_request));
799 sr->u.scan_request->database = 0;
800 sr->u.scan_request->stylesheet = 0;
801 sr->u.scan_request->maximumTerms = 0;
802 sr->u.scan_request->responsePosition = 0;
803 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
804 sr->u.scan_request->scanClause.cql = 0;
806 case Z_SRW_scan_response:
807 sr->u.scan_response = (Z_SRW_scanResponse *)
808 odr_malloc(o, sizeof(*sr->u.scan_response));
809 sr->u.scan_response->terms = 0;
810 sr->u.scan_response->num_terms = 0;
811 sr->u.scan_response->diagnostics = 0;
812 sr->u.scan_response->num_diagnostics = 0;
814 case Z_SRW_update_request:
815 sr->u.update_request = (Z_SRW_updateRequest *)
816 odr_malloc(o, sizeof(*sr->u.update_request));
817 sr->u.update_request->database = 0;
818 sr->u.update_request->stylesheet = 0;
819 sr->u.update_request->record = 0;
820 sr->u.update_request->recordId = 0;
821 sr->u.update_request->recordVersions = 0;
822 sr->u.update_request->num_recordVersions = 0;
823 sr->u.update_request->extra_record = 0;
824 sr->u.update_request->extraRequestData_buf = 0;
825 sr->u.update_request->extraRequestData_len = 0;
826 sr->u.request->database = 0;
828 case Z_SRW_update_response:
829 sr->u.update_response = (Z_SRW_updateResponse *)
830 odr_malloc(o, sizeof(*sr->u.update_response));
831 sr->u.update_response->operationStatus = 0;
832 sr->u.update_response->recordId = 0;
833 sr->u.update_response->recordVersions = 0;
834 sr->u.update_response->num_recordVersions = 0;
835 sr->u.update_response->record = 0;
836 sr->u.update_response->extra_record = 0;
837 sr->u.update_response->extraResponseData_buf = 0;
838 sr->u.update_response->extraResponseData_len = 0;
839 sr->u.update_response->diagnostics = 0;
840 sr->u.update_response->num_diagnostics = 0;
845 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
846 char *a_name, Odr_int *val)
851 value[*i] = (char *) odr_malloc(o, 40);
852 sprintf(value[*i], ODR_INT_PRINTF, *val);
857 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
858 char *a_name, char *val)
868 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
869 char **name, char **value, int max_names)
872 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
873 name[i] = "operation";
874 switch(srw_pdu->which)
876 case Z_SRW_searchRetrieve_request:
877 value[i++] = "searchRetrieve";
878 switch(srw_pdu->u.request->query_type)
880 case Z_SRW_query_type_cql:
881 yaz_add_name_value_str(encode, name, value, &i, "query",
882 srw_pdu->u.request->query.cql);
884 case Z_SRW_query_type_pqf:
885 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
886 srw_pdu->u.request->query.pqf);
888 case Z_SRW_query_type_xcql:
889 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
890 srw_pdu->u.request->query.xcql);
893 switch(srw_pdu->u.request->sort_type)
895 case Z_SRW_sort_type_none:
897 case Z_SRW_sort_type_sort:
898 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
899 srw_pdu->u.request->sort.sortKeys);
902 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
903 srw_pdu->u.request->startRecord);
904 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
905 srw_pdu->u.request->maximumRecords);
906 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
907 srw_pdu->u.request->recordSchema);
908 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
909 srw_pdu->u.request->recordPacking);
910 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
911 srw_pdu->u.request->recordXPath);
912 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
913 srw_pdu->u.request->stylesheet);
914 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
915 srw_pdu->u.request->resultSetTTL);
917 case Z_SRW_explain_request:
918 value[i++] = "explain";
919 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
920 srw_pdu->u.explain_request->stylesheet);
922 case Z_SRW_scan_request:
925 switch(srw_pdu->u.scan_request->query_type)
927 case Z_SRW_query_type_cql:
928 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
929 srw_pdu->u.scan_request->scanClause.cql);
931 case Z_SRW_query_type_pqf:
932 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
933 srw_pdu->u.scan_request->scanClause.pqf);
935 case Z_SRW_query_type_xcql:
936 yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause",
937 srw_pdu->u.scan_request->scanClause.xcql);
940 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
941 srw_pdu->u.scan_request->responsePosition);
942 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
943 srw_pdu->u.scan_request->maximumTerms);
944 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
945 srw_pdu->u.scan_request->stylesheet);
947 case Z_SRW_update_request:
948 value[i++] = "update";
953 if (srw_pdu->extra_args)
955 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
956 for (; ea && i < max_names-1; ea = ea->next)
959 value[i] = ea->value;
968 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
969 ODR encode, const char *charset)
971 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
975 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
976 srw_pdu->username, srw_pdu->password);
977 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
979 yaz_array_to_uri(&uri_args, encode, name, value);
981 hreq->method = "GET";
984 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
986 sprintf(path, "%s?%s", hreq->path, uri_args);
987 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
990 z_HTTP_header_add_content_type(encode, &hreq->headers,
991 "text/xml", charset);
995 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
996 ODR encode, const char *charset)
998 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1001 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1002 srw_pdu->username, srw_pdu->password);
1003 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1006 yaz_array_to_uri(&uri_args, encode, name, value);
1008 hreq->method = "POST";
1010 hreq->content_buf = uri_args;
1011 hreq->content_len = strlen(uri_args);
1013 z_HTTP_header_add_content_type(encode, &hreq->headers,
1014 "application/x-www-form-urlencoded",
1019 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1020 ODR odr, const char *charset)
1022 Z_SOAP_Handler handlers[3] = {
1024 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1025 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1029 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1031 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1032 srw_pdu->username, srw_pdu->password);
1033 z_HTTP_header_add_content_type(odr,
1035 "text/xml", charset);
1037 z_HTTP_header_add(odr, &hreq->headers,
1038 "SOAPAction", "\"\"");
1039 p->which = Z_SOAP_generic;
1040 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1041 p->u.generic->no = 0;
1042 p->u.generic->ns = 0;
1043 p->u.generic->p = srw_pdu;
1044 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1047 if (srw_pdu->which == Z_SRW_update_request ||
1048 srw_pdu->which == Z_SRW_update_response)
1049 p->u.generic->no = 1; /* second handler */
1051 return z_soap_codec_enc(odr, &p,
1053 &hreq->content_len, handlers,
1057 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1059 Z_SRW_recordVersion *ver
1060 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1062 for (i = 0; i < num; ++i)
1064 ver[i].versionType = 0;
1065 ver[i].versionValue = 0;
1070 const char *yaz_srw_pack_to_str(int pack)
1074 case Z_SRW_recordPacking_string:
1076 case Z_SRW_recordPacking_XML:
1078 case Z_SRW_recordPacking_URL:
1084 int yaz_srw_str_to_pack(const char *str)
1086 if (!yaz_matchstr(str, "string"))
1087 return Z_SRW_recordPacking_string;
1088 if (!yaz_matchstr(str, "xml"))
1089 return Z_SRW_recordPacking_XML;
1090 if (!yaz_matchstr(str, "url"))
1091 return Z_SRW_recordPacking_URL;
1095 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1101 Z_SRW_extra_arg **ea = &sr->extra_args;
1102 yaz_uri_to_array(extra_args, odr, &name, &val);
1104 /** append rather than override */
1109 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1110 (*ea)->name = *name;
1111 (*ea)->value = *val;
1124 * c-file-style: "Stroustrup"
1125 * indent-tabs-mode: nil
1127 * vim: shiftwidth=4 tabstop=8 expandtab