X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_multi.cpp;h=ccdcc4a2ae47d0ff4dd3f86b38b88c7be70fa0b7;hb=a65b7be116265cf331eb823acc9e48738f30e33a;hp=ed7169fe313e8ddffbb5289f9e2abefd5efa180c;hpb=1856d16cee33e8cc3b375c6a6fd2b2bea8c59f74;p=metaproxy-moved-to-github.git diff --git a/src/filter_multi.cpp b/src/filter_multi.cpp index ed7169f..ccdcc4a 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; @@ -395,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++; } @@ -423,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; @@ -501,7 +514,12 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) maximumRecordSize = *b_resp->maximumRecordSize; } else + { + if (!f_resp->userInformationField + && b_resp->userInformationField) + f_resp->userInformationField = b_resp->userInformationField; no_failed++; + } } else no_failed++; @@ -542,7 +560,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; @@ -571,20 +589,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) { @@ -613,31 +635,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)); @@ -1281,9 +1311,12 @@ 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")) {