-/* $Id: filter_z3950_client.cpp,v 1.18 2006-01-09 21:20:15 adam Exp $
- Copyright (c) 2005, Index Data.
+/* $Id: filter_z3950_client.cpp,v 1.27 2006-06-21 14:34:16 adam Exp $
+ Copyright (c) 2005-2006, Index Data.
-%LICENSE%
+ See the LICENSE file for details
*/
#include "config.hpp"
-#include "xmlutil.hpp"
#include "filter.hpp"
#include "package.hpp"
#include "util.hpp"
#include <yaz/otherinfo.h>
#include <yaz/diagbib1.h>
-#include <yaz++/socket-manager.h>
-#include <yaz++/pdu-assoc.h>
-#include <yaz++/z-assoc.h>
+#include <yazpp/socket-manager.h>
+#include <yazpp/pdu-assoc.h>
+#include <yazpp/z-assoc.h>
-namespace yf = yp2::filter;
+namespace mp = metaproxy_1;
+namespace yf = mp::filter;
-namespace yp2 {
+namespace metaproxy_1 {
namespace filter {
class Z3950Client::Assoc : public yazpp_1::Z_Assoc{
friend class Rep;
class Z3950Client::Rep {
public:
+ // number of seconds to wait before we give up request
int m_timeout_sec;
boost::mutex m_mutex;
boost::condition m_cond_session_ready;
- std::map<yp2::Session,Z3950Client::Assoc *> m_clients;
+ std::map<mp::Session,Z3950Client::Assoc *> m_clients;
Z3950Client::Assoc *get_assoc(Package &package);
void send_and_receive(Package &package,
yf::Z3950Client::Assoc *c);
}
}
-using namespace yp2;
+using namespace mp;
yf::Z3950Client::Assoc::Assoc(yazpp_1::SocketManager *socket_manager,
yazpp_1::IPDU_Observable *PDU_Observable,
{
m_waiting = false;
- yp2::odr odr;
+ mp::odr odr;
if (m_package)
{
- m_package->response() = odr.create_close(Z_Close_peerAbort, 0);
+ Z_GDU *gdu = m_package->request().get();
+ Z_APDU *apdu = 0;
+ if (gdu && gdu->which == Z_GDU_Z3950)
+ apdu = gdu->u.z3950;
+
+ m_package->response() = odr.create_close(apdu, Z_Close_peerAbort, 0);
m_package->session().close();
}
}
{
m_waiting = false;
- yp2::odr odr;
+ mp::odr odr;
if (m_package)
{
+ Z_GDU *gdu = m_package->request().get();
+ Z_APDU *apdu = 0;
+ if (gdu && gdu->which == Z_GDU_Z3950)
+ apdu = gdu->u.z3950;
+
if (m_connected)
- m_package->response() = odr.create_close(Z_Close_lackOfActivity, 0);
+ m_package->response() =
+ odr.create_close(apdu, Z_Close_lackOfActivity, 0);
else
- m_package->response() = odr.create_close(Z_Close_peerAbort, 0);
+ m_package->response() =
+ odr.create_close(apdu, Z_Close_peerAbort, 0);
m_package->session().close();
}
// only one thread messes with the clients list at a time
boost::mutex::scoped_lock lock(m_mutex);
- std::map<yp2::Session,yf::Z3950Client::Assoc *>::iterator it;
+ std::map<mp::Session,yf::Z3950Client::Assoc *>::iterator it;
Z_GDU *gdu = package.request().get();
// only deal with Z39.50
while(true)
{
#if 0
+ // double init .. NOT working yet
if (gdu && gdu->which == Z_GDU_Z3950 &&
gdu->u.z3950->which == Z_APDU_initRequest)
{
// check that it is init. If not, close
if (apdu->which != Z_APDU_initRequest)
{
- yp2::odr odr;
+ mp::odr odr;
- package.response() = odr.create_close(Z_Close_protocolError,
+ package.response() = odr.create_close(apdu,
+ Z_Close_protocolError,
"First PDU was not an "
"Initialize Request");
package.session().close();
return 0;
}
- // check virtual host
- const char *vhost =
- yaz_oi_get_string_oidval(&apdu->u.initRequest->otherInfo,
- VAL_PROXY,
- /* categoryValue */ 1, /* delete */ 1);
- if (!vhost)
+ std::list<std::string> vhosts;
+ mp::util::get_vhost_otherinfo(&apdu->u.initRequest->otherInfo,
+ true, vhosts);
+ size_t no_vhosts = vhosts.size();
+ if (no_vhosts == 0)
{
- yp2::odr odr;
+ mp::odr odr;
package.response() = odr.create_initResponse(
+ apdu,
YAZ_BIB1_INIT_NEGOTIATION_OPTION_REQUIRED,
- "Virtual host not given");
+ "z3950_client: No virtal host given");
package.session().close();
return 0;
}
-
+ if (no_vhosts > 1)
+ {
+ mp::odr odr;
+ package.response() = odr.create_initResponse(
+ apdu,
+ YAZ_BIB1_COMBI_OF_SPECIFIED_DATABASES_UNSUPP,
+ "z3950_client: Can not cope with multiple vhosts");
+ package.session().close();
+ return 0;
+ }
+ std::list<std::string>::const_iterator v_it = vhosts.begin();
+ std::list<std::string> dblist;
+ std::string host;
+ mp::util::split_zurl(*v_it, host, dblist);
+
+ if (dblist.size())
+ {
+ ; // z3950_client: Databases in vhost ignored
+ }
+
yazpp_1::SocketManager *sm = new yazpp_1::SocketManager;
yazpp_1::PDU_Assoc *pdu_as = new yazpp_1::PDU_Assoc(sm);
- yf::Z3950Client::Assoc *as = new yf::Z3950Client::Assoc(sm, pdu_as, vhost,
+ yf::Z3950Client::Assoc *as = new yf::Z3950Client::Assoc(sm, pdu_as,
+ host.c_str(),
m_timeout_sec);
m_clients[package.session()] = as;
return as;
if (!c->m_connected)
{
c->client(c->m_host.c_str());
- c->timeout(1);
+ c->timeout(1); // so timeoutNotify gets called once per second
while (!c->m_destroyed && c->m_waiting
&& c->m_socket_manager->processEvent() > 0)
void yf::Z3950Client::Rep::release_assoc(Package &package)
{
boost::mutex::scoped_lock lock(m_mutex);
- std::map<yp2::Session,yf::Z3950Client::Assoc *>::iterator it;
+ std::map<mp::Session,yf::Z3950Client::Assoc *>::iterator it;
it = m_clients.find(package.session());
if (it != m_clients.end())
continue;
if (!strcmp((const char *) ptr->name, "timeout"))
{
- std::string timeout_str = yp2::xml::get_text(ptr);
- int timeout_sec = atoi(timeout_str.c_str());
- if (timeout_sec < 2)
- throw yp2::filter::FilterException("Bad timeout value "
- + timeout_str);
- m_p->m_timeout_sec = timeout_sec;
+ m_p->m_timeout_sec = mp::xml::get_int(ptr->children, 30);
}
else
{
- throw yp2::filter::FilterException("Bad element "
+ throw mp::filter::FilterException("Bad element "
+ std::string((const char *)
ptr->name));
}
}
}
-static yp2::filter::Base* filter_creator()
+static mp::filter::Base* filter_creator()
{
- return new yp2::filter::Z3950Client;
+ return new mp::filter::Z3950Client;
}
extern "C" {
- struct yp2_filter_struct yp2_filter_z3950_client = {
+ struct metaproxy_1_filter_struct metaproxy_1_filter_z3950_client = {
0,
"z3950_client",
filter_creator