* Copyright (c) 1995-2003, Index Data
* See the file LICENSE for details.
*
- * $Id: seshigh.c,v 1.136 2003-02-17 14:35:42 adam Exp $
+ * $Id: seshigh.c,v 1.143 2003-02-19 15:22:11 adam Exp $
*/
/*
#include <io.h>
#define S_ISREG(x) (x & _S_IFREG)
#include <process.h>
+#include <sys/stat.h>
#else
#include <sys/stat.h>
#include <unistd.h>
#include <yaz/charneg.h>
#include <yaz/otherinfo.h>
#include <yaz/yaz-util.h>
+#include <yaz/pquery.h>
#include <yaz/srw.h>
#include <yaz/backend.h>
xfree(h);
xmalloc_trav("session closed");
if (control_block && control_block->one_shot)
+ {
exit (0);
+ }
}
static void do_close_req(association *a, int reason, char *message,
*cls->closeReason = reason;
cls->diagnosticInformation = message;
process_z_response(a, req, &apdu);
- iochan_settimeout(a->client_chan, 60);
+ iochan_settimeout(a->client_chan, 20);
}
else
{
/* We aren't speaking to this fellow */
if (assoc->state == ASSOC_DEAD)
{
- yaz_log(LOG_LOG, "Closed connection after reject");
+ yaz_log(LOG_LOG, "Connection closed - end of session");
cs_close(conn);
destroy_association(assoc);
iochan_destroy(h);
{ /* restore mask for cs_get operation ... */
iochan_clearflag(h, EVENT_OUTPUT|EVENT_INPUT);
iochan_setflag(h, assoc->cs_get_mask);
- yaz_log(LOG_LOG, "queue empty mask=%d", assoc->cs_get_mask);
if (assoc->state == ASSOC_DEAD)
iochan_setevent(assoc->client_chan, EVENT_TIMEOUT);
}
else
{
assoc->cs_put_mask = EVENT_OUTPUT;
- yaz_log(LOG_LOG, "queue not empty");
}
break;
default:
return 1;
}
-static void srw_bend_fetch(association *assoc, int pos,
- Z_SRW_searchRetrieveRequest *srw_req,
- Z_SRW_record *record)
+static int srw_bend_fetch(association *assoc, int pos,
+ Z_SRW_searchRetrieveRequest *srw_req,
+ Z_SRW_record *record)
{
bend_fetch_rr rr;
ODR o = assoc->encode;
rr.comp->u.complex->generic = (Z_Specification *)
odr_malloc(assoc->decode, sizeof(Z_Specification));
- rr.comp->u.complex->generic->which = Z_Specification_uri;
- rr.comp->u.complex->generic->u.uri = srw_req->recordSchema;
+ rr.comp->u.complex->generic->which = Z_Schema_uri;
+ rr.comp->u.complex->generic->schema.uri = srw_req->recordSchema;
rr.comp->u.complex->generic->elementSpec = 0;
rr.stream = assoc->encode;
if (srw_req->recordSchema)
record->recordSchema = odr_strdup(o, srw_req->recordSchema);
}
+ return rr.errcode;
}
static void srw_bend_search(association *assoc, request *req,
Z_SRW_searchRetrieveResponse *srw_res)
{
char *base = "Default";
+ int srw_error = 0;
bend_search_rr rr;
Z_External *ext;
+
+ yaz_log(LOG_LOG, "Got SRW SearchRetrieveRequest");
if (!assoc->init)
srw_bend_init(assoc);
rr.basenames = &srw_req->database;
rr.referenceId = 0;
- ext = (Z_External *) odr_malloc(assoc->decode, sizeof(*ext));
- ext->direct_reference = odr_getoidbystr(assoc->decode,
- "1.2.840.10003.16.2");
- ext->indirect_reference = 0;
- ext->descriptor = 0;
- ext->which = Z_External_CQL;
+ rr.query = (Z_Query *) odr_malloc (assoc->decode, sizeof(*rr.query));
+
if (srw_req->query)
+ {
+ ext = (Z_External *) odr_malloc(assoc->decode, sizeof(*ext));
+ ext->direct_reference = odr_getoidbystr(assoc->decode,
+ "1.2.840.10003.16.2");
+ ext->indirect_reference = 0;
+ ext->descriptor = 0;
+ ext->which = Z_External_CQL;
ext->u.cql = srw_req->query;
+
+ rr.query->which = Z_Query_type_104;
+ rr.query->u.type_104 = ext;
+ }
+ else if (srw_req->pQuery)
+ {
+ Z_RPNQuery *RPNquery;
+ YAZ_PQF_Parser pqf_parser;
+
+ pqf_parser = yaz_pqf_create ();
+
+ yaz_log(LOG_LOG, "PQF: %s", srw_req->pQuery);
+
+ RPNquery = yaz_pqf_parse (pqf_parser, assoc->decode, srw_req->pQuery);
+ if (!RPNquery)
+ {
+ const char *pqf_msg;
+ size_t off;
+ int code = yaz_pqf_error (pqf_parser, &pqf_msg, &off);
+ yaz_log(LOG_LOG, "%*s^\n", off+4, "");
+ yaz_log(LOG_LOG, "Bad PQF: %s (code %d)\n", pqf_msg, code);
+
+ srw_error = 10;
+ }
+
+ rr.query->which = Z_Query_type_1;
+ rr.query->u.type_1 = RPNquery;
+
+ yaz_pqf_destroy (pqf_parser);
+ }
else
- ext->u.cql = "noterm";
-
- rr.query = (Z_Query *) odr_malloc (assoc->decode, sizeof(*rr.query));
- rr.query->which = Z_Query_type_104;
- rr.query->u.type_104 = ext;
+ srw_error = 11;
+
+ if (srw_req->sortKeys || srw_req->xSortKeys)
+ srw_error = 80;
+
+ if (srw_error)
+ {
+ srw_res->num_diagnostics = 1;
+ srw_res->diagnostics = (Z_SRW_diagnostic *)
+ odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics));
+ srw_res->diagnostics[0].code =
+ odr_intdup(assoc->encode, srw_error);
+ srw_res->diagnostics[0].details = 0;
+ return;
+ }
+
rr.stream = assoc->encode;
rr.decode = assoc->decode;
srw_res->diagnostics = (Z_SRW_diagnostic *)
odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics));
srw_res->diagnostics[0].code =
- odr_intdup(assoc->encode, rr.errcode);
+ odr_intdup(assoc->encode,
+ yaz_diag_bib1_to_srw (rr.errcode));
srw_res->diagnostics[0].details = rr.errstring;
}
else
number * sizeof(*srw_res->records));
for (i = 0; i<number; i++)
{
+ int errcode;
srw_res->records[j].recordData_buf = 0;
- srw_bend_fetch(assoc, i+start, srw_req,
- srw_res->records + j);
+ errcode = srw_bend_fetch(assoc, i+start, srw_req,
+ srw_res->records + j);
+ if (errcode)
+ {
+ srw_res->num_diagnostics = 1;
+ srw_res->diagnostics = (Z_SRW_diagnostic *)
+ odr_malloc(assoc->encode,
+ sizeof(*srw_res->diagnostics));
+ srw_res->diagnostics[0].code =
+ odr_intdup(assoc->encode,
+ yaz_diag_bib1_to_srw (errcode));
+ srw_res->diagnostics[0].details = rr.errstring;
+ break;
+ }
if (srw_res->records[j].recordData_buf)
j++;
}
srw_res->num_records = j;
if (!j)
srw_res->records = 0;
- yaz_log(LOG_LOG, "got %d records", j);
}
}
}
ctype = "text/html";
}
z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype);
- yaz_log(LOG_LOG, "OK send page %s size=%ld", fpath, sz);
}
fclose(f);
}
#endif
if (!strcmp(hreq->path, "/"))
{
+#ifdef DOCDIR
struct stat sbuf;
+#endif
const char *doclink = "";
p = z_get_HTTP_Response(o, 200);
hres = p->u.HTTP_Response;
}
else if (!strcmp(hreq->method, "POST"))
{
-#if HAVE_XSLT
const char *content_type = z_HTTP_header_lookup(hreq->headers,
"Content-Type");
const char *soap_action = z_HTTP_header_lookup(hreq->headers,
!yaz_strcmp_del("text/xml", content_type, "; "))
{
Z_SOAP *soap_package = 0;
- int ret;
+ int ret = -1;
int http_code = 500;
static Z_SOAP_Handler soap_handlers[2] = {
+#if HAVE_XML2
{"http://www.loc.gov/zing/srw/v1.0/", 0,
(Z_SOAP_fun) yaz_srw_codec},
+#endif
{0, 0, 0}
};
-
ret = z_soap_codec(assoc->decode, &soap_package,
&hreq->content_buf, &hreq->content_len,
soap_handlers);
+#if HAVE_XML2
if (!ret && soap_package->which == Z_SOAP_generic &&
soap_package->u.generic->no == 0)
{
http_code = 200;
}
}
-
+#endif
p = z_get_HTTP_Response(o, 200);
hres = p->u.HTTP_Response;
ret = z_soap_codec(assoc->encode, &soap_package,
hres->code = http_code;
z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml");
}
-#endif
if (!p) /* still no response ? */
p = z_get_HTTP_Response(o, 500);
}
}
else
{
+ int t;
+ const char *alive = z_HTTP_header_lookup(hreq->headers, "Keep-Alive");
+
+ if (alive && isdigit(*alive))
+ t = atoi(alive);
+ else
+ t = 30;
+ if (t < 0 || t > 3600)
+ t = 3600;
+ iochan_settimeout(assoc->client_chan,t);
z_HTTP_header_add(o, &hres->headers, "Connection", "Keep-Alive");
}
process_gdu_response(assoc, req, p);
switch (req->apdu_request->which)
{
case Z_APDU_initRequest:
+ iochan_settimeout(assoc->client_chan,
+ statserv_getcontrol()->idle_timeout * 60);
res = process_initRequest(assoc, req); break;
case Z_APDU_searchRequest:
res = process_searchRequest(assoc, req, &fd); break;