X-Git-Url: http://sru.miketaylor.org.uk/?a=blobdiff_plain;f=src%2Ffilter_multi.cpp;h=e4bea124452b573ac9768ccb0efdb0f618f98990;hb=6bd242f99846e3663a0551c6d18d6dedd7a94a38;hp=cfd0bfb3a7b6b2731bd1af1a61402fcfa61092e7;hpb=15e0f02369c05e0bd4f86b5f1ce38dd10f30a71b;p=metaproxy-moved-to-github.git diff --git a/src/filter_multi.cpp b/src/filter_multi.cpp index cfd0bfb..e4bea12 100644 --- a/src/filter_multi.cpp +++ b/src/filter_multi.cpp @@ -88,6 +88,7 @@ namespace metaproxy_1 { std::string m_backend_database; std::string m_vhost; std::string m_route; + std::string m_auth; void operator() (void); // thread operation }; struct Multi::Frontend { @@ -111,13 +112,16 @@ namespace metaproxy_1 { class Multi::Map { std::string m_target_pattern; std::string m_route; + std::string m_auth; public: - Map(std::string pattern, std::string route) : - m_target_pattern(pattern), m_route(route) {}; - bool match(const std::string target, std::string *ret) const { + Map(std::string pattern, std::string route, std::string auth) : + m_target_pattern(pattern), m_route(route), m_auth(auth) {}; + bool match(const std::string target, std::string *ret, + std::string *auth) const { if (yaz_match_glob(m_target_pattern.c_str(), target.c_str())) { *ret = m_route; + *auth = m_auth; return true; } return false; @@ -136,6 +140,7 @@ namespace metaproxy_1 { boost::condition m_cond_session_ready; std::map m_clients; bool m_hide_unavailable; + bool m_hide_errors; multi_merge_type m_merge_type; }; } @@ -144,6 +149,7 @@ namespace metaproxy_1 { yf::Multi::Rep::Rep() { m_hide_unavailable = false; + m_hide_errors = false; m_merge_type = round_robin; } @@ -393,7 +399,7 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) std::list::const_iterator it = m_p->m_route_patterns.begin(); while (it != m_p->m_route_patterns.end()) { - if (it->match(*t_it, &b->m_route)) + if (it->match(*t_it, &b->m_route, &b->m_auth)) break; it++; } @@ -421,7 +427,16 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) Z_InitRequest *breq = init_apdu->u.initRequest; - breq->idAuthentication = req->idAuthentication; + if (b->m_auth.length()) + { + breq->idAuthentication = + (Z_IdAuthentication *) + odr_malloc(odr, sizeof(*breq->idAuthentication)); + breq->idAuthentication->which = Z_IdAuthentication_open; + breq->idAuthentication->u.open = odr_strdup(odr, b->m_auth.c_str()); + } + else + breq->idAuthentication = req->idAuthentication; *breq->preferredMessageSize = *req->preferredMessageSize; *breq->maximumRecordSize = *req->maximumRecordSize; @@ -540,7 +555,7 @@ void yf::Multi::Frontend::search(mp::Package &package, Z_APDU *apdu_req) // they are altered now - to disable piggyback *req->smallSetUpperBound = 0; *req->largeSetLowerBound = 1; - *req->mediumSetPresentNumber = 1; + *req->mediumSetPresentNumber = 0; int default_num_db = req->num_databaseNames; char **default_db = req->databaseNames; @@ -569,20 +584,24 @@ void yf::Multi::Frontend::search(mp::Package &package, Z_APDU *apdu_req) mp::odr odr; Odr_int result_set_size = 0; Z_DiagRecs *z_diag = 0; + int no_successful = 0; + PackagePtr close_p; + for (bit = m_backend_list.begin(); bit != m_backend_list.end(); bit++) { PackagePtr p = (*bit)->m_package; - if (p->session().is_closed()) // if any backend closes, close frontend - package.session().close(); - + // save closing package for at least one target + if (p->session().is_closed()) + close_p = p; + Z_GDU *gdu = p->response().get(); if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which == Z_APDU_searchResponse) { Z_APDU *b_apdu = gdu->u.z3950; Z_SearchResponse *b_resp = b_apdu->u.searchResponse; - + // see we get any errors (AKA diagnstics) if (b_resp->records) { @@ -611,31 +630,39 @@ void yf::Multi::Frontend::search(mp::Package &package, Z_APDU *apdu_req) b_resp->records->u.nonSurrogateDiagnostic; z_diag->diagRecs[z_diag->num_diagRecs++] = nr; } - if (b_resp->records->which == Z_Records_multipleNSD) + else if (b_resp->records->which == Z_Records_multipleNSD) { // we may set this multiple times (TOO BAD!) z_diag = b_resp->records->u.multipleNonSurDiagnostics; } + else + no_successful++; // probably piggyback } + else + no_successful++; // no records and no diagnostics BackendSet backendSet; backendSet.m_backend = *bit; backendSet.m_count = *b_resp->resultCount; result_set_size += *b_resp->resultCount; resultSet.m_backend_sets.push_back(backendSet); } - else - { - // if any target does not return search response - return that - package.response() = p->response(); - return; - } } Z_APDU *f_apdu = odr.create_searchResponse(apdu_req, 0, 0); Z_SearchResponse *f_resp = f_apdu->u.searchResponse; + yaz_log(YLOG_LOG, "no_successful=%d is_closed=%s hide_errors=%s", + no_successful, + close_p ? "true" : "false", + m_p->m_hide_errors ? "true" : "false"); *f_resp->resultCount = result_set_size; - if (z_diag) + if (close_p && (no_successful == 0 || !m_p->m_hide_errors)) + { + package.session().close(); + package.response() = close_p->response(); + return; + } + if (z_diag && (no_successful == 0 || !m_p->m_hide_errors)) { f_resp->records = (Z_Records *) odr_malloc(odr, sizeof(*f_resp->records)); @@ -1279,14 +1306,21 @@ void mp::filter::Multi::configure(const xmlNode * ptr, bool test_only, continue; if (!strcmp((const char *) ptr->name, "target")) { - std::string route = mp::xml::get_route(ptr); + std::string auth; + std::string route = mp::xml::get_route(ptr, auth); std::string target = mp::xml::get_text(ptr); - m_p->m_route_patterns.push_back(Multi::Map(target, route)); + if (target.length() == 0) + target = route; + m_p->m_route_patterns.push_back(Multi::Map(target, route, auth)); } else if (!strcmp((const char *) ptr->name, "hideunavailable")) { m_p->m_hide_unavailable = true; } + else if (!strcmp((const char *) ptr->name, "hideerrors")) + { + m_p->m_hide_errors = true; + } else if (!strcmp((const char *) ptr->name, "mergetype")) { std::string mergetype = mp::xml::get_text(ptr);