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;
381 char *queryType = "cql";
385 char *stylesheet = 0;
386 char *scanClause = 0;
387 char *recordXPath = 0;
388 char *recordSchema = 0;
389 char *recordPacking = "xml"; /* xml packing is default for SRU */
390 char *maximumRecords = 0;
391 char *startRecord = 0;
392 char *maximumTerms = 0;
393 char *responsePosition = 0;
394 Z_SRW_extra_arg *extra_args = 0;
399 grab_charset(decode, content_type, charset);
400 if (charset && *charset == 0 && !strcmp(hreq->method, "GET"))
405 p1 = strchr(p0, '?');
407 p1 = p0 + strlen(p0);
409 db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
410 if (!strcmp(hreq->method, "POST"))
411 p1 = hreq->content_buf;
412 yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
417 for (i = 0; uri_name[i]; i++)
419 char *n = uri_name[i];
420 char *v = uri_val[i];
421 if (!strcmp(n, "query"))
423 else if (!strcmp(n, "x-pquery"))
428 else if (!strcmp(n, "queryType"))
430 else if (!strcmp(n, "x-username"))
432 else if (!strcmp(n, "x-password"))
434 else if (!strcmp(n, "operation"))
436 else if (!strcmp(n, "stylesheet"))
438 else if (!strcmp(n, "sortKeys"))
440 else if (!strcmp(n, "recordXPath"))
442 else if (!strcmp(n, "recordSchema"))
444 else if (!strcmp(n, "recordPacking"))
446 else if (!strcmp(n, "version"))
448 else if (!strcmp(n, "scanClause"))
450 else if (!strcmp(n, "x-pScanClause"))
455 else if (!strcmp(n, "maximumRecords"))
457 else if (!strcmp(n, "startRecord"))
459 else if (!strcmp(n, "maximumTerms"))
461 else if (!strcmp(n, "responsePosition"))
462 responsePosition = v;
463 else if (!strcmp(n, "extraRequestData"))
464 ; /* ignoring extraRequestData */
465 else if (n[0] == 'x' && n[1] == '-')
467 Z_SRW_extra_arg **l = &extra_args;
470 *l = (Z_SRW_extra_arg *) odr_malloc(decode, sizeof(**l));
471 (*l)->name = odr_strdup(decode, n);
472 (*l)->value = odr_strdup(decode, v);
478 yaz_add_srw_diagnostic(decode, diag, num_diag,
479 YAZ_SRW_UNSUPP_PARAMETER, n);
486 yaz_add_srw_diagnostic(
487 decode, diag, num_diag,
488 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version");
492 version = yaz_negotiate_sru_version(version);
495 { /* negotiation failed. */
496 yaz_add_srw_diagnostic(decode, diag, num_diag,
497 YAZ_SRW_UNSUPP_VERSION, "1.2");
504 yaz_add_srw_diagnostic(
505 decode, diag, num_diag,
506 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation");
507 operation = "explain";
509 if (!strcmp(operation, "searchRetrieve"))
511 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
513 sr->srw_version = version;
514 sr->extra_args = extra_args;
516 yaz_srw_decodeauth(sr, hreq, username, password, decode);
518 sr->u.request->queryType = queryType;
519 sr->u.request->query = query;
522 yaz_add_srw_diagnostic(
523 decode, diag, num_diag,
524 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query");
528 sr->u.request->sort_type = Z_SRW_sort_type_sort;
529 sr->u.request->sort.sortKeys = sortKeys;
531 sr->u.request->recordXPath = recordXPath;
532 sr->u.request->recordSchema = recordSchema;
533 sr->u.request->recordPacking = recordPacking;
534 sr->u.request->stylesheet = stylesheet;
536 yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
537 &sr->u.request->maximumRecords,
540 yaz_sru_decode_integer(decode, "startRecord", startRecord,
541 &sr->u.request->startRecord,
544 sr->u.request->database = db;
546 (*soap_package) = (Z_SOAP *)
547 odr_malloc(decode, sizeof(**soap_package));
548 (*soap_package)->which = Z_SOAP_generic;
550 (*soap_package)->u.generic = (Z_SOAP_Generic *)
551 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
553 (*soap_package)->u.generic->p = sr;
554 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
555 (*soap_package)->u.generic->no = 0;
557 (*soap_package)->ns = "SRU";
561 else if (!strcmp(operation, "explain"))
563 /* Transfer SRU explain parameters to common struct */
564 /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
565 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
567 sr->srw_version = version;
568 sr->extra_args = extra_args;
569 yaz_srw_decodeauth(sr, hreq, username, password, decode);
571 sr->u.explain_request->recordPacking = recordPacking;
572 sr->u.explain_request->database = db;
574 sr->u.explain_request->stylesheet = stylesheet;
576 (*soap_package) = (Z_SOAP *)
577 odr_malloc(decode, sizeof(**soap_package));
578 (*soap_package)->which = Z_SOAP_generic;
580 (*soap_package)->u.generic = (Z_SOAP_Generic *)
581 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
583 (*soap_package)->u.generic->p = sr;
584 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
585 (*soap_package)->u.generic->no = 0;
587 (*soap_package)->ns = "SRU";
591 else if (!strcmp(operation, "scan"))
593 /* Transfer SRU scan parameters to common struct */
594 /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
595 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
597 sr->srw_version = version;
598 sr->extra_args = extra_args;
600 yaz_srw_decodeauth(sr, hreq, username, password, decode);
602 sr->u.scan_request->queryType = queryType;
603 sr->u.scan_request->scanClause = scanClause;
606 yaz_add_srw_diagnostic(
607 decode, diag, num_diag,
608 YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause");
609 sr->u.scan_request->database = db;
611 yaz_sru_decode_integer(decode, "maximumTerms",
613 &sr->u.scan_request->maximumTerms,
616 yaz_sru_decode_integer(decode, "responsePosition",
618 &sr->u.scan_request->responsePosition,
621 sr->u.scan_request->stylesheet = stylesheet;
623 (*soap_package) = (Z_SOAP *)
624 odr_malloc(decode, sizeof(**soap_package));
625 (*soap_package)->which = Z_SOAP_generic;
627 (*soap_package)->u.generic = (Z_SOAP_Generic *)
628 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
630 (*soap_package)->u.generic->p = sr;
631 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
632 (*soap_package)->u.generic->no = 0;
634 (*soap_package)->ns = "SRU";
640 /* unsupported operation ... */
641 /* Act as if we received a explain request and throw diagnostic. */
643 Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
645 sr->srw_version = version;
647 sr->u.explain_request->recordPacking = recordPacking;
648 sr->u.explain_request->database = db;
650 sr->u.explain_request->stylesheet = stylesheet;
652 (*soap_package) = (Z_SOAP *)
653 odr_malloc(decode, sizeof(**soap_package));
654 (*soap_package)->which = Z_SOAP_generic;
656 (*soap_package)->u.generic = (Z_SOAP_Generic *)
657 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
659 (*soap_package)->u.generic->p = sr;
660 (*soap_package)->u.generic->ns = soap_handlers[0].ns;
661 (*soap_package)->u.generic->no = 0;
663 (*soap_package)->ns = "SRU";
665 yaz_add_srw_diagnostic(decode, diag, num_diag,
666 YAZ_SRW_UNSUPP_OPERATION, operation);
676 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
678 Z_SRW_extra_record *res = (Z_SRW_extra_record *)
679 odr_malloc(o, sizeof(*res));
681 res->extraRecordData_buf = 0;
682 res->extraRecordData_len = 0;
683 res->recordIdentifier = 0;
688 Z_SRW_record *yaz_srw_get_records(ODR o, int n)
690 Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res));
693 for (i = 0; i<n; i++)
695 res[i].recordSchema = 0;
696 res[i].recordPacking = Z_SRW_recordPacking_string;
697 res[i].recordData_buf = 0;
698 res[i].recordData_len = 0;
699 res[i].recordPosition = 0;
704 Z_SRW_record *yaz_srw_get_record(ODR o)
706 return yaz_srw_get_records(o, 1);
709 static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
711 Z_SRW_PDU *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(*p));
712 p->srw_version = odr_strdup(o, version);
716 p->extraResponseData_buf = 0;
717 p->extraResponseData_len = 0;
721 Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o)
723 return yaz_srw_get_core_ver(o, "1.1");
726 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
728 return yaz_srw_get_pdu(o, which, "1.1");
731 Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version)
733 Z_SRW_PDU *sr = yaz_srw_get_core_ver(o, version);
738 case Z_SRW_searchRetrieve_request:
739 sr->u.request = (Z_SRW_searchRetrieveRequest *)
740 odr_malloc(o, sizeof(*sr->u.request));
741 sr->u.request->queryType = "cql";
742 sr->u.request->query = 0;
743 sr->u.request->sort_type = Z_SRW_sort_type_none;
744 sr->u.request->sort.none = 0;
745 sr->u.request->startRecord = 0;
746 sr->u.request->maximumRecords = 0;
747 sr->u.request->recordSchema = 0;
748 sr->u.request->recordPacking = 0;
749 sr->u.request->recordXPath = 0;
750 sr->u.request->database = 0;
751 sr->u.request->resultSetTTL = 0;
752 sr->u.request->stylesheet = 0;
753 sr->u.request->facetList = 0;
755 case Z_SRW_searchRetrieve_response:
756 sr->u.response = (Z_SRW_searchRetrieveResponse *)
757 odr_malloc(o, sizeof(*sr->u.response));
758 sr->u.response->numberOfRecords = 0;
759 sr->u.response->resultSetId = 0;
760 sr->u.response->resultSetIdleTime = 0;
761 sr->u.response->records = 0;
762 sr->u.response->num_records = 0;
763 sr->u.response->diagnostics = 0;
764 sr->u.response->num_diagnostics = 0;
765 sr->u.response->nextRecordPosition = 0;
766 sr->u.response->extra_records = 0;
767 sr->u.response->facetList = 0;
768 sr->u.response->suggestions = 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->queryType = "cql";
798 sr->u.scan_request->scanClause = 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;
839 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
840 char *a_name, Odr_int *val)
845 value[*i] = (char *) odr_malloc(o, 40);
846 sprintf(value[*i], ODR_INT_PRINTF, *val);
851 void yaz_add_name_value_str(ODR o, char **name, char **value, int *i,
852 char *a_name, char *val)
862 static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode,
863 char **name, char **value, int max_names)
867 yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version);
868 name[i] = "operation";
869 switch (srw_pdu->which)
871 case Z_SRW_searchRetrieve_request:
872 value[i++] = "searchRetrieve";
873 queryType = srw_pdu->u.request->queryType;
874 if (strcmp(srw_pdu->srw_version, "2.") > 0)
876 yaz_add_name_value_str(encode, name, value, &i, "queryType",
878 yaz_add_name_value_str(encode, name, value, &i, "query",
879 srw_pdu->u.request->query);
883 if (!strcmp(queryType, "cql"))
885 yaz_add_name_value_str(encode, name, value, &i, "query",
886 srw_pdu->u.request->query);
888 else if (!strcmp(queryType, "pqf"))
890 yaz_add_name_value_str(encode, name, value, &i, "x-pquery",
891 srw_pdu->u.request->query);
893 else if (!strcmp(queryType, "pqf"))
895 yaz_add_name_value_str(encode, name, value, &i, "x-cql",
896 srw_pdu->u.request->query);
899 switch (srw_pdu->u.request->sort_type)
901 case Z_SRW_sort_type_none:
903 case Z_SRW_sort_type_sort:
904 yaz_add_name_value_str(encode, name, value, &i, "sortKeys",
905 srw_pdu->u.request->sort.sortKeys);
908 yaz_add_name_value_int(encode, name, value, &i, "startRecord",
909 srw_pdu->u.request->startRecord);
910 yaz_add_name_value_int(encode, name, value, &i, "maximumRecords",
911 srw_pdu->u.request->maximumRecords);
912 yaz_add_name_value_str(encode, name, value, &i, "recordSchema",
913 srw_pdu->u.request->recordSchema);
914 yaz_add_name_value_str(encode, name, value, &i, "recordPacking",
915 srw_pdu->u.request->recordPacking);
916 yaz_add_name_value_str(encode, name, value, &i, "recordXPath",
917 srw_pdu->u.request->recordXPath);
918 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
919 srw_pdu->u.request->stylesheet);
920 yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
921 srw_pdu->u.request->resultSetTTL);
923 case Z_SRW_explain_request:
924 value[i++] = "explain";
925 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
926 srw_pdu->u.explain_request->stylesheet);
928 case Z_SRW_scan_request:
930 queryType = srw_pdu->u.request->queryType;
931 if (strcmp(srw_pdu->srw_version, "2.") > 0)
933 if (queryType && strcmp(queryType, "cql"))
934 yaz_add_name_value_str(encode, name, value, &i, "queryType",
936 yaz_add_name_value_str(encode, name, value, &i, "query",
937 srw_pdu->u.request->query);
941 if (!queryType || !strcmp(queryType, "cql"))
942 yaz_add_name_value_str(encode, name, value, &i, "scanClause",
943 srw_pdu->u.scan_request->scanClause);
944 else if (!strcmp(queryType, "pqf"))
945 yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause",
946 srw_pdu->u.scan_request->scanClause);
947 else if (!strcmp(queryType, "xcql"))
948 yaz_add_name_value_str(encode, name, value, &i,
950 srw_pdu->u.scan_request->scanClause);
952 yaz_add_name_value_int(encode, name, value, &i, "responsePosition",
953 srw_pdu->u.scan_request->responsePosition);
954 yaz_add_name_value_int(encode, name, value, &i, "maximumTerms",
955 srw_pdu->u.scan_request->maximumTerms);
956 yaz_add_name_value_str(encode, name, value, &i, "stylesheet",
957 srw_pdu->u.scan_request->stylesheet);
959 case Z_SRW_update_request:
960 value[i++] = "update";
965 if (srw_pdu->extra_args)
967 Z_SRW_extra_arg *ea = srw_pdu->extra_args;
968 for (; ea && i < max_names-1; ea = ea->next)
971 value[i] = ea->value;
980 int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
981 ODR encode, const char *charset)
983 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
987 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
988 srw_pdu->username, srw_pdu->password);
989 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
991 yaz_array_to_uri(&uri_args, encode, name, value);
993 hreq->method = "GET";
996 odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
998 sprintf(path, "%s?%s", hreq->path, uri_args);
999 yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
1002 z_HTTP_header_add_content_type(encode, &hreq->headers,
1003 "text/xml", charset);
1007 int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1008 ODR encode, const char *charset)
1010 char *name[MAX_SRU_PARAMETERS], *value[MAX_SRU_PARAMETERS]; /* definite upper limit for SRU params */
1013 z_HTTP_header_add_basic_auth(encode, &hreq->headers,
1014 srw_pdu->username, srw_pdu->password);
1015 if (yaz_get_sru_parms(srw_pdu, encode, name, value, MAX_SRU_PARAMETERS))
1018 yaz_array_to_uri(&uri_args, encode, name, value);
1020 hreq->method = "POST";
1022 hreq->content_buf = uri_args;
1023 hreq->content_len = strlen(uri_args);
1025 z_HTTP_header_add_content_type(encode, &hreq->headers,
1026 "application/x-www-form-urlencoded",
1031 int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
1032 ODR odr, const char *charset)
1034 Z_SOAP_Handler handlers[3] = {
1036 {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
1037 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
1041 Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p));
1043 z_HTTP_header_add_basic_auth(odr, &hreq->headers,
1044 srw_pdu->username, srw_pdu->password);
1045 z_HTTP_header_add_content_type(odr,
1047 "text/xml", charset);
1049 z_HTTP_header_add(odr, &hreq->headers,
1050 "SOAPAction", "\"\"");
1051 p->which = Z_SOAP_generic;
1052 p->u.generic = (Z_SOAP_Generic *) odr_malloc(odr, sizeof(*p->u.generic));
1053 p->u.generic->no = 0;
1054 p->u.generic->ns = 0;
1055 p->u.generic->p = srw_pdu;
1056 p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
1059 if (srw_pdu->which == Z_SRW_update_request ||
1060 srw_pdu->which == Z_SRW_update_response)
1061 p->u.generic->no = 1; /* second handler */
1063 return z_soap_codec_enc(odr, &p,
1065 &hreq->content_len, handlers,
1069 Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num)
1071 Z_SRW_recordVersion *ver
1072 = (Z_SRW_recordVersion *) odr_malloc(odr,num * sizeof(*ver));
1074 for (i = 0; i < num; ++i)
1076 ver[i].versionType = 0;
1077 ver[i].versionValue = 0;
1082 const char *yaz_srw_pack_to_str(int pack)
1086 case Z_SRW_recordPacking_string:
1088 case Z_SRW_recordPacking_XML:
1090 case Z_SRW_recordPacking_URL:
1096 int yaz_srw_str_to_pack(const char *str)
1098 if (!yaz_matchstr(str, "string"))
1099 return Z_SRW_recordPacking_string;
1100 if (!yaz_matchstr(str, "xml"))
1101 return Z_SRW_recordPacking_XML;
1102 if (!yaz_matchstr(str, "url"))
1103 return Z_SRW_recordPacking_URL;
1107 void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
1113 Z_SRW_extra_arg **ea = &sr->extra_args;
1114 yaz_uri_to_array(extra_args, odr, &name, &val);
1118 *ea = (Z_SRW_extra_arg *) odr_malloc(odr, sizeof(**ea));
1119 (*ea)->name = *name;
1120 (*ea)->value = *val;
1133 * c-file-style: "Stroustrup"
1134 * indent-tabs-mode: nil
1136 * vim: shiftwidth=4 tabstop=8 expandtab