X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fseshigh.c;h=92627c26a0e5c9fd716f5bc7748ef255446f4e7b;hp=9bf39cae82cc5c75ed234d43c00bb0a704df87f8;hb=2715f6522ca62ab5dbc886c21ed18945743216f0;hpb=002e8d5e6cdb9f188fd91df930b6cc763f50f96d diff --git a/src/seshigh.c b/src/seshigh.c index 9bf39ca..92627c2 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -1,5 +1,5 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2010 Index Data + * Copyright (C) 1995-2011 Index Data * See the file LICENSE for details. */ /** @@ -25,12 +25,14 @@ * minimize memory allocation/deallocation during normal operation. * */ +#if HAVE_CONFIG_H +#include +#endif #include #include #include #include -#include #if HAVE_SYS_TYPES_H #include @@ -54,7 +56,6 @@ #include #endif -#include #include #include #include "eventl.h" @@ -224,10 +225,6 @@ void destroy_association(association *h) request_delq(&h->outgoing); xfree(h); xmalloc_trav("session closed"); - if (cb && cb->one_shot) - { - exit(0); - } } static void do_close_req(association *a, int reason, char *message, @@ -301,7 +298,9 @@ int ir_read(IOCHAN h, int event) else if (res <= 0) { yaz_log(log_session, "Connection closed by client"); - assoc->state = ASSOC_DEAD; + cs_close(conn); + destroy_association(assoc); + iochan_destroy(h); return 0; } else if (res == 1) /* incomplete read - wait for more */ @@ -541,6 +540,9 @@ static int srw_bend_init(association *assoc, Z_SRW_diagnostic **d, int *num, Z_S len = strlen(sr->username) + 1; if (sr->password) len += strlen(sr->password) + 2; + yaz_log(log_requestdetail, "username=%s password-len=%ld", + sr->username, (long) + (sr->password ? strlen(sr->password) : 0)); auth->which = Z_IdAuthentication_open; auth->u.open = (char *) odr_malloc(assoc->decode, len); strcpy(auth->u.open, sr->username); @@ -755,7 +757,7 @@ static int srw_bend_fetch(association *assoc, int pos, } static int cql2pqf(ODR odr, const char *cql, cql_transform_t ct, - Z_Query *query_result) + Z_Query *query_result, char **sortkeys_p) { /* have a CQL query and CQL to PQF transform .. */ CQL_parser cp = cql_parser_create(); @@ -763,7 +765,8 @@ static int cql2pqf(ODR odr, const char *cql, cql_transform_t ct, int srw_errcode = 0; const char *add = 0; char rpn_buf[5120]; - + + *sortkeys_p = 0; r = cql_parser_string(cp, cql); if (r) { @@ -771,12 +774,29 @@ static int cql2pqf(ODR odr, const char *cql, cql_transform_t ct, } if (!r) { + struct cql_node *cn = cql_parser_result(cp); + /* Syntax OK */ - r = cql_transform_buf(ct, - cql_parser_result(cp), - rpn_buf, sizeof(rpn_buf)-1); + r = cql_transform_buf(ct, cn, rpn_buf, sizeof(rpn_buf)-1); if (r) srw_errcode = cql_transform_error(ct, &add); + else + { + char out[100]; + int r = cql_sortby_to_sortkeys_buf(cn, out, sizeof(out)-1); + + if (r == 0) + { + if (*out) + yaz_log(log_requestdetail, "srw_sortKeys '%s'", out); + *sortkeys_p = odr_strdup(odr, out); + } + else + { + yaz_log(log_requestdetail, "failed to create srw_sortKeys"); + srw_errcode = YAZ_SRW_UNSUPP_SORT_TYPE; + } + } } if (!r) { @@ -809,7 +829,8 @@ static int cql2pqf_scan(ODR odr, const char *cql, cql_transform_t ct, { Z_Query query; Z_RPNQuery *rpn; - int srw_error = cql2pqf(odr, cql, ct, &query); + char *sortkeys = 0; + int srw_error = cql2pqf(odr, cql, ct, &query, &sortkeys); if (srw_error) return srw_error; if (query.which != Z_Query_type_1 && query.which != Z_Query_type_101) @@ -846,7 +867,7 @@ static int ccl2pqf(ODR odr, const Odr_oct *ccl, CCL_bibset bibset, return 0; } -static void srw_bend_search(association *assoc, request *req, +static void srw_bend_search(association *assoc, Z_SRW_PDU *sr, Z_SRW_PDU *res, int *http_code) @@ -883,7 +904,9 @@ static void srw_bend_search(association *assoc, request *req, { int srw_errcode = cql2pqf(assoc->encode, srw_req->query.cql, assoc->server->cql_transform, - rr.query); + rr.query, + &rr.srw_sortKeys); + if (srw_errcode) { yaz_add_srw_diagnostic(assoc->encode, @@ -942,14 +965,15 @@ static void srw_bend_search(association *assoc, request *req, rr.stream = assoc->encode; rr.decode = assoc->decode; rr.print = assoc->print; - if ( srw_req->sort.sortKeys ) + if (srw_req->sort.sortKeys) rr.srw_sortKeys = odr_strdup(assoc->encode, - srw_req->sort.sortKeys ); + srw_req->sort.sortKeys); rr.association = assoc; rr.hits = 0; rr.errcode = 0; rr.errstring = 0; rr.search_info = 0; + rr.search_input = 0; yaz_log_zquery_level(log_requestdetail,rr.query); (assoc->init->bend_search)(assoc->backend, &rr); @@ -1139,7 +1163,7 @@ static void srw_bend_search(association *assoc, request *req, (srw_res->numberOfRecords ? *srw_res->numberOfRecords : 0)); } - wrbuf_printf(wr, " %s " ODR_INT_PRINTF " +%d", + wrbuf_printf(wr, " %s " ODR_INT_PRINTF "+%d", (srw_res->resultSetId ? srw_res->resultSetId : "-"), (srw_req->startRecord ? *srw_req->startRecord : 1), @@ -1149,7 +1173,7 @@ static void srw_bend_search(association *assoc, request *req, } } -static char *srw_bend_explain_default(void *handle, bend_explain_rr *rr) +static char *srw_bend_explain_default(bend_explain_rr *rr) { #if YAZ_HAVE_XML2 xmlNodePtr ptr = (xmlNode *) rr->server_node_ptr; @@ -1185,7 +1209,7 @@ static char *srw_bend_explain_default(void *handle, bend_explain_rr *rr) return 0; } -static void srw_bend_explain(association *assoc, request *req, +static void srw_bend_explain(association *assoc, Z_SRW_PDU *sr, Z_SRW_explainResponse *srw_res, int *http_code) @@ -1211,7 +1235,7 @@ static void srw_bend_explain(association *assoc, request *req, if (assoc->init->bend_explain) (*assoc->init->bend_explain)(assoc->backend, &rr); else - srw_bend_explain_default(assoc->backend, &rr); + srw_bend_explain_default(&rr); if (rr.explain_buf) { @@ -1233,7 +1257,7 @@ static void srw_bend_explain(association *assoc, request *req, } } -static void srw_bend_scan(association *assoc, request *req, +static void srw_bend_scan(association *assoc, Z_SRW_PDU *sr, Z_SRW_scanResponse *srw_res, int *http_code) @@ -1421,7 +1445,7 @@ static void srw_bend_scan(association *assoc, request *req, } -static void srw_bend_update(association *assoc, request *req, +static void srw_bend_update(association *assoc, Z_SRW_PDU *sr, Z_SRW_updateResponse *srw_res, int *http_code) @@ -1790,7 +1814,7 @@ static void process_http_request(association *assoc, request *req) } else { - srw_bend_search(assoc, req, sr, res, &http_code); + srw_bend_search(assoc, sr, res, &http_code); } if (http_code == 200) soap_package->u.generic->p = res; @@ -1805,8 +1829,7 @@ static void process_http_request(association *assoc, request *req) res->u.explain_response->diagnostics = diagnostic; res->u.explain_response->num_diagnostics = num_diagnostic; } - srw_bend_explain(assoc, req, sr, - res->u.explain_response, &http_code); + srw_bend_explain(assoc, sr, res->u.explain_response, &http_code); if (http_code == 200) soap_package->u.generic->p = res; } @@ -1820,8 +1843,7 @@ static void process_http_request(association *assoc, request *req) res->u.scan_response->diagnostics = diagnostic; res->u.scan_response->num_diagnostics = num_diagnostic; } - srw_bend_scan(assoc, req, sr, - res->u.scan_response, &http_code); + srw_bend_scan(assoc, sr, res->u.scan_response, &http_code); if (http_code == 200) soap_package->u.generic->p = res; } @@ -1836,8 +1858,7 @@ static void process_http_request(association *assoc, request *req) 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, req, sr, - res->u.update_response, &http_code); + srw_bend_update(assoc, sr, res->u.update_response, &http_code); if (http_code == 200) soap_package->u.generic->p = res; } @@ -1860,7 +1881,6 @@ static void process_http_request(association *assoc, request *req) {0, 0, 0} }; char ctype[80]; - int ret; p = z_get_HTTP_Response(o, 200); hres = p->u.HTTP_Response; @@ -1871,9 +1891,9 @@ static void process_http_request(association *assoc, request *req) if (stylesheet && *stylesheet == '\0') stylesheet = 0; - ret = z_soap_codec_enc_xsl(assoc->encode, &soap_package, - &hres->content_buf, &hres->content_len, - soap_handlers, charset, stylesheet); + z_soap_codec_enc_xsl(assoc->encode, &soap_package, + &hres->content_buf, &hres->content_len, + soap_handlers, charset, stylesheet); hres->code = http_code; strcpy(ctype, "text/xml"); @@ -1909,7 +1929,7 @@ static void process_http_request(association *assoc, request *req) keepalive = 1; hres->version = "1.1"; } - if (!keepalive) + if (!keepalive || !assoc->last_control->keepalive) { z_HTTP_header_add(o, &hres->headers, "Connection", "close"); assoc->state = ASSOC_DEAD; @@ -1920,7 +1940,7 @@ static void process_http_request(association *assoc, request *req) int t; const char *alive = z_HTTP_header_lookup(hreq->headers, "Keep-Alive"); - if (alive && isdigit(*(const unsigned char *) alive)) + if (alive && yaz_isdigit(*(const unsigned char *) alive)) t = atoi(alive); else t = 15; @@ -2035,7 +2055,7 @@ static int process_z_request(association *assoc, request *req, char **msg) } else { - yaz_log(YLOG_DEBUG, " result unavailble"); + yaz_log(YLOG_DEBUG, " result unavailable"); retval = -1; } return retval; @@ -2091,7 +2111,7 @@ static int process_gdu_response(association *assoc, request *req, Z_GDU *res) */ static int process_z_response(association *assoc, request *req, Z_APDU *res) { - Z_GDU *gres = (Z_GDU *) odr_malloc(assoc->encode, sizeof(*res)); + Z_GDU *gres = (Z_GDU *) odr_malloc(assoc->encode, sizeof(*gres)); gres->which = Z_GDU_Z3950; gres->u.z3950 = res; @@ -2161,7 +2181,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) yaz_log(log_requestdetail, "Config: %s", cb->configname); - iochan_settimeout(assoc->client_chan, cb->idle_timeout * 60); + iochan_settimeout(assoc->client_chan, cb->idle_timeout); /* we have a backend control block, so call that init function */ if (!(binitres = (*cb->bend_init)(assoc->init))) @@ -2426,13 +2446,19 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, (Z_Records *) odr_malloc(a->encode, sizeof(*records)); Z_NamePlusRecordList *reclist = (Z_NamePlusRecordList *) odr_malloc(a->encode, sizeof(*reclist)); - Z_NamePlusRecord **list = - (Z_NamePlusRecord **) odr_malloc(a->encode, sizeof(*list) * toget); records->which = Z_Records_DBOSD; records->u.databaseOrSurDiagnostics = reclist; reclist->num_records = 0; - reclist->records = list; + + if (toget < 0) + return diagrec(a, YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE, 0); + else if (toget == 0) + reclist->records = odr_nullval(); + else + reclist->records = (Z_NamePlusRecord **) + odr_malloc(a->encode, sizeof(*reclist->records) * toget); + *pres = Z_PresentStatus_success; *num = 0; *next = 0; @@ -2498,6 +2524,7 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, } if (freq.record == 0) /* no error and no record ? */ { + *pres = Z_PresentStatus_partial_4; *next = 0; /* signal end-of-set and stop */ break; } @@ -2515,6 +2542,8 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, { yaz_log(log_requestdetail, " Dropped last normal-sized record"); *pres = Z_PresentStatus_partial_2; + if (*next > 0) + (*next)--; break; } /* record can only be fetched by itself */ @@ -2525,7 +2554,9 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, { yaz_log(YLOG_DEBUG, " Dropped it"); reclist->records[reclist->num_records] = - surrogatediagrec(a, freq.basename, 16, 0); + surrogatediagrec( + a, freq.basename, + YAZ_BIB1_RECORD_EXCEEDS_PREFERRED_MESSAGE_SIZE, 0); reclist->num_records++; dumped_records += this_length; continue; @@ -2537,7 +2568,9 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, "this=%d max=%d", this_length, a->maximumRecordSize); reclist->records[reclist->num_records] = - surrogatediagrec(a, freq.basename, 17, 0); + surrogatediagrec( + a, freq.basename, + YAZ_BIB1_RECORD_EXCEEDS_MAXIMUM_RECORD_SIZE, 0); reclist->num_records++; dumped_records += this_length; continue; @@ -2551,7 +2584,10 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, thisrec->which = Z_NamePlusRecord_databaseRecord; if (!freq.output_format) - freq.output_format = freq.request_format; + { + yaz_log(YLOG_WARN, "bend_fetch output_format not set"); + return 0; + } thisrec->u.databaseRecord = z_ext_record_oid( a->encode, freq.output_format, freq.record, freq.len); if (!thisrec->u.databaseRecord) @@ -2580,7 +2616,7 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb) bsrr->extra_args = 0; bsrr->extra_response_data = 0; - yaz_log (log_requestdetail, "ResultSet '%s'", req->resultSetName); + yaz_log(log_requestdetail, "ResultSet '%s'", req->resultSetName); if (req->databaseNames) { int i; @@ -2605,6 +2641,7 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb) bsrr->errcode = 0; bsrr->errstring = NULL; bsrr->search_info = NULL; + bsrr->search_input = req->otherInfo; if (assoc->server && assoc->server->cql_transform && req->query->which == Z_Query_type_104 @@ -2613,7 +2650,8 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb) /* have a CQL query and a CQL to PQF transform .. */ int srw_errcode = cql2pqf(bsrr->stream, req->query->u.type_104->u.cql, - assoc->server->cql_transform, bsrr->query); + assoc->server->cql_transform, bsrr->query, + &bsrr->srw_sortKeys); if (srw_errcode) bsrr->errcode = yaz_diag_srw_to_bib1(srw_errcode); } @@ -2823,7 +2861,6 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb) Odr_int *next; Odr_int *num; int errcode = 0; - const char *errstring = 0; yaz_log(log_requestdetail, "Got PresentRequest."); @@ -2852,7 +2889,6 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb) resp->records = diagrec(assoc, bprr->errcode, bprr->errstring); *resp->presentStatus = Z_PresentStatus_failure; errcode = bprr->errcode; - errstring = bprr->errstring; } } apdu = (Z_APDU *)odr_malloc(assoc->encode, sizeof(*apdu)); @@ -2931,6 +2967,7 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb) if (req->stepSize) step_size = odr_int_to_int(*req->stepSize); + res->stepSize = 0; res->scanStatus = scanStatus; res->numberOfEntriesReturned = numberOfEntriesReturned; res->positionOfTerm = 0;