X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fyaz-proxy.cpp;h=33a2e255729e52c1cffb8b008d77afe96eb36b4d;hb=c1106f71355e2e89dd95e8f847b1f871642344db;hp=0ce638a411020a4186c6fe6ec6b3e882aef80bec;hpb=a0df8d2655255428841849ac544ad47bf714f690;p=yazpp-moved-to-github.git diff --git a/src/yaz-proxy.cpp b/src/yaz-proxy.cpp index 0ce638a..33a2e25 100644 --- a/src/yaz-proxy.cpp +++ b/src/yaz-proxy.cpp @@ -2,7 +2,7 @@ * Copyright (c) 1998-2004, Index Data. * See the file LICENSE for details. * - * $Id: yaz-proxy.cpp,v 1.88 2004-01-12 22:35:59 adam Exp $ + * $Id: yaz-proxy.cpp,v 1.93 2004-01-30 00:38:28 adam Exp $ */ #include @@ -108,9 +108,12 @@ Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable, m_marcxml_flag = 0; m_stylesheet_schema = 0; m_s2z_stylesheet = 0; + m_s2z_database = 0; m_schema = 0; m_initRequest_apdu = 0; m_initRequest_mem = 0; + m_initRequest_options = 0; + m_initRequest_version = 0; m_apdu_invalid_session = 0; m_mem_invalid_session = 0; m_s2z_odr_init = 0; @@ -426,7 +429,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie, { if (apdu->which != Z_APDU_initRequest) { - yaz_log (LOG_LOG, "no first INIT!"); + yaz_log (LOG_LOG, "%sno init request as first PDU", m_session_str); return 0; } Z_InitRequest *initRequest = apdu->u.initRequest; @@ -445,7 +448,6 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie, odr_strdup (odr_encode(), m_proxy_authentication); } } - // go through list of clients - and find the lowest/oldest one. Yaz_ProxyClient *c_min = 0; int min_seq = -1; @@ -704,7 +706,11 @@ int Yaz_Proxy::send_http_response(int code) Z_HTTP_Response *hres = gdu->u.HTTP_Response; if (m_http_version) hres->version = odr_strdup(o, m_http_version); - m_http_keepalive = 0; + if (m_http_keepalive) + z_HTTP_header_add(o, &hres->headers, "Connection", "Keep-Alive"); + else + timeout(0); + if (m_log_mask & PROXY_LOG_REQ_CLIENT) { yaz_log (LOG_LOG, "%sSending %s to client", m_session_str, @@ -727,6 +733,8 @@ int Yaz_Proxy::send_srw_response(Z_SRW_PDU *srw_pdu) z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); if (m_http_keepalive) z_HTTP_header_add(o, &hres->headers, "Connection", "Keep-Alive"); + else + timeout(0); static Z_SOAP_Handler soap_handlers[2] = { #if HAVE_XSLT @@ -767,8 +775,7 @@ int Yaz_Proxy::send_to_srw_client_error(int srw_error, const char *add) srw_res->num_diagnostics = 1; srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(o, sizeof(*srw_res->diagnostics)); - srw_res->diagnostics[0].code = odr_intdup(o, srw_error); - srw_res->diagnostics[0].details = add ? odr_strdup(o, add) : 0; + yaz_mk_std_diagnostic(o, srw_res->diagnostics, srw_error, add); return send_srw_response(srw_pdu); } @@ -781,9 +788,9 @@ int Yaz_Proxy::z_to_srw_diag(ODR o, Z_SRW_searchRetrieveResponse *srw_res, srw_res->num_diagnostics = 1; srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(o, sizeof(*srw_res->diagnostics)); - srw_res->diagnostics[0].code = - odr_intdup(o, yaz_diag_bib1_to_srw(*ddf->condition)); - srw_res->diagnostics[0].details = ddf->u.v2Addinfo; + yaz_mk_std_diagnostic(o, srw_res->diagnostics, + yaz_diag_bib1_to_srw(*ddf->condition), + ddf->u.v2Addinfo); return 0; } @@ -849,25 +856,27 @@ int Yaz_Proxy::send_to_srw_client_ok(int hits, Z_Records *records, int start) int Yaz_Proxy::send_srw_explain_response(Z_SRW_diagnostic *diagnostics, int num_diagnostics) { - Z_SRW_PDU *res = yaz_srw_get(odr_encode(), Z_SRW_explain_response); - Z_SRW_explainResponse *er = res->u.explain_response; - Yaz_ProxyConfig *cfg = check_reconfigure(); if (cfg) { int len; char *b = cfg->get_explain(odr_encode(), 0 /* target */, - 0 /* db */, &len); + m_s2z_database, &len); if (b) { + Z_SRW_PDU *res = yaz_srw_get(odr_encode(), Z_SRW_explain_response); + Z_SRW_explainResponse *er = res->u.explain_response; + er->record.recordData_buf = b; er->record.recordData_len = len; er->record.recordPacking = m_s2z_packing; + + er->diagnostics = diagnostics; + er->num_diagnostics = num_diagnostics; + return send_srw_response(res); } } - er->diagnostics = diagnostics; - er->num_diagnostics = num_diagnostics; - return send_srw_response(res); + return send_http_response(404); } int Yaz_Proxy::send_PDU_convert(Z_APDU *apdu, int *len) @@ -899,7 +908,7 @@ int Yaz_Proxy::send_PDU_convert(Z_APDU *apdu, int *len) { send_to_srw_client_ok(0, res->records, 1); } - else if (m_s2z_present_apdu) + else if (m_s2z_present_apdu && m_s2z_hit_count > 0) { // adjust Z_PresentRequest *pr = m_s2z_present_apdu->u.presentRequest; @@ -915,6 +924,7 @@ int Yaz_Proxy::send_PDU_convert(Z_APDU *apdu, int *len) } else { + m_s2z_present_apdu = 0; send_to_srw_client_ok(m_s2z_hit_count, res->records, 1); } } @@ -1002,6 +1012,37 @@ int Yaz_Proxy::send_to_client(Z_APDU *apdu) convert_xsl(p->u.databaseOrSurDiagnostics); } } + else if (apdu->which == Z_APDU_initResponse) + { + if (m_initRequest_options) + { + Z_Options *nopt = + (Odr_bitmask *)odr_malloc(odr_encode(), + sizeof(Odr_bitmask)); + ODR_MASK_ZERO(nopt); + + int i; + for (i = 0; i<24; i++) + if (ODR_MASK_GET(m_initRequest_options, i) && + ODR_MASK_GET(apdu->u.initResponse->options, i)) + ODR_MASK_SET(nopt, i); + apdu->u.initResponse->options = nopt; + } + if (m_initRequest_version) + { + Z_ProtocolVersion *nopt = + (Odr_bitmask *)odr_malloc(odr_encode(), + sizeof(Odr_bitmask)); + ODR_MASK_ZERO(nopt); + + int i; + for (i = 0; i<8; i++) + if (ODR_MASK_GET(m_initRequest_version, i) && + ODR_MASK_GET(apdu->u.initResponse->protocolVersion, i)) + ODR_MASK_SET(nopt, i); + apdu->u.initResponse->protocolVersion = nopt; + } + } int r = send_PDU_convert(apdu, &len); if (r) return r; @@ -1013,18 +1054,6 @@ int Yaz_Proxy::send_to_client(Z_APDU *apdu) m_client = 0; m_parent->pre_init(); } - if (m_http_version) - { - if (!m_http_keepalive) - { -#if 1 - timeout(1); -#else - shutdown(); - return -1; -#endif - } - } return r; } @@ -1532,7 +1561,6 @@ Z_ElementSetNames *Yaz_Proxy::mk_esn_from_schema(ODR o, const char *schema) void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq) { - if (m_s2z_odr_init) { odr_destroy(m_s2z_odr_init); @@ -1588,6 +1616,7 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq) { Z_SRW_searchRetrieveRequest *srw_req = srw_pdu->u.request; + m_s2z_database = odr_strdup(m_s2z_odr_init, srw_req->database); // recordXPath unsupported. if (srw_req->recordXPath) { @@ -1771,6 +1800,8 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq) { Z_SRW_explainRequest *srw_req = srw_pdu->u.explain_request; + m_s2z_database = odr_strdup(m_s2z_odr_init, srw_req->database); + // save stylesheet if (srw_req->stylesheet) m_s2z_stylesheet = @@ -1804,6 +1835,9 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq) } else if (srw_pdu->which == Z_SRW_scan_request) { + 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"); @@ -1819,13 +1853,15 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq) } else { + m_s2z_database = 0; + send_to_srw_client_error(4, 0); } } int len = 0; Z_GDU *p = z_get_HTTP_Response(odr_encode(), 400); + timeout(0); send_GDU(p, &len); - timeout(1); } void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu) @@ -1865,6 +1901,29 @@ void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu) nmem_destroy(m_initRequest_mem); m_initRequest_apdu = apdu; m_initRequest_mem = odr_extract_mem(odr_decode()); + + // save init options for the response.. + m_initRequest_options = apdu->u.initRequest->options; + + apdu->u.initRequest->options = + (Odr_bitmask *)nmem_malloc(m_initRequest_mem, + sizeof(Odr_bitmask)); + ODR_MASK_ZERO(apdu->u.initRequest->options); + int i; + for (i = 0; i<= 24; i++) + ODR_MASK_SET(apdu->u.initRequest->options, i); + ODR_MASK_CLEAR(apdu->u.initRequest->options, + Z_Options_negotiationModel); + + // make new version + m_initRequest_version = apdu->u.initRequest->protocolVersion; + apdu->u.initRequest->protocolVersion = + (Odr_bitmask *)nmem_malloc(m_initRequest_mem, + sizeof(Odr_bitmask)); + ODR_MASK_ZERO(apdu->u.initRequest->protocolVersion); + + for (i = 0; i<= 8; i++) + ODR_MASK_SET(apdu->u.initRequest->protocolVersion, i); } if (m_client->m_init_flag) { @@ -1877,6 +1936,10 @@ void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu) m_client->m_cookie); apdu2->u.initResponse->referenceId = apdu->u.initRequest->referenceId; + apdu2->u.initResponse->options = m_client->m_initResponse_options; + apdu2->u.initResponse->protocolVersion = + m_client->m_initResponse_version; + send_to_client(apdu2); return; } @@ -2042,19 +2105,14 @@ void Yaz_ProxyClient::pre_init_client() Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest); Z_InitRequest *req = apdu->u.initRequest; - ODR_MASK_SET(req->options, Z_Options_search); - ODR_MASK_SET(req->options, Z_Options_present); - ODR_MASK_SET(req->options, Z_Options_namedResultSets); - ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl); - ODR_MASK_SET(req->options, Z_Options_scan); - ODR_MASK_SET(req->options, Z_Options_sort); - ODR_MASK_SET(req->options, Z_Options_extendedServices); - ODR_MASK_SET(req->options, Z_Options_delSet); - - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1); - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2); - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3); - + int i; + for (i = 0; i<= 24; i++) + ODR_MASK_SET(req->options, i); + ODR_MASK_CLEAR(apdu->u.initRequest->options, + Z_Options_negotiationModel); + for (i = 0; i<= 10; i++) + ODR_MASK_SET(req->protocolVersion, i); + if (send_to_target(apdu) < 0) { delete this; @@ -2183,6 +2241,12 @@ void Yaz_Proxy::timeoutNotify() } } +void Yaz_Proxy::markInvalid() +{ + m_client = 0; + m_invalid_session = 1; +} + void Yaz_ProxyClient::timeoutNotify() { if (m_server) @@ -2192,6 +2256,14 @@ void Yaz_ProxyClient::timeoutNotify() get_hostname()); m_waiting = 1; m_root->pre_init(); + if (m_server && m_init_flag) + { + // target timed out in a session that was properly initialized + // server object stay alive but we mark it as invalid so it + // gets initialized again + m_server->markInvalid(); + m_server = 0; + } shutdown(); } @@ -2211,6 +2283,8 @@ Yaz_ProxyClient::Yaz_ProxyClient(IYaz_PDU_Observable *the_PDU_Observable, m_waiting = 0; m_init_odr = odr_createmem (ODR_DECODE); m_initResponse = 0; + m_initResponse_options = 0; + m_initResponse_version = 0; m_resultSetStartPoint = 0; m_bytes_sent = m_bytes_recv = 0; m_pdu_recv = 0; @@ -2275,6 +2349,8 @@ void Yaz_ProxyClient::recv_Z_PDU(Z_APDU *apdu, int len) odr_reset (m_init_odr); nmem_transfer (m_init_odr->mem, nmem); m_initResponse = apdu; + m_initResponse_options = apdu->u.initResponse->options; + m_initResponse_version = apdu->u.initResponse->protocolVersion; Z_InitResponse *ir = apdu->u.initResponse; char *im0 = ir->implementationName;