Character set nogotiation for z3950_client MP-574
[metaproxy-moved-to-github.git] / src / filter_zoom.cpp
index a29f243..f2d7127 100644 (file)
@@ -80,6 +80,7 @@ namespace metaproxy_1 {
             std::string sortStrategy;
             std::string extraArgs;
             std::string rpn2cql_fname;
+            std::string retry_on_failure;
             bool use_turbomarc;
             bool piggyback;
             CCL_bibset ccl_bibset;
@@ -103,6 +104,7 @@ namespace metaproxy_1 {
             xmlDoc *explain_doc;
             std::string m_proxy;
             cql_transform_t cqlt;
+            std::string retry_on_failure;
         public:
             Backend();
             ~Backend();
@@ -219,6 +221,7 @@ namespace metaproxy_1 {
             std::string torus_content_url;
             std::string torus_auth_url;
             std::string default_realm;
+            std::string torus_auth_hostname;
             std::map<std::string,std::string> fieldmap;
             std::string xsldir;
             std::string file_path;
@@ -488,6 +491,7 @@ yf::Zoom::Searchable::Searchable(CCL_bibset base)
     piggyback = true;
     use_turbomarc = true;
     sortStrategy = "embed";
+    retry_on_failure = "1"; // existing default (should have been false)
     ccl_bibset = ccl_qual_dup(base);
 }
 
@@ -699,6 +703,11 @@ yf::Zoom::SearchablePtr yf::Zoom::Impl::parse_torus_record(const xmlNode *ptr)
         }
         else if (!strcmp((const char *) ptr->name, "rpn2cql"))
             s->rpn2cql_fname = mp::xml::get_text(ptr);
+        else if (!strcmp((const char *) ptr->name,
+                          "retryOnFailure"))
+        {
+            s->retry_on_failure = mp::xml::get_text(ptr);
+        }
     }
     return s;
 }
@@ -778,6 +787,8 @@ void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only,
                     torus_auth_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, "auth_hostname"))
+                    torus_auth_hostname = mp::xml::get_text(attr->children);
                 else if (!strcmp((const char *) attr->name, "xsldir"))
                     xsldir = mp::xml::get_text(attr->children);
                 else if (!strcmp((const char *) attr->name, "element_transform"))
@@ -1131,6 +1142,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     const char *param_content_user = 0;
     const char *param_content_password = 0;
     const char *param_nocproxy = 0;
+    const char *param_retry = 0;
     int no_parms = 0;
 
     char **names;
@@ -1166,6 +1178,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
             content_proxy = value;
         else if (!strcmp(name, "nocproxy"))
             param_nocproxy = value;
