Working outgoing IP for {http,z3950}_client MP-575
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 24 Oct 2014 19:44:53 +0000 (21:44 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 27 Oct 2014 13:33:41 +0000 (14:33 +0100)
etc/config1.xml
include/metaproxy/origin.hpp
src/filter_frontend_net.cpp
src/filter_http_client.cpp
src/filter_z3950_client.cpp
src/origin.cpp
xml/schema/filter_http_client.rnc
xml/schema/filter_z3950_client.rnc

index 1ad1be8..b556b72 100644 (file)
@@ -1,26 +1,14 @@
 <?xml version="1.0"?>
 <metaproxy xmlns="http://indexdata.com/metaproxy" version="1.0">
-  <!-- Z39.50 proxy which relays to target specified in Init otherinfo
-  (VAL_RPOXY). If no target is given, it relays to target
-  z3950.indexdata.dk -->
   <start route="start"/>
-  <filters>
-    <filter id="frontend" type="frontend_net">
-      <threads>10</threads>
-      <port>@:9000</port>
-      <message>FN</message>
-    </filter>
-    <filter id="backend" type="z3950_client">
-     <timeout>30</timeout>
-     <default_target>localhost:9999</default_target>
-     <force_close>true</force_close>
-     <client_ip>true</client_ip>
-     <charset>utf-8</charset>
-    </filter>
-  </filters>
   <routes>
     <route id="start">
-      <filter refid="frontend"/>
+      <filter type="frontend_net">
+       <threads>10</threads>
+       <port>127.0.0.2:9000</port>
+       <port>127.0.0.1:9000</port>
+       <message>FN</message>
+      </filter>
       <filter type="cql_rpn">
          <conversion file="cql2pqf.txt" reverse="true"/>
       </filter>
       <filter type="present_chunk">
         <chunk>2</chunk>
       </filter>
-      <filter refid="backend"/>
+      <filter type="z3950_client">
+       <timeout>30</timeout>
+       <default_target>127.0.0.1:9999</default_target>
+       <force_close>true</force_close>
+       <client_ip>true</client_ip>
+       <charset>utf-8</charset>
+       <bind_host>true</bind_host>
+      </filter>
+      <filter type="http_client">
+       <default-host>http://127.0.0.1:9999</default-host>
+        <x-forwarded-for>true</x-forwarded-for>
+       <bind_host>true</bind_host>
+      </filter>
       <filter type="bounce"/>
     </route>
   </routes>
index d129e71..658872a 100644 (file)
@@ -48,6 +48,9 @@ namespace metaproxy_1 {
         /// get tcpip address
         std::string get_address();
 
+        /// get tcpip address
+        std::string get_bind_address();
+
         void set_custom_session(const std::string &s);
     private:
         friend std::ostream&
index 5f1f8ab..7ef28c8 100644 (file)
@@ -90,10 +90,10 @@ namespace metaproxy_1 {
             ZAssocChild(yazpp_1::IPDU_Observable *the_PDU_Observable,
                         mp::ThreadPoolSocketObserver *m_thread_pool_observer,
                         const mp::Package *package,
-                        std::string route,
+                        Port *port,
                         Rep *rep);
             int m_no_requests;
-            std::string m_route;
+            Port *m_port;
         private:
             yazpp_1::IPDU_Observer* sessionNotify(
                 yazpp_1::IPDU_Observable *the_PDU_Observable,
@@ -130,7 +130,7 @@ namespace metaproxy_1 {
         public:
             ~ZAssocServer();
             ZAssocServer(yazpp_1::IPDU_Observable *PDU_Observable,
-                         std::string route,
+                         FrontendNet::Port *port,
                          Rep *rep);
             void set_package(const mp::Package *package);
             void set_thread_pool(ThreadPoolSocketObserver *observer);
@@ -147,7 +147,7 @@ namespace metaproxy_1 {
             mp::ThreadPoolSocketObserver *m_thread_pool_observer;
             const mp::Package *m_package;
             yazpp_1::LimitConnect limit_connect;
-            std::string m_route;
+            Port *m_port;
             Rep *m_p;
         };
     }
@@ -259,7 +259,7 @@ void yf::FrontendNet::ThreadPoolPackage::result(const char *t_info)
 
 mp::IThreadPoolMsg *yf::FrontendNet::ThreadPoolPackage::handle()
 {
-    m_package->move(m_assoc_child->m_route);
+    m_package->move(m_assoc_child->m_port->route);
     return this;
 }
 
@@ -267,14 +267,14 @@ yf::FrontendNet::ZAssocChild::ZAssocChild(
     yazpp_1::IPDU_Observable *PDU_Observable,
     mp::ThreadPoolSocketObserver *my_thread_pool,
     const mp::Package *package,
-    std::string route, Rep *rep)
+    Port *port, Rep *rep)
     :  Z_Assoc(PDU_Observable), m_p(rep)
 {
     m_thread_pool_observer = my_thread_pool;
     m_no_requests = 0;
     m_delete_flag = false;
     m_package = package;
-    m_route = route;
+    m_port = port;
     const char *peername = PDU_Observable->getpeername();
     if (!peername)
         peername = "unknown";
@@ -284,7 +284,11 @@ yf::FrontendNet::ZAssocChild::ZAssocChild(
         if (cp)
             peername = cp + 1;
     }
-    m_origin.set_tcpip_address(std::string(peername), m_session.id());
+    std::string addr;
+    addr.append(peername);
+    addr.append(" ");
+    addr.append(port->port);
+    m_origin.set_tcpip_address(addr, m_session.id());
     timeout(m_p->m_session_timeout);
 }
 
@@ -437,10 +441,10 @@ void yf::FrontendNet::ZAssocChild::connectNotify()
 
 yf::FrontendNet::ZAssocServer::ZAssocServer(
     yazpp_1::IPDU_Observable *PDU_Observable,
-    std::string route,
+    Port *port,
     Rep *rep)
     :
-    Z_Assoc(PDU_Observable), m_route(route), m_p(rep)
+    Z_Assoc(PDU_Observable), m_port(port), m_p(rep)
 {
     m_package = 0;
 }
@@ -472,7 +476,7 @@ yazpp_1::IPDU_Observer *yf::FrontendNet::ZAssocServer::sessionNotify(
     }
     ZAssocChild *my = new ZAssocChild(the_PDU_Observable,
                                       m_thread_pool_observer,
-                                      m_package, m_route, m_p);
+                                      m_package, m_port, m_p);
     return my;
 }
 
@@ -752,7 +756,7 @@ void yf::FrontendNet::set_ports(std::vector<Port> &ports)
         // create ZAssoc with PDU Assoc
         m_p->pdu[i] = as;
         m_p->az[i] = new yf::FrontendNet::ZAssocServer(
-            as, m_p->m_ports[i].route, m_p.get());
+            as, &m_p->m_ports[i], m_p.get());
         if (m_p->az[i]->server(m_p->m_ports[i].port.c_str()))
         {
             throw yf::FilterException("Unable to bind to address "
index 9e9512a..b8c2015 100644 (file)
@@ -52,6 +52,7 @@ namespace metaproxy_1 {
             std::string default_host;
             int max_redirects;
             bool x_forwarded_for;
+            bool bind_host;
             Rep();
         };
     }
@@ -61,6 +62,7 @@ yf::HTTPClient::Rep::Rep()
 {
     max_redirects = 0;
     x_forwarded_for = false;
+    bind_host = false;
 }
 
 yf::HTTPClient::HTTPClient() : m_p(new Rep)
@@ -114,6 +116,14 @@ void yf::HTTPClient::Rep::proxy(mp::Package &package)
         }
         else
             uri = hreq->path;
