X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fseshigh.c;h=a9e248e41a47c2d0aff229f4f78c31c769578c1b;hp=24ade483d37dc2f77df4b60518b002e880b1612a;hb=75fff8a1c0b9deb4b402475a408fc69bc2b06a13;hpb=f991472f1e2474cb605b4b40f69af1456b870570 diff --git a/src/seshigh.c b/src/seshigh.c index 24ade48..a9e248e 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -1,5 +1,5 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2013 Index Data + * Copyright (C) Index Data * See the file LICENSE for details. */ /** @@ -56,6 +56,7 @@ #include #endif +#include #include #include #include "eventl.h" @@ -73,7 +74,7 @@ #include #include #include - +#include #include #include #include @@ -468,7 +469,8 @@ void ir_session(IOCHAN h, int event) } if (event & EVENT_EXCEPT) { - yaz_log(YLOG_WARN, "ir_session (exception)"); + if (assoc->state != ASSOC_DEAD) + yaz_log(YLOG_WARN, "ir_session (exception)"); cs_close(conn); destroy_association(assoc); iochan_destroy(h); @@ -478,8 +480,10 @@ void ir_session(IOCHAN h, int event) 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)); @@ -509,13 +513,24 @@ static void assoc_init_reset(association *assoc) 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) @@ -525,7 +540,7 @@ static int srw_bend_init(association *assoc, Z_SRW_diagnostic **d, int *num, Z_S 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) { @@ -687,6 +702,7 @@ static int retrieve_fetch(association *assoc, bend_fetch_rr *rr) if (r) { rr->errcode = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS; + rr->surrogate_flag = 1; if (details) rr->errstring = odr_strdup(rr->stream, details); } @@ -901,6 +917,7 @@ static int ccl2pqf(ODR odr, const Odr_oct *ccl, CCL_bibset bibset, } static void srw_bend_search(association *assoc, + Z_HTTP_Header *headers, Z_SRW_PDU *sr, Z_SRW_PDU *res, int *http_code) @@ -912,7 +929,8 @@ static void srw_bend_search(association *assoc, *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; @@ -933,11 +951,11 @@ static void srw_bend_search(association *assoc, rr.present_number = srw_req->maximumRecords ? *srw_req->maximumRecords : 0; - if (srw_req->query_type == Z_SRW_query_type_cql) + if (!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) { if (assoc->server && assoc->server->cql_transform) { - int srw_errcode = cql2pqf(assoc->encode, srw_req->query.cql, + int srw_errcode = cql2pqf(assoc->encode, srw_req->query, assoc->server->cql_transform, rr.query, &rr.srw_sortKeys); @@ -959,21 +977,20 @@ static void srw_bend_search(association *assoc, ext->indirect_reference = 0; ext->descriptor = 0; ext->which = Z_External_CQL; - ext->u.cql = srw_req->query.cql; + ext->u.cql = srw_req->query; rr.query->which = Z_Query_type_104; rr.query->u.type_104 = ext; } } - else if (srw_req->query_type == Z_SRW_query_type_pqf) + else if (!strcmp(srw_req->queryType, "pqf")) { Z_RPNQuery *RPNquery; YAZ_PQF_Parser pqf_parser; pqf_parser = yaz_pqf_create(); - RPNquery = yaz_pqf_parse(pqf_parser, assoc->decode, - srw_req->query.pqf); + RPNquery = yaz_pqf_parse(pqf_parser, assoc->decode, srw_req->query); if (!RPNquery) { const char *pqf_msg; @@ -1009,6 +1026,11 @@ static void srw_bend_search(association *assoc, 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); @@ -1047,6 +1069,7 @@ static void srw_bend_search(association *assoc, 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 */ @@ -1161,7 +1184,19 @@ static void srw_bend_search(association *assoc, 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, @@ -1175,21 +1210,8 @@ static void srw_bend_search(association *assoc, } if (log_request) { - const char *querystr = "?"; - const char *querytype = "?"; WRBUF wr = wrbuf_alloc(); - switch (srw_req->query_type) - { - case Z_SRW_query_type_cql: - querytype = "CQL"; - querystr = srw_req->query.cql; - break; - case Z_SRW_query_type_pqf: - querytype = "PQF"; - querystr = srw_req->query.pqf; - break; - } wrbuf_printf(wr, "SRWSearch %s ", srw_req->database); if (srw_res->num_diagnostics) wrbuf_printf(wr, "ERROR %s", srw_res->diagnostics[0].uri); @@ -1206,7 +1228,8 @@ static void srw_bend_search(association *assoc, srw_res->resultSetId : "-"), (srw_req->startRecord ? *srw_req->startRecord : 1), srw_res->num_records); - yaz_log(log_request, "%s %s: %s", wrbuf_cstr(wr), querytype, querystr); + yaz_log(log_request, "%s %s: %s", wrbuf_cstr(wr), srw_req->queryType, + srw_req->query); wrbuf_destroy(wr); } } @@ -1248,14 +1271,17 @@ static char *srw_bend_explain_default(bend_explain_rr *rr) } 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; @@ -1296,6 +1322,7 @@ static void srw_bend_explain(association *assoc, } static void srw_bend_scan(association *assoc, + Z_HTTP_Header *headers, Z_SRW_PDU *sr, Z_SRW_PDU *res, int *http_code) @@ -1305,7 +1332,8 @@ static void srw_bend_scan(association *assoc, 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; @@ -1349,20 +1377,20 @@ static void srw_bend_scan(association *assoc, } save_entries = bsrr->entries; /* save it so we can compare later */ - if (srw_req->query_type == Z_SRW_query_type_pqf && + if (srw_req->queryType && !strcmp(srw_req->queryType, "pqf") && assoc->init->bend_scan) { YAZ_PQF_Parser pqf_parser = yaz_pqf_create(); bsrr->term = yaz_pqf_scan(pqf_parser, assoc->decode, &bsrr->attributeset, - srw_req->scanClause.pqf); + srw_req->scanClause); yaz_pqf_destroy(pqf_parser); bsrr->scanClause = 0; ((int (*)(void *, bend_scan_rr *)) (*assoc->init->bend_scan))(assoc->backend, bsrr); } - else if (srw_req->query_type == Z_SRW_query_type_cql + else if ((!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) && assoc->init->bend_scan && assoc->server && assoc->server->cql_transform) { @@ -1372,7 +1400,7 @@ static void srw_bend_scan(association *assoc, bsrr->term = (Z_AttributesPlusTerm *) odr_malloc(assoc->decode, sizeof(*bsrr->term)); srw_error = cql2pqf_scan(assoc->encode, - srw_req->scanClause.cql, + srw_req->scanClause, assoc->server->cql_transform, bsrr->term); if (srw_error) @@ -1385,12 +1413,12 @@ static void srw_bend_scan(association *assoc, (*assoc->init->bend_scan))(assoc->backend, bsrr); } } - else if (srw_req->query_type == Z_SRW_query_type_cql + else if ((!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) && assoc->init->bend_srw_scan) { bsrr->term = 0; bsrr->attributeset = 0; - bsrr->scanClause = srw_req->scanClause.cql; + bsrr->scanClause = srw_req->scanClause; ((int (*)(void *, bend_scan_rr *)) (*assoc->init->bend_srw_scan))(assoc->backend, bsrr); } @@ -1451,24 +1479,6 @@ static void srw_bend_scan(association *assoc, if (log_request) { WRBUF wr = wrbuf_alloc(); - const char *querytype = 0; - const char *querystr = 0; - - switch(srw_req->query_type) - { - case Z_SRW_query_type_pqf: - querytype = "PQF"; - querystr = srw_req->scanClause.pqf; - break; - case Z_SRW_query_type_cql: - querytype = "CQL"; - querystr = srw_req->scanClause.cql; - break; - default: - querytype = "UNKNOWN"; - querystr = ""; - } - wrbuf_printf(wr, "SRWScan %s ", srw_req->database); if (srw_res->num_diagnostics) @@ -1484,7 +1494,7 @@ static void srw_bend_scan(association *assoc, (srw_req->maximumTerms ? *srw_req->maximumTerms : 1)); /* there is no step size in SRU/W ??? */ - wrbuf_printf(wr, "%s: %s ", querytype, querystr); + wrbuf_printf(wr, "%s: %s ", srw_req->queryType, srw_req->scanClause); yaz_log(log_request, "%s ", wrbuf_cstr(wr) ); wrbuf_destroy(wr); } @@ -1492,6 +1502,7 @@ static void srw_bend_scan(association *assoc, } static void srw_bend_update(association *assoc, + Z_HTTP_Header *headers, Z_SRW_PDU *sr, Z_SRW_updateResponse *srw_res, int *http_code) @@ -1499,8 +1510,10 @@ static void srw_bend_update(association *assoc, 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; @@ -1850,8 +1863,8 @@ static void process_http_request(association *assoc, request *req) 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) { @@ -1860,36 +1873,35 @@ static void process_http_request(association *assoc, request *req) } 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; } @@ -1904,7 +1916,8 @@ 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, 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; } @@ -1943,11 +1956,6 @@ static void process_http_request(association *assoc, request *req) 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 @@ -2202,8 +2210,9 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) 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; @@ -2490,7 +2499,8 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, 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)); @@ -2520,13 +2530,13 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, { 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; @@ -2582,10 +2592,11 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, 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) @@ -2615,7 +2626,7 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int 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( @@ -2698,6 +2709,19 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb) 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) @@ -3112,7 +3136,6 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb) { 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) @@ -3139,12 +3162,10 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb) 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); }