<?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>
/// 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&
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,
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);
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;
};
}
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;
}
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";
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);
}
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;
}
}
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;
}
// 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 "
std::string default_host;
int max_redirects;
bool x_forwarded_for;
+ bool bind_host;
Rep();
};
}
{
max_redirects = 0;
x_forwarded_for = false;
+ bind_host = false;
}
yf::HTTPClient::HTTPClient() : m_p(new Rep)
}
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 =
{
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
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;
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() {
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() =
{
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 "
*/
#include "config.hpp"
+#include <assert.h>
#include <metaproxy/origin.hpp>
#include <yaz/log.h>
#include <iostream>
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;
m_address.append(" ");
m_address.append(tmp);
}
+ else
+ {
+ size_t pos = addr.find(' ');
+ assert (pos != std::string::npos);
+ }
m_origin_id = s;
}
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
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 }?
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 }?