}
-#if YAZ_HAVE_XML2
-static void set_HTTP_error(ZOOM_connection c, int error,
- const char *addinfo, const char *addinfo2)
-{
- ZOOM_set_dset_error(c, error, "HTTP", addinfo, addinfo2);
-}
-
-static void set_SRU_error(ZOOM_connection c, Z_SRW_diagnostic *d)
-{
- const char *uri = d->uri;
- if (uri)
- ZOOM_set_dset_error(c, ZOOM_uri_to_code(uri), uri, d->details, 0);
-}
-
-#endif
-
void ZOOM_set_error(ZOOM_connection c, int error, const char *addinfo)
{
0 if PDU was not sent OK (nothing to wait for)
*/
-#if YAZ_HAVE_XML2
-static zoom_ret send_srw(ZOOM_connection c, Z_SRW_PDU *sr)
-{
- Z_GDU *gdu;
- ZOOM_Event event;
- const char *database = ZOOM_options_get(c->options, "databaseName");
- char *fdatabase = 0;
-
- if (database)
- fdatabase = yaz_encode_sru_dbpath_odr(c->odr_out, database);
- gdu = z_get_HTTP_Request_host_path(c->odr_out, c->host_port,
- fdatabase ? fdatabase : c->path);
-
- if (c->sru_mode == zoom_sru_get)
- {
- yaz_sru_get_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset);
- }
- else if (c->sru_mode == zoom_sru_post)
- {
- yaz_sru_post_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset);
- }
- else if (c->sru_mode == zoom_sru_soap)
- {
- yaz_sru_soap_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset);
- }
- if (!z_GDU(c->odr_out, &gdu, 0, 0))
- return zoom_complete;
- if (c->odr_print)
- z_GDU(c->odr_print, &gdu, 0, 0);
- c->buf_out = odr_getbuf(c->odr_out, &c->len_out, 0);
-
- event = ZOOM_Event_create(ZOOM_EVENT_SEND_APDU);
- ZOOM_connection_put_event(c, event);
- odr_reset(c->odr_out);
- return ZOOM_send_buf(c);
-}
-#endif
-
-#if YAZ_HAVE_XML2
-static Z_SRW_PDU *ZOOM_srw_get_pdu(ZOOM_connection c, int type)
-{
- Z_SRW_PDU *sr = yaz_srw_get_pdu(c->odr_out, type, c->sru_version);
- sr->username = c->user;
- sr->password = c->password;
- return sr;
-}
-#endif
-
-#if YAZ_HAVE_XML2
-static zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
-{
- int i;
- int *start, *count;
- ZOOM_resultset resultset = 0;
- Z_SRW_PDU *sr = 0;
- const char *option_val = 0;
- Z_Query *z_query;
-
- if (c->error) /* don't continue on error */
- return zoom_complete;
- assert(c->tasks);
- switch(c->tasks->which)
- {
- case ZOOM_TASK_SEARCH:
- resultset = c->tasks->u.search.resultset;
- if (!resultset->setname)
- resultset->setname = xstrdup("default");
- ZOOM_options_set(resultset->options, "setname", resultset->setname);
- start = &c->tasks->u.search.start;
- count = &c->tasks->u.search.count;
- break;
- case ZOOM_TASK_RETRIEVE:
- resultset = c->tasks->u.retrieve.resultset;
-
- start = &c->tasks->u.retrieve.start;
- count = &c->tasks->u.retrieve.count;
-
- if (*start >= resultset->size)
- return zoom_complete;
- if (*start + *count > resultset->size)
- *count = resultset->size - *start;
-
- for (i = 0; i < *count; i++)
- {
- ZOOM_record rec =
- ZOOM_record_cache_lookup(resultset, i + *start,
- c->tasks->u.retrieve.syntax,
- c->tasks->u.retrieve.elementSetName);
- if (!rec)
- break;
- else
- {
- ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD);
- ZOOM_connection_put_event(c, event);
- }
- }
- *start += i;
- *count -= i;
-
- if (*count == 0)
- return zoom_complete;
- break;
- default:
- return zoom_complete;
- }
- assert(resultset->query);
-
- sr = ZOOM_srw_get_pdu(c, Z_SRW_searchRetrieve_request);
- z_query = ZOOM_query_get_Z_Query(resultset->query);
-
- if (z_query->which == Z_Query_type_104
- && z_query->u.type_104->which == Z_External_CQL)
- {
- sr->u.request->query_type = Z_SRW_query_type_cql;
- sr->u.request->query.cql = z_query->u.type_104->u.cql;
- }
- else if (z_query->which == Z_Query_type_1 && z_query->u.type_1)
- {
- sr->u.request->query_type = Z_SRW_query_type_pqf;
- sr->u.request->query.pqf =
- ZOOM_query_get_query_string(resultset->query);
- }
- else
- {
- ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_QUERY, 0);
- return zoom_complete;
- }
- sr->u.request->startRecord = odr_intdup(c->odr_out, *start + 1);
- sr->u.request->maximumRecords = odr_intdup(
- c->odr_out, (resultset->step > 0 && resultset->step < *count) ?
- resultset->step : *count);
- sr->u.request->recordSchema = resultset->schema;
-
- option_val = ZOOM_resultset_option_get(resultset, "recordPacking");
- if (option_val)
- sr->u.request->recordPacking = odr_strdup(c->odr_out, option_val);
-
- option_val = ZOOM_resultset_option_get(resultset, "extraArgs");
- yaz_encode_sru_extra(sr, c->odr_out, option_val);
- return send_srw(c, sr);
-}
-#else
-static zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
-{
- return zoom_complete;
-}
-#endif
-
ZOOM_API(ZOOM_record)
ZOOM_resultset_record_immediate(ZOOM_resultset s,size_t pos)
{
return ZOOM_send_buf(c);
}
-#if YAZ_HAVE_XML2
-static zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c)
-{
- ZOOM_scanset scan;
- Z_SRW_PDU *sr = 0;
- const char *option_val = 0;
- Z_Query *z_query;
-
- if (!c->tasks)
- return zoom_complete;
- assert (c->tasks->which == ZOOM_TASK_SCAN);
- scan = c->tasks->u.scan.scan;
-
- sr = ZOOM_srw_get_pdu(c, Z_SRW_scan_request);
-
- z_query = ZOOM_query_get_Z_Query(scan->query);
- /* SRU scan can only carry CQL and PQF */
- if (z_query->which == Z_Query_type_104)
- {
- sr->u.scan_request->query_type = Z_SRW_query_type_cql;
- sr->u.scan_request->scanClause.cql =
- ZOOM_query_get_query_string(scan->query);
- }
- else if (z_query->which == Z_Query_type_1
- || z_query->which == Z_Query_type_101)
- {
- sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
- sr->u.scan_request->scanClause.pqf =
- ZOOM_query_get_query_string(scan->query);
- }
- else
- {
- ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_QUERY, 0);
- return zoom_complete;
- }
-
- sr->u.scan_request->maximumTerms = odr_intdup(
- c->odr_out, ZOOM_options_get_int(scan->options, "number", 10));
-
- sr->u.scan_request->responsePosition = odr_intdup(
- c->odr_out, ZOOM_options_get_int(scan->options, "position", 1));
-
- option_val = ZOOM_options_get(scan->options, "extraArgs");
- yaz_encode_sru_extra(sr, c->odr_out, option_val);
- return send_srw(c, sr);
-}
-#else
-static zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c)
-{
- return zoom_complete;
-}
-#endif
-
-
ZOOM_API(size_t)
ZOOM_scanset_size(ZOOM_scanset scan)
{
}
#if YAZ_HAVE_XML2
-static zoom_ret handle_srw_response(ZOOM_connection c,
- Z_SRW_searchRetrieveResponse *res)
-{
- ZOOM_resultset resultset = 0;
- int i;
- NMEM nmem;
- ZOOM_Event event;
- int *start, *count;
- const char *syntax, *elementSetName;
-
- if (!c->tasks)
- return zoom_complete;
-
- switch(c->tasks->which)
- {
- case ZOOM_TASK_SEARCH:
- resultset = c->tasks->u.search.resultset;
- start = &c->tasks->u.search.start;
- count = &c->tasks->u.search.count;
- syntax = c->tasks->u.search.syntax;
- elementSetName = c->tasks->u.search.elementSetName;
-
- if (!c->tasks->u.search.recv_search_fired)
- {
- event = ZOOM_Event_create(ZOOM_EVENT_RECV_SEARCH);
- ZOOM_connection_put_event(c, event);
- c->tasks->u.search.recv_search_fired = 1;
- }
- break;
- case ZOOM_TASK_RETRIEVE:
- resultset = c->tasks->u.retrieve.resultset;
- start = &c->tasks->u.retrieve.start;
- count = &c->tasks->u.retrieve.count;
- syntax = c->tasks->u.retrieve.syntax;
- elementSetName = c->tasks->u.retrieve.elementSetName;
- break;
- default:
- return zoom_complete;
- }
-
- resultset->size = 0;
-
- if (res->resultSetId)
- ZOOM_resultset_option_set(resultset, "resultSetId", res->resultSetId);
-
- yaz_log(c->log_details, "%p handle_srw_response got SRW response OK", c);
-
- if (res->num_diagnostics > 0)
- {
- set_SRU_error(c, &res->diagnostics[0]);
- }
- else
- {
- if (res->numberOfRecords)
- resultset->size = *res->numberOfRecords;
- for (i = 0; i<res->num_records; i++)
- {
- int pos;
- Z_SRW_record *sru_rec;
- Z_SRW_diagnostic *diag = 0;
- int num_diag;
-
- Z_NamePlusRecord *npr = (Z_NamePlusRecord *)
- odr_malloc(c->odr_in, sizeof(Z_NamePlusRecord));
-
- if (res->records[i].recordPosition &&
- *res->records[i].recordPosition > 0)
- pos = *res->records[i].recordPosition - 1;
- else
- pos = *start + i;
-
- sru_rec = &res->records[i];
-
- npr->databaseName = 0;
- npr->which = Z_NamePlusRecord_databaseRecord;
- npr->u.databaseRecord = (Z_External *)
- odr_malloc(c->odr_in, sizeof(Z_External));
- npr->u.databaseRecord->descriptor = 0;
- npr->u.databaseRecord->direct_reference =
- odr_oiddup(c->odr_in, yaz_oid_recsyn_xml);
- npr->u.databaseRecord->which = Z_External_octet;
-
- npr->u.databaseRecord->u.octet_aligned = (Odr_oct *)
- odr_malloc(c->odr_in, sizeof(Odr_oct));
- npr->u.databaseRecord->u.octet_aligned->buf = (unsigned char*)
- sru_rec->recordData_buf;
- npr->u.databaseRecord->u.octet_aligned->len =
- npr->u.databaseRecord->u.octet_aligned->size =
- sru_rec->recordData_len;
-
- if (sru_rec->recordSchema
- && !strcmp(sru_rec->recordSchema,
- "info:srw/schema/1/diagnostics-v1.1"))
- {
- sru_decode_surrogate_diagnostics(sru_rec->recordData_buf,
- sru_rec->recordData_len,
- &diag, &num_diag,
- resultset->odr);
- }
- ZOOM_record_cache_add(resultset, npr, pos, syntax, elementSetName,
- sru_rec->recordSchema, diag);
- }
- *count -= i;
- *start += i;
- if (*count + *start > resultset->size)
- *count = resultset->size - *start;
- if (*count < 0)
- *count = 0;
-
- nmem = odr_extract_mem(c->odr_in);
- nmem_transfer(odr_getmem(resultset->odr), nmem);
- nmem_destroy(nmem);
-
- if (*count > 0)
- return ZOOM_connection_srw_send_search(c);
- }
- return zoom_complete;
-}
-#endif
-
-#if YAZ_HAVE_XML2
-static void handle_srw_scan_response(ZOOM_connection c,
- Z_SRW_scanResponse *res)
-{
- NMEM nmem = odr_extract_mem(c->odr_in);
- ZOOM_scanset scan;
-
- if (!c->tasks || c->tasks->which != ZOOM_TASK_SCAN)
- return;
- scan = c->tasks->u.scan.scan;
-
- if (res->num_diagnostics > 0)
- set_SRU_error(c, &res->diagnostics[0]);
-
- scan->scan_response = 0;
- scan->srw_scan_response = res;
- nmem_transfer(odr_getmem(scan->odr), nmem);
-
- ZOOM_options_set_int(scan->options, "number", res->num_terms);
- nmem_destroy(nmem);
-}
-#endif
-
-#if YAZ_HAVE_XML2
static Z_GDU *get_HTTP_Request_url(ODR odr, const char *url)
{
Z_GDU *p = z_get_HTTP_Request(odr);
return p;
}
-static zoom_ret send_SRW_redirect(ZOOM_connection c, const char *uri,
+static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri,
Z_HTTP_Response *cookie_hres)
{
struct Z_HTTP_Header *h;
return ZOOM_send_buf(c);
}
+#if YAZ_HAVE_XML2
+void ZOOM_set_HTTP_error(ZOOM_connection c, int error,
+ const char *addinfo, const char *addinfo2)
+{
+ ZOOM_set_dset_error(c, error, "HTTP", addinfo, addinfo2);
+}
+#endif
+
+
static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
{
zoom_ret cret = zoom_complete;
c->no_redirects++;
if (c->no_redirects > 10)
{
- set_HTTP_error(c, hres->code, 0, 0);
+ ZOOM_set_HTTP_error(c, hres->code, 0, 0);
c->no_redirects = 0;
ZOOM_connection_close(c);
}
/* since redirect may change host we just reconnect. A smarter
implementation might check whether it's the same server */
do_connect_host(c, location, 0);
- send_SRW_redirect(c, location, hres);
+ send_HTTP_redirect(c, location, hres);
/* we're OK for now. Operation is not really complete */
ret = 0;
cret = zoom_pending;
}
}
else
- { /* not redirect (normal response) */
- if (!yaz_srw_check_content_type(hres))
- addinfo = "content-type";
- else
- {
- Z_SOAP *soap_package = 0;
- ODR o = c->odr_in;
- Z_SOAP_Handler soap_handlers[2] = {
- {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
- {0, 0, 0}
- };
- ret = z_soap_codec(o, &soap_package,
- &hres->content_buf, &hres->content_len,
- soap_handlers);
- if (!ret && soap_package->which == Z_SOAP_generic &&
- soap_package->u.generic->no == 0)
- {
- Z_SRW_PDU *sr = (Z_SRW_PDU*) soap_package->u.generic->p;
-
- ZOOM_options_set(c->options, "sru_version", sr->srw_version);
- ZOOM_options_setl(c->options, "sru_extra_response_data",
- sr->extraResponseData_buf, sr->extraResponseData_len);
- if (sr->which == Z_SRW_searchRetrieve_response)
- cret = handle_srw_response(c, sr->u.response);
- else if (sr->which == Z_SRW_scan_response)
- handle_srw_scan_response(c, sr->u.scan_response);
- else
- ret = -1;
- }
- else if (!ret && (soap_package->which == Z_SOAP_fault
- || soap_package->which == Z_SOAP_error))
- {
- set_HTTP_error(c, hres->code,
- soap_package->u.fault->fault_code,
- soap_package->u.fault->fault_string);
- }
- else
- ret = -1;
- }
+ {
+ ret = ZOOM_handle_sru(c, hres, &cret);
if (ret == 0)
{
if (c->no_redirects) /* end of redirect. change hosts again */
if (ret)
{
if (hres->code != 200)
- set_HTTP_error(c, hres->code, 0, 0);
+ ZOOM_set_HTTP_error(c, hres->code, 0, 0);
else
ZOOM_set_error(c, ZOOM_ERROR_DECODE, addinfo);
ZOOM_connection_close(c);
--- /dev/null
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2010 Index Data
+ * See the file LICENSE for details.
+ */
+/**
+ * \file zoom-sru.c
+ * \brief Implements ZOOM SRU
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include "zoom-p.h"
+
+#include <yaz/log.h>
+
+#if YAZ_HAVE_XML2
+static void set_SRU_error(ZOOM_connection c, Z_SRW_diagnostic *d)
+{
+ const char *uri = d->uri;
+ if (uri)
+ ZOOM_set_dset_error(c, ZOOM_uri_to_code(uri), uri, d->details, 0);
+}
+#endif
+
+
+
+#if YAZ_HAVE_XML2
+static zoom_ret send_srw(ZOOM_connection c, Z_SRW_PDU *sr)
+{
+ Z_GDU *gdu;
+ ZOOM_Event event;
+ const char *database = ZOOM_options_get(c->options, "databaseName");
+ char *fdatabase = 0;
+
+ if (database)
+ fdatabase = yaz_encode_sru_dbpath_odr(c->odr_out, database);
+ gdu = z_get_HTTP_Request_host_path(c->odr_out, c->host_port,
+ fdatabase ? fdatabase : c->path);
+
+ if (c->sru_mode == zoom_sru_get)
+ {
+ yaz_sru_get_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset);
+ }
+ else if (c->sru_mode == zoom_sru_post)
+ {
+ yaz_sru_post_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset);
+ }
+ else if (c->sru_mode == zoom_sru_soap)
+ {
+ yaz_sru_soap_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset);
+ }
+ if (!z_GDU(c->odr_out, &gdu, 0, 0))
+ return zoom_complete;
+ if (c->odr_print)
+ z_GDU(c->odr_print, &gdu, 0, 0);
+ c->buf_out = odr_getbuf(c->odr_out, &c->len_out, 0);
+
+ event = ZOOM_Event_create(ZOOM_EVENT_SEND_APDU);
+ ZOOM_connection_put_event(c, event);
+ odr_reset(c->odr_out);
+ return ZOOM_send_buf(c);
+}
+#endif
+
+#if YAZ_HAVE_XML2
+static Z_SRW_PDU *ZOOM_srw_get_pdu(ZOOM_connection c, int type)
+{
+ Z_SRW_PDU *sr = yaz_srw_get_pdu(c->odr_out, type, c->sru_version);
+ sr->username = c->user;
+ sr->password = c->password;
+ return sr;
+}
+#endif
+
+#if YAZ_HAVE_XML2
+zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c)
+{
+ ZOOM_scanset scan;
+ Z_SRW_PDU *sr = 0;
+ const char *option_val = 0;
+ Z_Query *z_query;
+
+ if (!c->tasks)
+ return zoom_complete;
+ assert (c->tasks->which == ZOOM_TASK_SCAN);
+ scan = c->tasks->u.scan.scan;
+
+ sr = ZOOM_srw_get_pdu(c, Z_SRW_scan_request);
+
+ z_query = ZOOM_query_get_Z_Query(scan->query);
+ /* SRU scan can only carry CQL and PQF */
+ if (z_query->which == Z_Query_type_104)
+ {
+ sr->u.scan_request->query_type = Z_SRW_query_type_cql;
+ sr->u.scan_request->scanClause.cql =
+ ZOOM_query_get_query_string(scan->query);
+ }
+ else if (z_query->which == Z_Query_type_1
+ || z_query->which == Z_Query_type_101)
+ {
+ sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
+ sr->u.scan_request->scanClause.pqf =
+ ZOOM_query_get_query_string(scan->query);
+ }
+ else
+ {
+ ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_QUERY, 0);
+ return zoom_complete;
+ }
+
+ sr->u.scan_request->maximumTerms = odr_intdup(
+ c->odr_out, ZOOM_options_get_int(scan->options, "number", 10));
+
+ sr->u.scan_request->responsePosition = odr_intdup(
+ c->odr_out, ZOOM_options_get_int(scan->options, "position", 1));
+
+ option_val = ZOOM_options_get(scan->options, "extraArgs");
+ yaz_encode_sru_extra(sr, c->odr_out, option_val);
+ return send_srw(c, sr);
+}
+#else
+zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c)
+{
+ return zoom_complete;
+}
+#endif
+
+#if YAZ_HAVE_XML2
+zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
+{
+ int i;
+ int *start, *count;
+ ZOOM_resultset resultset = 0;
+ Z_SRW_PDU *sr = 0;
+ const char *option_val = 0;
+ Z_Query *z_query;
+
+ if (c->error) /* don't continue on error */
+ return zoom_complete;
+ assert(c->tasks);
+ switch(c->tasks->which)
+ {
+ case ZOOM_TASK_SEARCH:
+ resultset = c->tasks->u.search.resultset;
+ if (!resultset->setname)
+ resultset->setname = xstrdup("default");
+ ZOOM_options_set(resultset->options, "setname", resultset->setname);
+ start = &c->tasks->u.search.start;
+ count = &c->tasks->u.search.count;
+ break;
+ case ZOOM_TASK_RETRIEVE:
+ resultset = c->tasks->u.retrieve.resultset;
+
+ start = &c->tasks->u.retrieve.start;
+ count = &c->tasks->u.retrieve.count;
+
+ if (*start >= resultset->size)
+ return zoom_complete;
+ if (*start + *count > resultset->size)
+ *count = resultset->size - *start;
+
+ for (i = 0; i < *count; i++)
+ {
+ ZOOM_record rec =
+ ZOOM_record_cache_lookup(resultset, i + *start,
+ c->tasks->u.retrieve.syntax,
+ c->tasks->u.retrieve.elementSetName);
+ if (!rec)
+ break;
+ else
+ {
+ ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD);
+ ZOOM_connection_put_event(c, event);
+ }
+ }
+ *start += i;
+ *count -= i;
+
+ if (*count == 0)
+ return zoom_complete;
+ break;
+ default:
+ return zoom_complete;
+ }
+ assert(resultset->query);
+
+ sr = ZOOM_srw_get_pdu(c, Z_SRW_searchRetrieve_request);
+ z_query = ZOOM_query_get_Z_Query(resultset->query);
+
+ if (z_query->which == Z_Query_type_104
+ && z_query->u.type_104->which == Z_External_CQL)
+ {
+ sr->u.request->query_type = Z_SRW_query_type_cql;
+ sr->u.request->query.cql = z_query->u.type_104->u.cql;
+ }
+ else if (z_query->which == Z_Query_type_1 && z_query->u.type_1)
+ {
+ sr->u.request->query_type = Z_SRW_query_type_pqf;
+ sr->u.request->query.pqf =
+ ZOOM_query_get_query_string(resultset->query);
+ }
+ else
+ {
+ ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_QUERY, 0);
+ return zoom_complete;
+ }
+ sr->u.request->startRecord = odr_intdup(c->odr_out, *start + 1);
+ sr->u.request->maximumRecords = odr_intdup(
+ c->odr_out, (resultset->step > 0 && resultset->step < *count) ?
+ resultset->step : *count);
+ sr->u.request->recordSchema = resultset->schema;
+
+ option_val = ZOOM_resultset_option_get(resultset, "recordPacking");
+ if (option_val)
+ sr->u.request->recordPacking = odr_strdup(c->odr_out, option_val);
+
+ option_val = ZOOM_resultset_option_get(resultset, "extraArgs");
+ yaz_encode_sru_extra(sr, c->odr_out, option_val);
+ return send_srw(c, sr);
+}
+#else
+zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
+{
+ return zoom_complete;
+}
+#endif
+
+#if YAZ_HAVE_XML2
+static zoom_ret handle_srw_response(ZOOM_connection c,
+ Z_SRW_searchRetrieveResponse *res)
+{
+ ZOOM_resultset resultset = 0;
+ int i;
+ NMEM nmem;
+ ZOOM_Event event;
+ int *start, *count;
+ const char *syntax, *elementSetName;
+
+ if (!c->tasks)
+ return zoom_complete;
+
+ switch(c->tasks->which)
+ {
+ case ZOOM_TASK_SEARCH:
+ resultset = c->tasks->u.search.resultset;
+ start = &c->tasks->u.search.start;
+ count = &c->tasks->u.search.count;
+ syntax = c->tasks->u.search.syntax;
+ elementSetName = c->tasks->u.search.elementSetName;
+
+ if (!c->tasks->u.search.recv_search_fired)
+ {
+ event = ZOOM_Event_create(ZOOM_EVENT_RECV_SEARCH);
+ ZOOM_connection_put_event(c, event);
+ c->tasks->u.search.recv_search_fired = 1;
+ }
+ break;
+ case ZOOM_TASK_RETRIEVE:
+ resultset = c->tasks->u.retrieve.resultset;
+ start = &c->tasks->u.retrieve.start;
+ count = &c->tasks->u.retrieve.count;
+ syntax = c->tasks->u.retrieve.syntax;
+ elementSetName = c->tasks->u.retrieve.elementSetName;
+ break;
+ default:
+ return zoom_complete;
+ }
+
+ resultset->size = 0;
+
+ if (res->resultSetId)
+ ZOOM_resultset_option_set(resultset, "resultSetId", res->resultSetId);
+
+ yaz_log(c->log_details, "%p handle_srw_response got SRW response OK", c);
+
+ if (res->num_diagnostics > 0)
+ {
+ set_SRU_error(c, &res->diagnostics[0]);
+ }
+ else
+ {
+ if (res->numberOfRecords)
+ resultset->size = *res->numberOfRecords;
+ for (i = 0; i<res->num_records; i++)
+ {
+ int pos;
+ Z_SRW_record *sru_rec;
+ Z_SRW_diagnostic *diag = 0;
+ int num_diag;
+
+ Z_NamePlusRecord *npr = (Z_NamePlusRecord *)
+ odr_malloc(c->odr_in, sizeof(Z_NamePlusRecord));
+
+ if (res->records[i].recordPosition &&
+ *res->records[i].recordPosition > 0)
+ pos = *res->records[i].recordPosition - 1;
+ else
+ pos = *start + i;
+
+ sru_rec = &res->records[i];
+
+ npr->databaseName = 0;
+ npr->which = Z_NamePlusRecord_databaseRecord;
+ npr->u.databaseRecord = (Z_External *)
+ odr_malloc(c->odr_in, sizeof(Z_External));
+ npr->u.databaseRecord->descriptor = 0;
+ npr->u.databaseRecord->direct_reference =
+ odr_oiddup(c->odr_in, yaz_oid_recsyn_xml);
+ npr->u.databaseRecord->which = Z_External_octet;
+
+ npr->u.databaseRecord->u.octet_aligned = (Odr_oct *)
+ odr_malloc(c->odr_in, sizeof(Odr_oct));
+ npr->u.databaseRecord->u.octet_aligned->buf = (unsigned char*)
+ sru_rec->recordData_buf;
+ npr->u.databaseRecord->u.octet_aligned->len =
+ npr->u.databaseRecord->u.octet_aligned->size =
+ sru_rec->recordData_len;
+
+ if (sru_rec->recordSchema
+ && !strcmp(sru_rec->recordSchema,
+ "info:srw/schema/1/diagnostics-v1.1"))
+ {
+ sru_decode_surrogate_diagnostics(sru_rec->recordData_buf,
+ sru_rec->recordData_len,
+ &diag, &num_diag,
+ resultset->odr);
+ }
+ ZOOM_record_cache_add(resultset, npr, pos, syntax, elementSetName,
+ sru_rec->recordSchema, diag);
+ }
+ *count -= i;
+ *start += i;
+ if (*count + *start > resultset->size)
+ *count = resultset->size - *start;
+ if (*count < 0)
+ *count = 0;
+
+ nmem = odr_extract_mem(c->odr_in);
+ nmem_transfer(odr_getmem(resultset->odr), nmem);
+ nmem_destroy(nmem);
+
+ if (*count > 0)
+ return ZOOM_connection_srw_send_search(c);
+ }
+ return zoom_complete;
+}
+#endif
+
+#if YAZ_HAVE_XML2
+static void handle_srw_scan_response(ZOOM_connection c,
+ Z_SRW_scanResponse *res)
+{
+ NMEM nmem = odr_extract_mem(c->odr_in);
+ ZOOM_scanset scan;
+
+ if (!c->tasks || c->tasks->which != ZOOM_TASK_SCAN)
+ return;
+ scan = c->tasks->u.scan.scan;
+
+ if (res->num_diagnostics > 0)
+ set_SRU_error(c, &res->diagnostics[0]);
+
+ scan->scan_response = 0;
+ scan->srw_scan_response = res;
+ nmem_transfer(odr_getmem(scan->odr), nmem);
+
+ ZOOM_options_set_int(scan->options, "number", res->num_terms);
+ nmem_destroy(nmem);
+}
+#endif
+
+int ZOOM_handle_sru(ZOOM_connection c, Z_HTTP_Response *hres,
+ zoom_ret *cret)
+{
+ int ret = 0;
+ const char *addinfo = 0;
+
+ /* not redirect (normal response) */
+ if (!yaz_srw_check_content_type(hres))
+ addinfo = "content-type";
+ else
+ {
+ Z_SOAP *soap_package = 0;
+ ODR o = c->odr_in;
+ Z_SOAP_Handler soap_handlers[2] = {
+ {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
+ {0, 0, 0}
+ };
+ ret = z_soap_codec(o, &soap_package,
+ &hres->content_buf, &hres->content_len,
+ soap_handlers);
+ if (!ret && soap_package->which == Z_SOAP_generic &&
+ soap_package->u.generic->no == 0)
+ {
+ Z_SRW_PDU *sr = (Z_SRW_PDU*) soap_package->u.generic->p;
+
+ ZOOM_options_set(c->options, "sru_version", sr->srw_version);
+ ZOOM_options_setl(c->options, "sru_extra_response_data",
+ sr->extraResponseData_buf, sr->extraResponseData_len);
+ if (sr->which == Z_SRW_searchRetrieve_response)
+ *cret = handle_srw_response(c, sr->u.response);
+ else if (sr->which == Z_SRW_scan_response)
+ handle_srw_scan_response(c, sr->u.scan_response);
+ else
+ ret = -1;
+ }
+ else if (!ret && (soap_package->which == Z_SOAP_fault
+ || soap_package->which == Z_SOAP_error))
+ {
+ ZOOM_set_HTTP_error(c, hres->code,
+ soap_package->u.fault->fault_code,
+ soap_package->u.fault->fault_string);
+ }
+ else
+ ret = -1;
+ }
+ return ret;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+