Character set nogotiation for z3950_client MP-574
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 14 Oct 2014 10:56:24 +0000 (12:56 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 21 Oct 2014 07:02:47 +0000 (09:02 +0200)
etc/config1.xml
src/filter_z3950_client.cpp
xml/schema/filter_z3950_client.rnc

index 11a9fec..1ad1be8 100644 (file)
@@ -15,6 +15,7 @@
      <default_target>localhost:9999</default_target>
      <force_close>true</force_close>
      <client_ip>true</client_ip>
+     <charset>utf-8</charset>
     </filter>
   </filters>
   <routes>
index 343e33d..eef55ad 100644 (file)
@@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include <yaz/otherinfo.h>
 #include <yaz/diagbib1.h>
 #include <yaz/oid_db.h>
+#include <yaz/charneg.h>
 
 #include <yazpp/socket-manager.h>
 #include <yazpp/pdu-assoc.h>
@@ -85,6 +86,7 @@ namespace metaproxy_1 {
             int m_max_sockets;
             bool m_force_close;
             bool m_client_ip;
+            std::string m_charset;
             std::string m_default_target;
             std::string m_force_target;
             boost::mutex m_mutex;
@@ -464,6 +466,35 @@ yf::Z3950Client::Assoc *yf::Z3950Client::Rep::get_assoc(Package &package)
     return as;
 }
 
+static void set_charset_proposal(ODR odr, Z_InitRequest *req, const char *charset)
+{
+    Z_OtherInformation **p = &req->otherInfo;
+    Z_OtherInformationUnit *oi;
+
+    if (*p)
+    {
+        int i;
+        for (i = 0; i < (*p)->num_elements; i++)
+        {
+            Z_External *ext = (*p)->list[i]->information.externallyDefinedInfo;
+            if ((*p)->list[i]->which == Z_OtherInfo_externallyDefinedInfo
+                && ext &&
+                ext->which == Z_External_charSetandLanguageNegotiation)
+                return;
+        }
+    }
+    if ((oi = yaz_oi_update(p, odr, 0, 0, 0)))
+    {
+        ODR_MASK_SET(req->options, Z_Options_negotiationModel);
+        oi->which = Z_OtherInfo_externallyDefinedInfo;
+        oi->information.externallyDefinedInfo =
+            yaz_set_proposal_charneg_list(odr, ",",
+                                          charset,
+                                          0 /* lang */,
+                                          1 /* records included */);
+    }
+}
+
 void yf::Z3950Client::Rep::send_and_receive(Package &package,
                                             yf::Z3950Client::Assoc *c)
 {
@@ -536,6 +567,9 @@ void yf::Z3950Client::Rep::send_and_receive(Package &package,
                                   1, pcomb.c_str());
         }
     }
+    if (apdu->which == Z_APDU_initRequest && m_charset.length() > 0)
+        set_charset_proposal(odr, apdu->u.initRequest, m_charset.c_str());
+
     // prepare response
     c->m_time_elapsed = 0;
     c->m_waiting = true;
@@ -626,6 +660,10 @@ void yf::Z3950Client::configure(const xmlNode *ptr, bool test_only,
         {
             m_p->m_client_ip = mp::xml::get_bool(ptr, 0);
         }
+        else if (!strcmp((const char *) ptr->name, "charset"))
+        {
+            m_p->m_charset = mp::xml::get_text(ptr);
+        }
         else
         {
             throw mp::filter::FilterException("Bad element "
index 04c6b64..929e0f0 100644 (file)
@@ -10,5 +10,6 @@ filter_z3950_client =
   element mp:default_target { xsd:string }?,
   element mp:force_target { xsd:string }?,
   element mp:force_close { xsd:boolean }?,
-  element mp:client_ip { xsd:boolean }?
+  element mp:client_ip { xsd:boolean }?,
+  element mp:charset { xsd:string }?