+
+
+        if (bind_host)
+        {
+            std::string host = package.origin().get_bind_address();
+            uri.append(" ");
+            uri.append(host);
+        }
         Z_HTTP_Response *http_response = 0;
         if (uri.length())
             http_response =
@@ -178,6 +188,10 @@ void mp::filter::HTTPClient::configure(const xmlNode * ptr, bool test_only,
         {
             m_p->x_forwarded_for = mp::xml::get_bool(ptr, 0);
         }
+        else if (!strcmp((const char *) ptr->name, "bind_host"))
+        {
+            m_p->bind_host = mp::xml::get_bool(ptr, 0);
+        }
         else
         {
             throw mp::filter::FilterException
index eef55ad..dd16ffe 100644 (file)
@@ -86,6 +86,7 @@ namespace metaproxy_1 {
             int m_max_sockets;
             bool m_force_close;
             bool m_client_ip;
+            bool m_bind_host;
             std::string m_charset;
             std::string m_default_target;
             std::string m_force_target;
@@ -301,6 +302,7 @@ yf::Z3950Client::Z3950Client() :  m_p(new yf::Z3950Client::Rep)
     m_p->m_max_sockets = 0;
     m_p->m_force_close = false;
     m_p->m_client_ip = false;
+    m_p->m_bind_host = false;
 }
 
 yf::Z3950Client::~Z3950Client() {
@@ -527,7 +529,18 @@ void yf::Z3950Client::Rep::send_and_receive(Package &package,
     c->m_waiting = true;
     if (!c->m_connected)
     {
-        if (c->client(c->m_host.c_str()))
+        std::string host(c->m_host);
+
+        if (m_bind_host)
+        {
+            std::string bind_host = package.origin().get_bind_address();
+            if (bind_host.length())
+            {
+                host.append(" ");
+                host.append(bind_host);
+            }
+        }
+        if (c->client(host.c_str()))
         {
             mp::odr odr;
             package.response() =
@@ -664,6 +677,10 @@ void yf::Z3950Client::configure(const xmlNode *ptr, bool test_only,
         {
             m_p->m_charset = mp::xml::get_text(ptr);
         }
+        else if (!strcmp((const char *) ptr->name, "bind_host"))
+        {
+            m_p->m_bind_host = mp::xml::get_bool(ptr, 0);
+        }
         else
         {
             throw mp::filter::FilterException("Bad element "
index e4f9415..b6acea6 100644 (file)
@@ -17,6 +17,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
 #include "config.hpp"
+#include <assert.h>
 #include <metaproxy/origin.hpp>
 #include <yaz/log.h>
 #include <iostream>
@@ -39,7 +40,7 @@ int mp::Origin::get_max_sockets()
 
 void mp::Origin::set_tcpip_address(std::string addr, unsigned long s)
 {
-    // assume first call is immediate reverse IP: cs_addrstr(COMSTACK)
+    // assume first call is immediate reverse IP: + bind IP
     // 2nd call might be X-Forwarded .. we use that for logging
     std::string tmp = m_address;
     m_address = addr;
@@ -48,6 +49,11 @@ void mp::Origin::set_tcpip_address(std::string addr, unsigned long s)
         m_address.append(" ");
         m_address.append(tmp);
     }
+    else
+    {
+        size_t pos = addr.find(' ');
+        assert (pos != std::string::npos);
+    }
     m_origin_id = s;
 }
 
@@ -69,14 +75,33 @@ std::string mp::Origin::get_forward_address() const
 
 std::string mp::Origin::get_address()
 {
+    // return 2nd last component of address (last is listening IP)
+    size_t pos2 = m_address.rfind(' ');
+    if (pos2 != std::string::npos && pos2 > 0)
+    {
+        size_t pos1 = m_address.rfind(' ', pos2 - 1);
+        if (pos1 != std::string::npos)
+            return m_address.substr(pos1 + 1, pos2 - pos1 - 1);
+        else
+            return m_address.substr(0, pos2);
+    }
+    else
+        return m_address;
+}
+
+std::string mp::Origin::get_bind_address()
+{
     // return last component of address
-    size_t pos = m_address.rfind(' ');
-    if (pos != std::string::npos)
-        return m_address.substr(pos + 1);
+    size_t pos2 = m_address.rfind(' ');
+    if (pos2 != std::string::npos && pos2 > 0)
+    {
+        return m_address.substr(pos2 + 1);
+    }
     else
         return m_address;
 }
 
+
 std::ostream& std::operator<<(std::ostream& os, const mp::Origin& o)
 {
     // print first component of address
index 7eb9e46..6e9ff2f 100644 (file)
@@ -9,5 +9,6 @@ filter_http_client =
   element mp:default-host { xsd:string }?,
   element mp:max-redirects { xsd:integer }?,
   element mp:proxy { xsd:string }?,
-  element mp:x-forwarded-for { xsd:boolean }?
+  element mp:x-forwarded-for { xsd:boolean }?,
+  element mp:bind_host { xsd:boolean }?
 
index 929e0f0..fa8ae46 100644 (file)
@@ -11,5 +11,6 @@ filter_z3950_client =
   element mp:force_target { xsd:string }?,
   element mp:force_close { xsd:boolean }?,
   element mp:client_ip { xsd:boolean }?,
-  element mp:charset { xsd:string }?
+  element mp:charset { xsd:string }?,
+  element mp:bind_host { xsd:boolean }?