From 627806c9d1a499273ecea94fbc3e01f4cfc0de8a Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 17 Jan 2006 13:34:51 +0000 Subject: [PATCH] Added yp2::util split_zurl and get_vhost_otherinfo. For virt_db close the connection, if backend does it.. rather than sending a search/scan response for a dead session. --- src/filter_multi.cpp | 19 ++-------- src/filter_virt_db.cpp | 68 +++++++++++++-------------------- src/filter_z3950_client.cpp | 39 ++++++++++++++----- src/util.cpp | 88 +++++++++++++++++++++++++++++-------------- src/util.hpp | 9 ++++- 5 files changed, 128 insertions(+), 95 deletions(-) diff --git a/src/filter_multi.cpp b/src/filter_multi.cpp index 468ccdf..778a527 100644 --- a/src/filter_multi.cpp +++ b/src/filter_multi.cpp @@ -1,4 +1,4 @@ -/* $Id: filter_multi.cpp,v 1.3 2006-01-16 15:51:56 adam Exp $ +/* $Id: filter_multi.cpp,v 1.4 2006-01-17 13:34:51 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -286,20 +286,9 @@ void yf::Multi::Frontend::init(Package &package, Z_GDU *gdu) std::list targets; - int no_targets = 0; - while (true) - { - const char *vhost_cstr = - yaz_oi_get_string_oidval(&req->otherInfo, VAL_PROXY, no_targets+1, - 0); - if (!vhost_cstr) - break; - no_targets++; - if (no_targets > 1000) - return; - targets.push_back(vhost_cstr); - } - if (no_targets < 2) + yp2::util::get_vhost_otherinfo(&req->otherInfo, false, targets); + + if (targets.size() < 1) { package.move(); return; diff --git a/src/filter_virt_db.cpp b/src/filter_virt_db.cpp index b203a98..d861701 100644 --- a/src/filter_virt_db.cpp +++ b/src/filter_virt_db.cpp @@ -1,4 +1,4 @@ -/* $Id: filter_virt_db.cpp,v 1.28 2006-01-16 17:03:09 adam Exp $ +/* $Id: filter_virt_db.cpp,v 1.29 2006-01-17 13:34:51 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -44,9 +44,6 @@ namespace yp2 { }; struct Virt_db::Backend { yp2::Session m_backend_session; -#if 0 - std::string m_backend_database; -#endif std::list m_frontend_databases; std::list m_targets; std::string m_route; @@ -143,14 +140,7 @@ yf::Virt_db::BackendPtr yf::Virt_db::Frontend::create_backend_from_databases( std::map::const_iterator tm_it = targets_dedup.begin(); for (; tm_it != targets_dedup.end(); tm_it++) b->m_targets.push_back(tm_it->first); -#if 0 - const char *sep = strchr(b->m_vhost.c_str(), '/'); - std::string backend_database; - if (sep) - b->m_backend_database = std::string(sep+1); - else - b->m_backend_database = database; -#endif + return b; } @@ -172,7 +162,7 @@ yf::Virt_db::BackendPtr yf::Virt_db::Frontend::init_backend( yp2::odr odr; Z_APDU *init_apdu = zget_APDU(odr, Z_APDU_initRequest); - + std::list::const_iterator t_it = b->m_targets.begin(); int cat = 1; for (; t_it != b->m_targets.end(); t_it++, cat++) @@ -180,6 +170,7 @@ yf::Virt_db::BackendPtr yf::Virt_db::Frontend::init_backend( yaz_oi_set_string_oidval(&init_apdu->u.initRequest->otherInfo, odr, VAL_PROXY, cat, t_it->c_str()); } + Z_InitRequest *req = init_apdu->u.initRequest; ODR_MASK_SET(req->options, Z_Options_search); @@ -320,10 +311,14 @@ void yf::Virt_db::Frontend::search(Package &package, Z_APDU *apdu_req) req->resultSetName = odr_strdup(odr, backend_setname.c_str()); } -#if 0 - const char *backend_database = b->m_backend_database.c_str(); - req->databaseNames[0] = odr_strdup(odr, backend_database); -#endif + // pick first targets spec and move the databases from it .. + std::list::const_iterator t_it = b->m_targets.begin(); + if (t_it != b->m_targets.end()) + { + if (!yp2::util::set_databases_from_zurl(odr, *t_it, + &req->num_databaseNames, + &req->databaseNames)); + } *req->replaceIndicator = 1; @@ -333,10 +328,8 @@ void yf::Virt_db::Frontend::search(Package &package, Z_APDU *apdu_req) if (search_package.session().is_closed()) { - Z_APDU *apdu = - odr.create_searchResponse( - apdu_req, YAZ_BIB1_DATABASE_UNAVAILABLE, 0); - package.response() = apdu; + package.response() = search_package.response(); + package.session().close(); return; } package.response() = search_package.response(); @@ -479,13 +472,9 @@ void yf::Virt_db::Frontend::present(Package &package, Z_APDU *apdu_req) if (present_package.session().is_closed()) { - Z_APDU *apdu = - odr.create_presentResponse( - apdu_req, - YAZ_BIB1_RESULT_SET_NO_LONGER_EXISTS_UNILATERALLY_DELETED_BY_, - resultSetId.c_str()); - package.response() = apdu; - m_sets.erase(resultSetId); + package.response() = present_package.response(); + package.session().close(); + return; } else { @@ -538,21 +527,22 @@ void yf::Virt_db::Frontend::scan(Package &package, Z_APDU *apdu_req) scan_package.copy_filter(package); -#if 0 - const char *backend_database = b->m_backend_database.c_str(); - req->databaseNames[0] = odr_strdup(odr, backend_database); -#endif - + // pick first targets spec and move the databases from it .. + std::list::const_iterator t_it = b->m_targets.begin(); + if (t_it != b->m_targets.end()) + { + if (!yp2::util::set_databases_from_zurl(odr, *t_it, + &req->num_databaseNames, + &req->databaseNames)); + } scan_package.request() = yazpp_1::GDU(apdu_req); scan_package.move(b->m_route); if (scan_package.session().is_closed()) { - Z_APDU *apdu = - odr.create_scanResponse( - apdu_req, YAZ_BIB1_DATABASE_UNAVAILABLE, 0); - package.response() = apdu; + package.response() = scan_package.response(); + package.session().close(); return; } package.response() = scan_package.response(); @@ -698,10 +688,6 @@ void yp2::filter::Virt_db::configure(const xmlNode * ptr) } std::string route = yp2::xml::get_route(ptr); add_map_db2targets(database, targets, route); -#if 0 - std::cout << "Add " << database << "->" << target - << "," << route << "\n"; -#endif } else { diff --git a/src/filter_z3950_client.cpp b/src/filter_z3950_client.cpp index 9975aa6..594a66b 100644 --- a/src/filter_z3950_client.cpp +++ b/src/filter_z3950_client.cpp @@ -1,4 +1,4 @@ -/* $Id: filter_z3950_client.cpp,v 1.20 2006-01-13 15:09:35 adam Exp $ +/* $Id: filter_z3950_client.cpp,v 1.21 2006-01-17 13:34:51 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -223,26 +223,45 @@ yf::Z3950Client::Assoc *yf::Z3950Client::Rep::get_assoc(Package &package) package.session().close(); return 0; } - // check virtual host - const char *vhost = - yaz_oi_get_string_oidval(&apdu->u.initRequest->otherInfo, - VAL_PROXY, - /* categoryValue */ 1, /* delete */ 1); - if (!vhost) + std::list vhosts; + yp2::util::get_vhost_otherinfo(&apdu->u.initRequest->otherInfo, + true, vhosts); + size_t no_vhosts = vhosts.size(); + if (no_vhosts == 0) { yp2::odr odr; package.response() = odr.create_initResponse( apdu, YAZ_BIB1_INIT_NEGOTIATION_OPTION_REQUIRED, - "Virtual host not given"); + "z3950_client: No virtal host given"); package.session().close(); return 0; } - + if (no_vhosts > 1) + { + yp2::odr odr; + package.response() = odr.create_initResponse( + apdu, + YAZ_BIB1_INIT_NEGOTIATION_OPTION_REQUIRED, + "z3950_client: Can not cope with multiple vhosts"); + package.session().close(); + return 0; + } + std::list::const_iterator v_it = vhosts.begin(); + std::list dblist; + std::string host; + yp2::util::split_zurl(*v_it, host, dblist); + + if (dblist.size()) + { + std::cout << "z3950_client: No databases in vhost supported\n"; + } + yazpp_1::SocketManager *sm = new yazpp_1::SocketManager; yazpp_1::PDU_Assoc *pdu_as = new yazpp_1::PDU_Assoc(sm); - yf::Z3950Client::Assoc *as = new yf::Z3950Client::Assoc(sm, pdu_as, vhost, + yf::Z3950Client::Assoc *as = new yf::Z3950Client::Assoc(sm, pdu_as, + host.c_str(), m_timeout_sec); m_clients[package.session()] = as; return as; diff --git a/src/util.cpp b/src/util.cpp index da9eb53..4a533b1 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,4 +1,4 @@ -/* $Id: util.cpp,v 1.5 2006-01-16 15:51:56 adam Exp $ +/* $Id: util.cpp,v 1.6 2006-01-17 13:34:51 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -8,6 +8,7 @@ #include #include +#include #include "util.hpp" @@ -29,42 +30,73 @@ bool yp2::util::pqf(ODR odr, Z_APDU *apdu, const std::string &q) { return true; } - -bool yp2::util::set_databases_from_zurl(ODR odr, std::string zurl, - int *db_num, char ***db_strings) +int yp2::util::get_vhost_otherinfo(Z_OtherInformation **otherInformation, + bool remove_flag, + std::list &vhosts) { - const char *sep = strchr(zurl.c_str(), '/'); - if (!sep) - return false; - - int num = 0; - const char *cp1 = sep+1; - while(1) + int cat; + for (cat = 1; ; cat++) { - const char *cp2 = strchr(cp1, '+'); - if (!cp2) + // check virtual host + const char *vhost = + yaz_oi_get_string_oidval(otherInformation, + VAL_PROXY, + cat /* categoryValue */, + remove_flag /* delete flag */); + if (!vhost) break; - cp1 = cp2+1; - num++; + vhosts.push_back(std::string(vhost)); } - *db_num = num+1; - *db_strings = (char **) odr_malloc(odr, sizeof(char*) * (*db_num)); + --cat; + return cat; +} - num = 0; - cp1 = sep+1; - while(1) +void yp2::util::split_zurl(std::string zurl, std::string &host, + std::list &db) +{ + const char *zurl_cstr = zurl.c_str(); + const char *sep = strchr(zurl_cstr, '/'); + + if (sep) { - const char *cp2 = strchr(cp1, '+'); - if (cp2) - (*db_strings)[num] = odr_strdupn(odr, cp1, cp2-cp1-1); - else + host = std::string(zurl_cstr, sep - zurl_cstr); + + const char *cp1 = sep+1; + while(1) { - (*db_strings)[num] = odr_strdup(odr, cp1); - break; + const char *cp2 = strchr(cp1, '+'); + if (cp2) + db.push_back(std::string(cp1, cp2 - cp1)); + else + { + db.push_back(std::string(cp1)); + break; + } + cp1 = cp2+1; } - cp1 = cp2+1; - num++; } + else + { + host = zurl; + } +} + +bool yp2::util::set_databases_from_zurl(ODR odr, std::string zurl, + int *db_num, char ***db_strings) +{ + std::string host; + std::list dblist; + + split_zurl(zurl, host, dblist); + + if (dblist.size() == 0) + return false; + *db_num = dblist.size(); + *db_strings = (char **) odr_malloc(odr, sizeof(char*) * (*db_num)); + + std::list::const_iterator it = dblist.begin(); + for (int i = 0; it != dblist.end(); it++, i++) + (*db_strings)[i] = odr_strdup(odr, it->c_str()); return true; } diff --git a/src/util.hpp b/src/util.hpp index cb3c165..93caa33 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -1,4 +1,4 @@ -/* $Id: util.hpp,v 1.5 2006-01-16 15:51:56 adam Exp $ +/* $Id: util.hpp,v 1.6 2006-01-17 13:34:51 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -9,6 +9,7 @@ #include #include +#include #include @@ -19,6 +20,12 @@ namespace yp2 { Z_APDU *create_APDU(ODR odr, int type, Z_APDU *in_apdu); bool set_databases_from_zurl(ODR odr, std::string zurl, int *db_num, char ***db_strings); + void split_zurl(std::string zurl, std::string &host, + std::list &db); + + int get_vhost_otherinfo(Z_OtherInformation **otherInformation, + bool remove_flag, + std::list &vhosts); }; class odr : public boost::noncopyable { -- 1.7.10.4