X-Git-Url: http://sru.miketaylor.org.uk/?a=blobdiff_plain;f=src%2Ffilter_zoom.cpp;h=45ead65fa6b9bfa8f0b288ef098568bb10cce21c;hb=8085904b5f89768a01a4ddf5eb74b371b6999166;hp=84fb20c0e2dcba5b4641acc65ef5dcffafdf029d;hpb=6bbc073d4048f6bbff75e165b7539b9adbe22559;p=metaproxy-moved-to-github.git diff --git a/src/filter_zoom.cpp b/src/filter_zoom.cpp index 84fb20c..45ead65 100644 --- a/src/filter_zoom.cpp +++ b/src/filter_zoom.cpp @@ -120,7 +120,8 @@ namespace metaproxy_1 { std::string &database, int *error, char **addinfo, - ODR odr); + ODR odr, + int *proxy_step); bool create_content_session(mp::Package &package, BackendPtr b, @@ -170,7 +171,8 @@ namespace metaproxy_1 { std::map m_clients; boost::mutex m_mutex; boost::condition m_cond_session_ready; - std::string torus_url; + std::string torus_searchable_url; + std::string torus_content_url; std::string default_realm; std::map fieldmap; std::string xsldir; @@ -235,37 +237,30 @@ void yf::Zoom::Backend::get_zoom_error(int *error, char **addinfo, const char *msg = 0; const char *zoom_addinfo = 0; const char *dset = 0; - *error = ZOOM_connection_error_x(m_connection, &msg, &zoom_addinfo, &dset); - if (*error) + int error0 = ZOOM_connection_error_x(m_connection, &msg, + &zoom_addinfo, &dset); + if (error0) { - if (*error >= ZOOM_ERROR_CONNECT) - { - // turn ZOOM diagnostic into a Bib-1 2: with addinfo=zoom err msg - *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR; - *addinfo = (char *) odr_malloc( - odr, 20 + strlen(msg) + - (zoom_addinfo ? strlen(zoom_addinfo) : 0)); - strcpy(*addinfo, msg); - if (zoom_addinfo) - { - strcat(*addinfo, ": "); - strcat(*addinfo, zoom_addinfo); - } - } + if (!dset) + dset = "Unknown"; + + if (!strcmp(dset, "info:srw/diagnostic/1")) + *error = yaz_diag_srw_to_bib1(error0); + else if (!strcmp(dset, "Bib-1")) + *error = error0; else + *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR; + + *addinfo = (char *) odr_malloc( + odr, 30 + strlen(dset) + strlen(msg) + + (zoom_addinfo ? strlen(zoom_addinfo) : 0)); + **addinfo = '\0'; + if (zoom_addinfo && *zoom_addinfo) { - if (dset && !strcmp(dset, "info:srw/diagnostic/1")) - *error = yaz_diag_srw_to_bib1(*error); - *addinfo = (char *) odr_malloc( - odr, 20 + (zoom_addinfo ? strlen(zoom_addinfo) : 0)); - **addinfo = '\0'; - if (zoom_addinfo && *zoom_addinfo) - { - strcpy(*addinfo, zoom_addinfo); - strcat(*addinfo, " "); - } - strcat(*addinfo, "(backend)"); + strcpy(*addinfo, zoom_addinfo); + strcat(*addinfo, " "); } + sprintf(*addinfo + strlen(*addinfo), "(%s %d %s)", dset, error0, msg); } } @@ -579,7 +574,9 @@ void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only, for (attr = ptr->properties; attr; attr = attr->next) { if (!strcmp((const char *) attr->name, "url")) - torus_url = mp::xml::get_text(attr->children); + torus_searchable_url = mp::xml::get_text(attr->children); + else if (!strcmp((const char *) attr->name, "content_url")) + torus_content_url = mp::xml::get_text(attr->children); else if (!strcmp((const char *) attr->name, "realm")) default_realm = mp::xml::get_text(attr->children); else if (!strcmp((const char *) attr->name, "xsldir")) @@ -595,6 +592,10 @@ void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only, "Bad attribute " + std::string((const char *) attr->name)); } + // If content_url is not given, use value of searchable, to + // ensure backwards compatibility + if (!torus_content_url.length()) + torus_content_url = torus_searchable_url; configure_local_records(ptr->children, test_only); } else if (!strcmp((const char *) ptr->name, "cclmap")) @@ -709,7 +710,8 @@ bool yf::Zoom::Frontend::create_content_session(mp::Package &package, yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( mp::Package &package, - std::string &database, int *error, char **addinfo, ODR odr) + std::string &database, int *error, char **addinfo, ODR odr, + int *proxy_step) { std::list::const_iterator map_it; if (m_backend && m_backend->m_frontend_database == database) @@ -729,6 +731,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( std::string authentication; std::string content_authentication; std::string proxy; + std::string content_proxy; std::string realm = m_p->default_realm; const char *param_user = 0; @@ -749,6 +752,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( const char **out_values = (const char **) odr_malloc(odr, (10 + no_parms) * sizeof(*out_values)); + // may be changed if it's a content connection + std::string torus_url = m_p->torus_searchable_url; int i; for (i = 0; i < no_parms; i++) { @@ -764,12 +769,29 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( param_content_user = value; else if (!strcmp(name, "content-password")) param_content_password = value; + else if (!strcmp(name, "content-proxy")) + content_proxy = value; else if (!strcmp(name, "proxy")) - proxy = value; + { + char **dstr; + int dnum = 0; + nmem_strsplit(odr->mem, ",", value, &dstr, &dnum); + if (*proxy_step >= dnum) + *proxy_step = 0; + else + { + proxy = dstr[*proxy_step]; + + (*proxy_step)++; + if (*proxy_step == dnum) + *proxy_step = 0; + } + } else if (!strcmp(name, "cproxysession")) { out_names[no_out_args] = name; out_values[no_out_args++] = value; + torus_url = m_p->torus_content_url; } else if (!strcmp(name, "realm")) realm = value; @@ -806,11 +828,10 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( it = m_p->s_map.find(torus_db); if (it != m_p->s_map.end()) sptr = it->second; - else if (m_p->torus_url.length() > 0) + else if (torus_url.length() > 0) { - xmlDoc *doc = mp::get_searchable(package, - m_p->torus_url, torus_db, realm, - m_p->proxy); + xmlDoc *doc = mp::get_searchable(package,torus_url, torus_db, + realm, m_p->proxy); if (!doc) { *error = YAZ_BIB1_DATABASE_DOES_NOT_EXIST; @@ -996,6 +1017,9 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( if (proxy.length()) b->set_option("proxy", proxy); } + if (proxy.length()) + package.log("zoom", YLOG_LOG, "proxy: %s", proxy.c_str()); + std::string url; if (sptr->sru.length()) { @@ -1023,7 +1047,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( if (*error == 0) create_content_session(package, b, error, addinfo, odr, content_authentication.length() ? - content_authentication : authentication, proxy); + content_authentication : authentication, + content_proxy.length() ? content_proxy : proxy); if (*error == 0) m_backend = b; return b; @@ -1387,11 +1412,22 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package) return; } + int proxy_step = 0; + +next_proxy: + int error = 0; char *addinfo = 0; std::string db(sr->databaseNames[0]); + BackendPtr b = get_backend_from_databases(package, db, &error, - &addinfo, odr); + &addinfo, odr, &proxy_step); + if (error && proxy_step) + { + package.log("zoom", YLOG_WARN, + "create backend failed: trying next proxy"); + goto next_proxy; + } if (error) { log_diagnostic(package, error, addinfo); @@ -1629,6 +1665,14 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package) wrbuf_destroy(pqf_wrbuf); } + if (error && proxy_step) + { + // reset below prevent reuse in get_backend_from_databases + m_backend.reset(); + package.log("zoom", YLOG_WARN, "search failed: trying next proxy"); + goto next_proxy; + } + const char *element_set_name = 0; Odr_int number_to_present = 0; if (!error)