/* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2013 Index Data
+ * Copyright (C) Index Data
* See the file LICENSE for details.
*/
/**
#include <libxml/tree.h>
#endif
+#include <yaz/facet.h>
#include <yaz/xmalloc.h>
#include <yaz/comstack.h>
#include "eventl.h"
#include <yaz/yaz-util.h>
#include <yaz/pquery.h>
#include <yaz/oid_db.h>
-
+#include <yaz/query-charset.h>
#include <yaz/srw.h>
#include <yaz/backend.h>
#include <yaz/yaz-ccl.h>
static int process_z_request(association *assoc, request *req, char **msg);
-static void assoc_init_reset(association *assoc)
+static void assoc_init_reset(association *assoc, const char *peer_name1)
{
+ const char *peer_name2 = cs_addrstr(assoc->client_link);
+
xfree(assoc->init);
assoc->init = (bend_initrequest *) xmalloc(sizeof(*assoc->init));
assoc->init->charneg_response = NULL;
assoc->init->decode = assoc->decode;
- assoc->init->peer_name =
- odr_strdup(assoc->encode, cs_addrstr(assoc->client_link));
+
+ assoc->init->peer_name = (char *)
+ odr_malloc(assoc->encode,
+ (peer_name1 ? strlen(peer_name1) : 0)
+ + 4 + strlen(peer_name2));
+ strcpy(assoc->init->peer_name, "");
+ if (peer_name1)
+ {
+ strcat(assoc->init->peer_name, peer_name1);
+ strcat(assoc->init->peer_name, ", ");
+ }
+ strcat(assoc->init->peer_name, peer_name2);
yaz_log(log_requestdetail, "peer %s", assoc->init->peer_name);
}
-static int srw_bend_init(association *assoc, Z_SRW_diagnostic **d, int *num, Z_SRW_PDU *sr)
+static int srw_bend_init(association *assoc, Z_HTTP_Header *headers,
+ Z_SRW_diagnostic **d, int *num, Z_SRW_PDU *sr)
{
statserv_options_block *cb = statserv_getcontrol();
if (!assoc->init)
bend_initresult *binitres;
yaz_log(log_requestdetail, "srw_bend_init config=%s", cb->configname);
- assoc_init_reset(assoc);
+ assoc_init_reset(assoc, z_HTTP_header_lookup(headers, "X-Forwarded-For"));
if (sr->username)
{
if (r)
{
rr->errcode = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
+ rr->surrogate_flag = 1;
if (details)
rr->errstring = odr_strdup(rr->stream, details);
}
}
static void srw_bend_search(association *assoc,
+ Z_HTTP_Header *headers,
Z_SRW_PDU *sr,
Z_SRW_PDU *res,
int *http_code)
*http_code = 200;
yaz_log(log_requestdetail, "Got SRW SearchRetrieveRequest");
- srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+ srw_bend_init(assoc, headers,
+ &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
if (srw_res->num_diagnostics == 0 && assoc->init)
{
bend_search_rr rr;
rr.errstring = 0;
rr.search_info = 0;
rr.search_input = 0;
+
+ if (srw_req->facetList)
+ yaz_oi_set_facetlist(&rr.search_input, assoc->encode,
+ srw_req->facetList);
+
yaz_log_zquery_level(log_requestdetail,rr.query);
(assoc->init->bend_search)(assoc->backend, &rr);
odr_intdup(assoc->encode, *rr.srw_setnameIdleTime );
}
+ srw_res->facetList = yaz_oi_get_facetlist(&rr.search_info);
if (start > rr.hits || start < 1)
{
/* if hits<=0 and start=1 we don't return a diagnostic */
res->extraResponseData_buf = rr.extra_response_data;
res->extraResponseData_len = strlen(rr.extra_response_data);
}
- if (rr.estimated_hit_count || rr.partial_resultset)
+ if (strcmp(res->srw_version, "2.") > 0)
+ {
+ if (rr.estimated_hit_count)
+ srw_res->resultCountPrecision =
+ odr_strdup(assoc->encode, "estimate");
+ else if (rr.partial_resultset)
+ srw_res->resultCountPrecision =
+ odr_strdup(assoc->encode, "minimum");
+ else
+ srw_res->resultCountPrecision =
+ odr_strdup(assoc->encode, "exact");
+ }
+ else if (rr.estimated_hit_count || rr.partial_resultset)
{
yaz_add_srw_diagnostic(
assoc->encode,
}
static void srw_bend_explain(association *assoc,
+ Z_HTTP_Header *headers,
Z_SRW_PDU *sr,
Z_SRW_explainResponse *srw_res,
int *http_code)
{
Z_SRW_explainRequest *srw_req = sr->u.explain_request;
yaz_log(log_requestdetail, "Got SRW ExplainRequest");
- *http_code = 404;
- srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+ srw_bend_init(assoc, headers,
+ &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+ if (!assoc->init && srw_res->num_diagnostics == 0)
+ *http_code = 404;
if (assoc->init)
{
bend_explain_rr rr;
}
static void srw_bend_scan(association *assoc,
+ Z_HTTP_Header *headers,
Z_SRW_PDU *sr,
Z_SRW_PDU *res,
int *http_code)
yaz_log(log_requestdetail, "Got SRW ScanRequest");
*http_code = 200;
- srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+ srw_bend_init(assoc, headers,
+ &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
if (srw_res->num_diagnostics == 0 && assoc->init)
{
int step_size = 0;
}
static void srw_bend_update(association *assoc,
+ Z_HTTP_Header *headers,
Z_SRW_PDU *sr,
Z_SRW_updateResponse *srw_res,
int *http_code)
Z_SRW_updateRequest *srw_req = sr->u.update_request;
yaz_log(log_session, "SRWUpdate action=%s", srw_req->operation);
yaz_log(YLOG_DEBUG, "num_diag = %d", srw_res->num_diagnostics );
- *http_code = 404;
- srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+ srw_bend_init(assoc, headers,
+ &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+ if (!assoc->init && srw_res->num_diagnostics == 0)
+ *http_code = 404;
if (assoc->init)
{
bend_update_rr rr;
if (sr->which == Z_SRW_searchRetrieve_request)
{
Z_SRW_PDU *res =
- yaz_srw_get_pdu(assoc->encode, Z_SRW_searchRetrieve_response,
- sr->srw_version);
+ yaz_srw_get_pdu_e(assoc->encode, Z_SRW_searchRetrieve_response,
+ sr);
stylesheet = sr->u.request->stylesheet;
if (num_diagnostic)
{
}
else
{
- srw_bend_search(assoc, sr, res, &http_code);
+ srw_bend_search(assoc, hreq->headers, sr, res, &http_code);
}
if (http_code == 200)
soap_package->u.generic->p = res;
}
else if (sr->which == Z_SRW_explain_request)
{
- Z_SRW_PDU *res = yaz_srw_get_pdu(o, Z_SRW_explain_response,
- sr->srw_version);
+ Z_SRW_PDU *res = yaz_srw_get_pdu_e(o, Z_SRW_explain_response, sr);
stylesheet = sr->u.explain_request->stylesheet;
if (num_diagnostic)
{
res->u.explain_response->diagnostics = diagnostic;
res->u.explain_response->num_diagnostics = num_diagnostic;
}
- srw_bend_explain(assoc, sr, res->u.explain_response, &http_code);
+ srw_bend_explain(assoc, hreq->headers,
+ sr, res->u.explain_response, &http_code);
if (http_code == 200)
soap_package->u.generic->p = res;
}
else if (sr->which == Z_SRW_scan_request)
{
- Z_SRW_PDU *res = yaz_srw_get_pdu(o, Z_SRW_scan_response,
- sr->srw_version);
+ Z_SRW_PDU *res = yaz_srw_get_pdu_e(o, Z_SRW_scan_response, sr);
stylesheet = sr->u.scan_request->stylesheet;
if (num_diagnostic)
{
res->u.scan_response->diagnostics = diagnostic;
res->u.scan_response->num_diagnostics = num_diagnostic;
}
- srw_bend_scan(assoc, sr, res, &http_code);
+ srw_bend_scan(assoc, hreq->headers, sr, res, &http_code);
if (http_code == 200)
soap_package->u.generic->p = res;
}
res->u.update_response->num_diagnostics = num_diagnostic;
}
yaz_log(YLOG_DEBUG, "num_diag = %d", res->u.update_response->num_diagnostics );
- srw_bend_update(assoc, sr, res->u.update_response, &http_code);
+ srw_bend_update(assoc, hreq->headers,
+ sr, res->u.update_response, &http_code);
if (http_code == 200)
soap_package->u.generic->p = res;
}
hres->code = http_code;
strcpy(ctype, "text/xml");
- if (charset && strlen(charset) < sizeof(ctype)-30)
- {
- strcat(ctype, "; charset=");
- strcat(ctype, charset);
- }
z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype);
}
else
yaz_log(log_requestdetail, "Version: %s",
req->implementationVersion);
- assoc_init_reset(assoc);
-
+ assoc_init_reset(assoc,
+ yaz_oi_get_string_oid(&req->otherInfo,
+ yaz_oid_userinfo_client_ip, 1, 0));
assoc->init->auth = req->idAuthentication;
assoc->init->referenceId = req->referenceId;
Z_ReferenceId *referenceId,
Odr_oid *oid, int *errcode)
{
- int recno, total_length = 0, dumped_records = 0;
+ int recno;
+ Odr_int dumped_records = 0;
int toget = odr_int_to_int(*num);
Z_Records *records =
(Z_Records *) odr_malloc(a->encode, sizeof(*records));
{
bend_fetch_rr freq;
Z_NamePlusRecord *thisrec;
- int this_length = 0;
+ Odr_int this_length = 0;
/*
* we get the number of bytes allocated on the stream before any
* allocation done by the backend - this should give us a reasonable
* idea of the total size of the data so far.
*/
- total_length = odr_total(a->encode) - dumped_records;
+ Odr_int total_length = odr_total(a->encode) - dumped_records;
freq.errcode = 0;
freq.errstring = 0;
freq.basename = 0;
this_length = freq.len;
else
this_length = odr_total(a->encode) - total_length - dumped_records;
- yaz_log(YLOG_DEBUG, " fetched record, len=%d, total=%d dumped=%d",
- this_length, total_length, dumped_records);
+ yaz_log(log_requestdetail, " fetched record, len=" ODR_INT_PRINTF
+ " total=" ODR_INT_PRINTF " dumped=" ODR_INT_PRINTF,
+ this_length, total_length, dumped_records);
if (a->preferredMessageSize > 0 &&
- this_length + total_length > a->preferredMessageSize)
+ this_length + total_length > a->preferredMessageSize)
{
/* record is small enough, really */
if (this_length <= a->preferredMessageSize && recno > start)
else /* too big entirely */
{
yaz_log(log_requestdetail, "Record > maxrcdsz "
- "this=%d max=%d",
+ "this=" ODR_INT_PRINTF " max=%d",
this_length, a->maximumRecordSize);
reclist->records[reclist->num_records] =
surrogatediagrec(
bsrr->errcode = 0;
bsrr->errstring = NULL;
bsrr->search_info = NULL;
- bsrr->search_input = req->otherInfo;
+ bsrr->search_input = req->additionalSearchInfo;
+ if (!bsrr->search_input)
+ bsrr->search_input = req->otherInfo;
bsrr->present_number = *req->mediumSetPresentNumber;
+ if (assoc->server && assoc->server->client_query_charset &&
+ req->query->which == Z_Query_type_1)
+ {
+ yaz_iconv_t cd =
+ yaz_iconv_open("UTF-8", assoc->server->client_query_charset);
+ if (cd)
+ {
+ yaz_query_charset_convert_rpnquery(req->query->u.type_1,
+ assoc->decode, cd);
+ yaz_iconv_close(cd);
+ }
+ }
+
if (assoc->server && assoc->server->cql_transform
&& req->query->which == Z_Query_type_104
&& req->query->u.type_104->which == Z_External_CQL)
{
Z_Entry *e;
Z_TermInfo *t;
- Odr_oct *o;
tab[i] = e = (Z_Entry *)odr_malloc(assoc->encode, sizeof(*e));
if (bsrr->entries[i].occurrences >= 0)
t->term = (Z_Term *)
odr_malloc(assoc->encode, sizeof(*t->term));
t->term->which = Z_Term_general;
- t->term->u.general = o =
- (Odr_oct *)odr_malloc(assoc->encode, sizeof(Odr_oct));
- o->buf = (unsigned char *)
- odr_malloc(assoc->encode, o->len = o->size =
- strlen(bsrr->entries[i].term));
- memcpy(o->buf, bsrr->entries[i].term, o->len);
+ t->term->u.general =
+ odr_create_Odr_oct(assoc->encode,
+ bsrr->entries[i].term,
+ strlen(bsrr->entries[i].term));
yaz_log(YLOG_DEBUG, " term #%d: '%s' (" ODR_INT_PRINTF ")", i,
bsrr->entries[i].term, bsrr->entries[i].occurrences);
}