/* This file is part of YAZ proxy
- Copyright (C) 1998-2008 Index Data
+ Copyright (C) 1998-2011 Index Data
YAZ proxy is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
#include <yaz/oid_db.h>
#include "msg-thread.h"
+#if YAZ_VERSIONL >= 0x03001D
+#define YAZ_HAS_MK_SURROGATE 1
+#else
+#define YAZ_HAS_MK_SURROGATE 0
+#endif
+
using namespace yazpp_1;
#ifdef WIN32
m_mem_invalid_session = 0;
m_s2z_odr_init = 0;
m_s2z_odr_search = 0;
+ m_s2z_odr_scan = 0;
m_s2z_init_apdu = 0;
m_s2z_search_apdu = 0;
m_s2z_present_apdu = 0;
+ m_s2z_scan_apdu = 0;
m_http_keepalive = 0;
m_http_version = 0;
m_soap_ns = 0;
switch (r->which)
{
case Z_DefaultDiagFormat_v2Addinfo:
- yaz_log(YLOG_LOG, "%sError %d %s:%s",
+ yaz_log(YLOG_LOG, "%sError " ODR_INT_PRINTF " %s:%s",
m_session_str,
*r->condition, diagbib1_str(*r->condition),
r->u.v2Addinfo);
break;
case Z_DefaultDiagFormat_v3Addinfo:
- yaz_log(YLOG_LOG, "%sError %d %s:%s",
+ yaz_log(YLOG_LOG, "%sError " ODR_INT_PRINTF " %s:%s",
m_session_str,
*r->condition, diagbib1_str(*r->condition),
r->u.v3Addinfo);
return 0;
}
-static void yazproxy_encode_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
- int code, const char *details)
+int Yaz_Proxy::z_to_srw_diag(ODR o, Z_SRW_scanResponse *srw_res,
+ Z_DiagRec *dr)
+{
+ if (dr->which == Z_DiagRec_defaultFormat)
+ {
+ int bib1_code = *dr->u.defaultFormat->condition;
+ if (bib1_code == 109)
+ return 404;
+ srw_res->num_diagnostics = 1;
+ srw_res->diagnostics = (Z_SRW_diagnostic *)
+ odr_malloc(o, sizeof(*srw_res->diagnostics));
+ yaz_mk_std_diagnostic(o, srw_res->diagnostics,
+ yaz_diag_bib1_to_srw(*dr->u.defaultFormat->condition),
+ dr->u.defaultFormat->u.v2Addinfo);
+ }
+ return 0;
+}
+
+#if YAZ_HAS_MK_SURROGATE
+#else
+static void yazproxy_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
+ int code, const char *details)
{
const char *message = yaz_diag_srw_str(code);
int len = 200;
record->recordPosition = odr_intdup(o, pos);
record->recordSchema = odr_strdup(o, "info:srw/schema/1/diagnostics-v1.1");
}
-
+#endif
int Yaz_Proxy::send_to_srw_client_ok(int hits, Z_Records *records, int start)
{
Z_NamePlusRecord *npr = records->u.databaseOrSurDiagnostics->records[i];
if (npr->which != Z_NamePlusRecord_databaseRecord)
{
- yaz_log(YLOG_LOG, "Point 1");
- yazproxy_encode_sru_surrogate(
+#if YAZ_HAS_MK_SURROGATE
+ yaz_mk_sru_surrogate(
o, srw_res->records + i, i+start,
YAZ_SRW_RECORD_NOT_AVAILABLE_IN_THIS_SCHEMA, 0);
+#else
+ yazproxy_mk_sru_surrogate(
+ o, srw_res->records + i, i+start,
+ YAZ_SRW_RECORD_NOT_AVAILABLE_IN_THIS_SCHEMA, 0);
+#endif
continue;
}
Z_External *r = npr->u.databaseRecord;
}
else
{
- yaz_log(YLOG_LOG, "Point 2");
- yazproxy_encode_sru_surrogate(
+#if YAZ_HAS_MK_SURROGATE
+ yaz_mk_sru_surrogate(
o, srw_res->records + i, i+start,
YAZ_SRW_RECORD_NOT_AVAILABLE_IN_THIS_SCHEMA, 0);
+#else
+ yazproxy_mk_sru_surrogate(
+ o, srw_res->records + i, i+start,
+ YAZ_SRW_RECORD_NOT_AVAILABLE_IN_THIS_SCHEMA, 0);
+#endif
}
}
}
}
+int Yaz_Proxy::send_to_srw_client_ok(Z_ListEntries *entries)
+{
+ ODR o = odr_encode();
+ Z_SRW_PDU *srw_pdu = yaz_srw_get(o, Z_SRW_scan_response);
+ Z_SRW_scanResponse *srw_res = srw_pdu->u.scan_response;
+
+ if (entries && entries->num_entries > 0)
+ {
+ srw_res->num_terms = entries->num_entries;
+ int i;
+ srw_res->terms = (Z_SRW_scanTerm *)
+ odr_malloc(o, srw_res->num_terms * sizeof(Z_SRW_scanTerm));
+ for (i = 0; i < srw_res->num_terms; i++)
+ {
+ if (entries->entries[i]->which == Z_Entry_termInfo)
+ {
+ switch(entries->entries[i]->u.termInfo->term->which)
+ {
+ case Z_Term_general:
+ srw_res->terms[i].value = odr_strdupn(o,
+ (char *) entries->entries[i]->u.termInfo->term->u.general->buf,
+ entries->entries[i]->u.termInfo->term->u.general->len);
+ break;
+ default:
+ srw_res->terms[i].value = NULL;
+ }
+ if (entries->entries[i]->u.termInfo->globalOccurrences != NULL)
+ srw_res->terms[i].numberOfRecords = odr_intdup(o,
+ *entries->entries[i]->u.termInfo->globalOccurrences);
+ else
+ srw_res->terms[i].numberOfRecords = NULL;
+ if (entries->entries[i]->u.termInfo->displayTerm != NULL)
+ srw_res->terms[i].displayTerm = odr_strdup(o,
+ entries->entries[i]->u.termInfo->displayTerm);
+ else
+ srw_res->terms[i].displayTerm = NULL;
+ srw_res->terms[i].whereInList = NULL;
+ }
+ }
+ }
+ if (entries && entries->num_nonsurrogateDiagnostics > 0)
+ {
+ int http_code;
+ http_code = z_to_srw_diag(odr_encode(), srw_res,
+ entries->nonsurrogateDiagnostics[0]);
+ if (http_code)
+ return send_http_response(http_code);
+ }
+ return send_srw_response(srw_pdu);
+
+}
+
int Yaz_Proxy::send_srw_search_response(Z_SRW_diagnostic *diagnostics,
int num_diagnostics, int http_code /* = 200 */)
{
return send_srw_response(srw_pdu, http_code);
}
+int Yaz_Proxy::send_srw_scan_response(Z_SRW_diagnostic *diagnostics,
+ int num_diagnostics, int http_code /* = 200 */)
+{
+ ODR o = odr_encode();
+ Z_SRW_PDU *srw_pdu = yaz_srw_get(o, Z_SRW_scan_response);
+ Z_SRW_scanResponse *srw_res = srw_pdu->u.scan_response;
+
+ srw_res->num_diagnostics = num_diagnostics;
+ srw_res->diagnostics = diagnostics;
+ return send_srw_response(srw_pdu, http_code);
+}
+
int Yaz_Proxy::send_srw_explain_response(Z_SRW_diagnostic *diagnostics,
int num_diagnostics)
{
+ int http_status = 404;
Yaz_ProxyConfig *cfg = check_reconfigure();
if (cfg)
{
int len;
char *b = cfg->get_explain_doc(odr_encode(), 0 /* target */,
- m_s2z_database, &len);
+ m_s2z_database, &len, &http_status);
if (b)
{
Z_SRW_PDU *res = yaz_srw_get(odr_encode(), Z_SRW_explain_response);
return send_srw_response(res);
}
}
- return send_http_response(404);
+ return send_http_response(http_status);
}
int Yaz_Proxy::send_PDU_convert(Z_APDU *apdu)
{
send_to_srw_client_error(3, 0);
}
- else if (!m_s2z_search_apdu)
+ else if (m_s2z_search_apdu)
{
- send_srw_explain_response(0, 0);
+ handle_incoming_Z_PDU(m_s2z_search_apdu);
+ }
+ else if (m_s2z_scan_apdu)
+ {
+ handle_incoming_Z_PDU(m_s2z_scan_apdu);
}
else
{
- handle_incoming_Z_PDU(m_s2z_search_apdu);
+ send_srw_explain_response(0, 0);
}
}
else if (m_s2z_search_apdu && apdu->which == Z_APDU_searchResponse)
Z_PresentResponse *res = apdu->u.presentResponse;
send_to_srw_client_ok(m_s2z_hit_count, res->records, start);
}
+ else if (m_s2z_scan_apdu && apdu->which == Z_APDU_scanResponse)
+ {
+ Z_ScanResponse *res = apdu->u.scanResponse;
+ send_to_srw_client_ok(res->entries);
+ }
}
else
{
}
if (sr->resultCount)
{
- yaz_log(YLOG_LOG, "%s%d hits", m_session_str,
+ yaz_log(YLOG_LOG, "%s" ODR_INT_PRINTF " hits", m_session_str,
*sr->resultCount);
if (*sr->resultCount < 0)
{
{
Z_Records *rec = (Z_Records *)
odr_malloc (odr, sizeof(*rec));
- int *err = (int *)
+ Odr_int *err = (Odr_int *)
odr_malloc (odr, sizeof(*err));
Z_DiagRec *drec = (Z_DiagRec *)
odr_malloc (odr, sizeof(*drec));
return rec;
}
+Z_ListEntries *Yaz_Proxy::create_nonSurrogateDiagnostics2(ODR odr,
+ int error,
+ const char *addinfo)
+{
+ Z_ListEntries *rec = (Z_ListEntries *)
+ odr_malloc (odr, sizeof(*rec));
+ Odr_int *err = (Odr_int *)
+ odr_malloc (odr, sizeof(*err));
+ Z_DiagRec *drec = (Z_DiagRec *)
+ odr_malloc (odr, sizeof(*drec));
+ Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
+ odr_malloc (odr, sizeof(*dr));
+ *err = error;
+ drec->which = Z_DiagRec_defaultFormat;
+ drec->u.defaultFormat = dr;
+ rec->num_entries = 0;
+ rec->entries = NULL;
+ rec->num_nonsurrogateDiagnostics = 1;
+ rec->nonsurrogateDiagnostics =
+ (Z_DiagRec **)odr_malloc(odr, sizeof(Z_DiagRec *));
+ rec->nonsurrogateDiagnostics[0] = drec;
+ dr->diagnosticSetId = odr_oiddup(odr, yaz_oid_diagset_bib_1);
+ dr->condition = err;
+ dr->which = Z_DefaultDiagFormat_v2Addinfo;
+ dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
+ return rec;
+}
+
Z_APDU *Yaz_Proxy::handle_query_transformation(Z_APDU *apdu)
{
if (apdu->which == Z_APDU_searchRequest &&
}
return apdu;
}
+ else if (apdu->which == Z_APDU_scanRequest)
+ {
+ Z_RPNQuery *rpnquery = 0;
+ Z_ScanRequest *sr = apdu->u.scanRequest;
+ char *addinfo = 0;
+
+ yaz_log(YLOG_LOG, "%sCQL: %s", m_session_str,
+ sr->termListAndStartPoint->term->u.characterString);
+
+ int r = m_cql2rpn.query_transform(sr->termListAndStartPoint->term->u.characterString,
+ &rpnquery, odr_encode(),
+ &addinfo);
+ if (r == -3)
+ yaz_log(YLOG_LOG, "%sNo CQL to RPN table", m_session_str);
+ else if (r)
+ {
+ yaz_log(YLOG_LOG, "%sCQL Conversion error %d", m_session_str, r);
+ Z_APDU *new_apdu = create_Z_PDU(Z_APDU_scanResponse);
+
+ new_apdu->u.scanResponse->referenceId = sr->referenceId;
+ new_apdu->u.scanResponse->entries =
+ create_nonSurrogateDiagnostics2(odr_encode(),
+ yaz_diag_srw_to_bib1(r),
+ addinfo);
+ *new_apdu->u.scanResponse->scanStatus = Z_Scan_failure;
+
+ send_to_client(new_apdu);
+
+ return 0;
+ }
+ else
+ {
+ sr->attributeSet = rpnquery->attributeSetId;
+ if (rpnquery->RPNStructure->which == Z_RPNStructure_simple)
+ sr->termListAndStartPoint = rpnquery->RPNStructure->u.simple->u.attributesPlusTerm;
+ }
+ return apdu;
+ }
return apdu;
}
m_charset_converter->convert_type_1(rpnquery, odr_encode());
}
}
+ else if (apdu->which == Z_APDU_scanRequest &&
+ apdu->u.scanRequest->termListAndStartPoint)
+ {
+ if (apdu->u.scanRequest->termListAndStartPoint->term)
+ if (m_http_version)
+ m_charset_converter->set_client_query_charset("UTF-8");
+ Z_Term *term = apdu->u.scanRequest->termListAndStartPoint->term;
+ m_charset_converter->convert_term(term, odr_encode());
+ }
return apdu;
}
return 0;
}
}
+ else if (apdu->which == Z_APDU_scanRequest)
+ {
+ Z_ScanRequest *sr = apdu->u.scanRequest;
+ int err = 0;
+ char *addinfo = 0;
+
+ Yaz_ProxyConfig *cfg = check_reconfigure();
+// Something like this needs to be implemented later:
+/*
+ if (cfg)
+ err = cfg->check_type_1_attributes(odr_encode(), m_default_target,
+ sr->termListAndStartPoint->attributes, &addinfo);
+*/
+ if (err)
+ {
+ Z_APDU *new_apdu = create_Z_PDU(Z_APDU_scanResponse);
+
+ new_apdu->u.scanResponse->referenceId = sr->referenceId;
+ new_apdu->u.scanResponse->entries =
+ create_nonSurrogateDiagnostics2(odr_encode(), err, addinfo);
+ *new_apdu->u.scanResponse->scanStatus = Z_Scan_failure;
+
+ send_to_client(new_apdu);
+
+ return 0;
+ }
+ }
+
return apdu;
}
odr_destroy(m_s2z_odr_search);
m_s2z_odr_search = 0;
}
+ if (m_s2z_odr_scan)
+ {
+ odr_destroy(m_s2z_odr_scan);
+ m_s2z_odr_scan = 0;
+ }
m_http_keepalive = 0;
m_http_version = 0;
{
m_s2z_odr_init = odr_createmem(ODR_ENCODE);
m_s2z_odr_search = odr_createmem(ODR_ENCODE);
+ m_s2z_odr_scan = odr_createmem(ODR_ENCODE);
m_soap_ns = odr_strdup(m_s2z_odr_search, soap_package->ns);
m_s2z_init_apdu = 0;
m_s2z_search_apdu = 0;
m_s2z_present_apdu = 0;
+ m_s2z_scan_apdu = 0;
m_s2z_stylesheet = 0;
Z_IdAuthentication *auth = NULL;
- if (srw_pdu->username && srw_pdu->password)
+ if (srw_pdu->username && !srw_pdu->password)
+ {
+ yaz_log(YLOG_LOG, "username: %s\n", srw_pdu->username);
+ auth = (Z_IdAuthentication *) odr_malloc(m_s2z_odr_init, sizeof(Z_IdAuthentication));
+ auth->which = Z_IdAuthentication_open;
+ auth->u.open = odr_strdup(m_s2z_odr_init, srw_pdu->username);
+ }
+ else if (srw_pdu->username && srw_pdu->password)
{
yaz_log(YLOG_LOG, "username/password: %s/%s\n",
srw_pdu->username, srw_pdu->password);
m_s2z_init_apdu = zget_APDU(m_s2z_odr_init,
Z_APDU_initRequest);
+ ODR_MASK_SET(m_s2z_init_apdu->u.initRequest->options, Z_Options_scan);
m_s2z_init_apdu->u.initRequest->idAuthentication = auth;
// prevent m_initRequest_apdu memory from being grabbed
m_s2z_init_apdu = zget_APDU(m_s2z_odr_init,
Z_APDU_initRequest);
+ ODR_MASK_SET(m_s2z_init_apdu->u.initRequest->options, Z_Options_scan);
m_s2z_init_apdu->u.initRequest->idAuthentication = auth;
// prevent m_initRequest_apdu memory from being grabbed
}
else if (srw_pdu->which == Z_SRW_scan_request)
{
+ Z_SRW_scanRequest *srw_req = srw_pdu->u.scan_request;
+
+ const char *backend_db = srw_req->database;
+ srw_get_client(srw_req->database, &backend_db);
+
m_s2z_database = odr_strdup(m_s2z_odr_init,
- srw_pdu->u.scan_request->database);
-
- yaz_add_srw_diagnostic(odr_decode(),
- &diagnostic, &num_diagnostic,
- 4, "scan");
- Z_SRW_PDU *srw_pdu =
- yaz_srw_get(odr_encode(),
- Z_SRW_scan_response);
- Z_SRW_scanResponse *srw_res = srw_pdu->u.scan_response;
-
- srw_res->diagnostics = diagnostic;
- srw_res->num_diagnostics = num_diagnostic;
- send_srw_response(srw_pdu);
- return;
+ srw_req->database);
+ // save stylesheet
+ if (srw_req->stylesheet)
+ m_s2z_stylesheet =
+ odr_strdup(m_s2z_odr_init, srw_req->stylesheet);
+
+ // prepare scan PDU
+ m_s2z_scan_apdu = zget_APDU(m_s2z_odr_scan,
+ Z_APDU_scanRequest);
+ Z_ScanRequest *z_scanRequest =
+ m_s2z_scan_apdu->u.scanRequest;
+
+ z_scanRequest->num_databaseNames = 1;
+ z_scanRequest->databaseNames = (char**)
+ odr_malloc(m_s2z_odr_scan, sizeof(char *));
+ z_scanRequest->databaseNames[0] = odr_strdup(m_s2z_odr_scan,
+ backend_db);
+
+ // query transformation
+ if (srw_req->query_type == Z_SRW_query_type_cql)
+ {
+ z_scanRequest->termListAndStartPoint =
+ (Z_AttributesPlusTerm *)odr_malloc(m_s2z_odr_scan, sizeof(Z_AttributesPlusTerm));
+ z_scanRequest->termListAndStartPoint->attributes = NULL;
+ z_scanRequest->termListAndStartPoint->term =
+ (Z_Term *)odr_malloc(m_s2z_odr_scan, sizeof(Z_Term));
+ z_scanRequest->termListAndStartPoint->term->which =
+ Z_Term_characterString;
+ z_scanRequest->termListAndStartPoint->term->u.characterString =
+ odr_strdup(m_s2z_odr_scan, srw_req->scanClause.cql);
+ }
+
+ if (srw_req->responsePosition)
+ z_scanRequest->preferredPositionInResponse =
+ odr_intdup(m_s2z_odr_scan, *srw_req->responsePosition);
+ if (srw_req->maximumTerms)
+ *z_scanRequest->numberOfTermsRequested = *srw_req->maximumTerms;
+
+ if (!m_client)
+ {
+ m_s2z_init_apdu = zget_APDU(m_s2z_odr_init,
+ Z_APDU_initRequest);
+
+ ODR_MASK_SET(m_s2z_init_apdu->u.initRequest->options, Z_Options_scan);
+ m_s2z_init_apdu->u.initRequest->idAuthentication = auth;
+
+ // prevent m_initRequest_apdu memory from being grabbed
+ // in Yaz_Proxy::handle_incoming_Z_PDU
+ m_initRequest_apdu = m_s2z_init_apdu;
+ handle_incoming_Z_PDU(m_s2z_init_apdu);
+ return;
+ }
+ else
+ {
+ handle_incoming_Z_PDU(m_s2z_scan_apdu);
+ return;
+ }
}
else
{
YAZ_SRW_SYSTEM_TEMPORARILY_UNAVAILABLE, addr);
if (m_s2z_search_apdu)
send_srw_search_response(diagnostic, num_diagnostic);
+ else if (m_s2z_scan_apdu)
+ send_srw_scan_response(diagnostic, num_diagnostic);
else
send_srw_explain_response(diagnostic, num_diagnostic);
}
const char *zurl_in_use[MAX_ZURL_PLEX];
int limit_bw, limit_pdu, limit_req, limit_search;
int target_idletime, client_idletime;
- int max_sockets;
+ int max_sockets = m_max_sockets;
int max_clients;
int keepalive_limit_bw, keepalive_limit_pdu;
int pre_init;
/*
* Local variables:
* c-basic-offset: 4
+ * c-file-style: "Stroustrup"
* indent-tabs-mode: nil
* End:
* vim: shiftwidth=4 tabstop=8 expandtab