+        else if (!strcmp(name, "retry"))
+            param_retry = value;
         else if (!strcmp(name, "proxy"))
         {
             char **dstr;
@@ -1257,15 +1271,17 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
         sptr = it->second;
     else if (torus_url.length() > 0)
     {
+        std::string torus_addinfo;
         std::string torus_query = "udb==" + torus_db;
         xmlDoc *doc = mp::get_searchable(package,torus_url, torus_db,
                                          torus_query,
-                                         realm, m_p->proxy);
+                                         realm, m_p->proxy,
+                                         torus_addinfo);
         if (!doc)
         {
             *error = YAZ_BIB1_UNSPECIFIED_ERROR;
-            *addinfo = odr_strdup(odr, "Torus server unavailable or "
-                                  "incorrectly configured");
+            if (torus_addinfo.length())
+                *addinfo = odr_strdup(odr, torus_addinfo.c_str());
             BackendPtr b;
             return b;
         }
@@ -1424,6 +1440,11 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     b->m_frontend_database = database;
     b->enable_cproxy = param_nocproxy ? false : true;
 
+    if (param_retry)
+        b->retry_on_failure = param_retry;
+    else
+        b->retry_on_failure = b->sptr->retry_on_failure;
+
     if (sptr->query_encoding.length())
         b->set_option("rpnCharset", sptr->query_encoding);
 
@@ -1730,8 +1751,19 @@ Z_Records *yf::Zoom::Frontend::get_records(mp::Package &package,
     if (!*error)
     {
         for (i = 0; i < number_to_present; i++)
+        {
             if (!recs[i])
                 break;
+
+            const char *addinfo;
+            int sur_error = ZOOM_record_error(recs[i], 0 /* msg */,
+                                              &addinfo, 0 /* diagset */);
+            if (sur_error ==
+                YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS && addinfo &&
+                !strcmp(addinfo,
+                        "ZOOM C generated. Present phase and no records"))
+                break;
+        }
     }
     if (i > 0)
     {  // only return records if no error and at least one record
@@ -1762,7 +1794,7 @@ Z_Records *yf::Zoom::Frontend::get_records(mp::Package &package,
         npl->num_records = i;
         npl->records = (Z_NamePlusRecord **)
             odr_malloc(odr, i * sizeof(*npl->records));
-        for (i = 0; i < number_to_present; i++)
+        for (i = 0; i < npl->num_records; i++)
         {
             Z_NamePlusRecord *npr = 0;
             const char *addinfo;
@@ -2013,10 +2045,12 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::explain_search(mp::Package &package,
     else if (query->which == Z_Query_type_104 &&
         query->u.type_104->which == Z_External_CQL)
     {
+        std::string torus_addinfo;
         std::string torus_query(query->u.type_104->u.cql);
         xmlDoc *doc = mp::get_searchable(package, torus_url, "",
                                          torus_query,
-                                         realm, m_p->proxy);
+                                         realm, m_p->proxy,
+                                         torus_addinfo);
         if (m_p->explain_xsp)
         {
             xmlDoc *rec_res =  xsltApplyStylesheet(m_p->explain_xsp, doc, 0);
@@ -2027,8 +2061,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::explain_search(mp::Package &package,
         if (!doc)
         {
             *error = YAZ_BIB1_UNSPECIFIED_ERROR;
-            *addinfo = odr_strdup(odr, "Torus server unavailable or "
-                                  "incorrectly configured");
+            if (torus_addinfo.length())
+                *addinfo = odr_strdup(odr, torus_addinfo.c_str());
         }
         else
         {
@@ -2132,7 +2166,8 @@ bool yf::Zoom::Frontend::retry(mp::Package &package,
         error = YAZ_BIB1_PROXY_FAILURE;
         *addinfo = odr_strdup(odr, b->m_proxy.c_str());
     }
-    else if (same_retries == 0 && proxy_retries == 0)
+    else if (b && b->retry_on_failure.compare("0")
+             && same_retries == 0 && proxy_retries == 0)
     {
         log_diagnostic(package, error, *addinfo);
         same_retries++;
@@ -2625,22 +2660,31 @@ void yf::Zoom::Frontend::auth(mp::Package &package, Z_InitRequest *req,
     }
     else
     {
-        torus_query = "ip encloses/net.ipaddress \"";
+        torus_query = "ipRanges encloses/net.ipaddress \"";
         torus_query += escape_cql_term(std::string(ip));
         torus_query += "\"";
+
+        if (m_p->torus_auth_hostname.length())
+        {
+            torus_query += " AND hostName == \"";
+            torus_query += escape_cql_term(m_p->torus_auth_hostname);
+            torus_query += "\"";
+        }
         failure_code = YAZ_BIB1_INIT_AC_BLOCKED_NETWORK_ADDRESS;
     }
 
     std::string dummy_db;
     std::string dummy_realm;
+    std::string torus_addinfo;
     xmlDoc *doc = mp::get_searchable(package, m_p->torus_auth_url, dummy_db,
-                                     torus_query, dummy_realm, m_p->proxy);
+                                     torus_query, dummy_realm, m_p->proxy,
+                                     torus_addinfo);
     if (!doc)
     {
         // something fundamental broken in lookup.
         *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
-        *addinfo = odr_strdup(odr, "zoom: torus server unavailable or "
-                              "incorrectly configured.");
+        if (torus_addinfo.length())
+            *addinfo = odr_strdup(odr, torus_addinfo.c_str());
         return;
     }
     const xmlNode *ptr = xmlDocGetRootElement(doc);