session_shared: expire backend class when no instances left
[metaproxy-moved-to-github.git] / src / filter_zoom.cpp
index d3bc5b1..2edddd5 100644 (file)
@@ -60,6 +60,7 @@ namespace metaproxy_1 {
         class Zoom::Searchable : boost::noncopyable {
           public:
             std::string authentication;
+            std::string authenticationMode;
             std::string cfAuth;
             std::string cfProxy;
             std::string cfSubDB;
@@ -508,6 +509,11 @@ yf::Zoom::SearchablePtr yf::Zoom::Impl::parse_torus_record(const xmlNode *ptr)
             s->authentication = mp::xml::get_text(ptr);
         }
         else if (!strcmp((const char *) ptr->name,
+                         "authenticationMode"))
+        {
+            s->authenticationMode = mp::xml::get_text(ptr);
+        }
+        else if (!strcmp((const char *) ptr->name,
                          "cfAuth"))
         {
             s->cfAuth = mp::xml::get_text(ptr);
@@ -1345,8 +1351,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     if (sptr->query_encoding.length())
         b->set_option("rpnCharset", sptr->query_encoding);
 
-    if (sptr->extraArgs.length())
-        b->set_option("extraArgs", sptr->extraArgs);
+    std::string extraArgs = sptr->extraArgs;
 
     b->set_option("timeout", m_p->zoom_timeout.c_str());
 
@@ -1407,19 +1412,60 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     }
     else
     {
-        size_t found = authentication.find('/');
-
-        if (sptr->sru.length() && found != std::string::npos)
-        {
-            b->set_option("user", authentication.substr(0, found));
-            b->set_option("password", authentication.substr(found+1));
-        }
+        if (sptr->sru.length() == 0)
+            b->set_option("user", authentication); /* Z39.50 */
         else
-            b->set_option("user", authentication);
+        {
+            std::string user;
+            std::string password;
+            std::string authtype = sptr->authenticationMode;
+
+            {
+                const char *cstr = authentication.c_str();
+                const char *cp1 = strchr(cstr, '/');
+                if (cp1)
+                {
+                    password.assign(cp1 + 1);
+                    user.assign(cstr, cp1 - cstr);
+                }
+                else
+                    user.assign(cstr);
+            }
 
+            if (authtype.compare("url") == 0)
+            {
+                /* SRU URL encoding of auth stuff */
+                ODR o = odr_createmem(ODR_ENCODE);
+                char *path = 0;
+                const char *names[3];
+                const char *values[3];
+
+                names[0] = "x-username";
+                values[0] = user.c_str();
+                names[1] = "x-password";
+                values[1] = password.c_str();
+                names[2] = 0;
+                values[2] = 0;
+
+                yaz_array_to_uri(&path, o, (char **) names, (char **) values);
+                if (extraArgs.length())
+                    extraArgs.append("&");
+                extraArgs.append(path);
+                odr_destroy(o);
+            }
+            else
+            {
+                b->set_option("user", user);
+                if (password.length())
+                    b->set_option("password", password);
+            }
+        }
         if (proxy.length())
             b->set_option("proxy", proxy);
     }
+    if (extraArgs.length())
+        b->set_option("extraArgs", extraArgs);
+
     std::string url(sptr->target);
     if (sptr->sru.length())
     {
@@ -2295,7 +2341,7 @@ next_proxy:
         if (status)
         {
             error = YAZ_BIB1_MALFORMED_QUERY;
-            const char *addinfo = "can not convert from RPN to CQL/SOLR";
+            const char *addinfo = "can not convert from RPN to CQL/Solr";
             log_diagnostic(package, error, addinfo);
             apdu_res = odr.create_searchResponse(apdu_req, error, addinfo);
             package.response() = apdu_res;