/* This file is part of Metaproxy.
- Copyright (C) 2005-2008 Index Data
+ Copyright (C) 2005-2009 Index Data
Metaproxy is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+// make std::min actually work on Windows
+#define NOMINMAX 1
+
#include "config.hpp"
#include "filter.hpp"
#include "package.hpp"
#include <yaz/srw.h>
#include <yaz/pquery.h>
#include <yaz/oid_db.h>
+#include <yaz/log.h>
#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
#include <iostream>
#include <sstream>
void configure(const xmlNode *xmlnode);
void process(metaproxy_1::Package &package);
private:
- union SRW_query {char * cql; char * xcql; char * pqf;};
- typedef const int& SRW_query_type;
std::map<std::string, const xmlNode *> m_database_explain;
- private:
+ typedef std::map<std::string, int> ActiveUrlMap;
+
+ boost::mutex m_mutex;
+ boost::condition m_cond_url_ready;
+ ActiveUrlMap m_active_urls;
+ private:
+ void sru(metaproxy_1::Package &package, Z_GDU *zgdu_req);
bool z3950_build_query(mp::odr &odr_en, Z_Query *z_query,
- const SRW_query &query,
- SRW_query_type query_type) const;
+ const Z_SRW_searchRetrieveRequest *req
+ ) const;
bool z3950_init_request(mp::Package &package,
mp::odr &odr_en,
std::string zurl,
- Z_SRW_PDU *sru_pdu_res) const;
+ Z_SRW_PDU *sru_pdu_res,
+ const Z_SRW_PDU *sru_pdu_req
+ ) const;
bool z3950_close_request(mp::Package &package) const;
int z3950_to_srw_diag(mp::odr &odr_en,
Z_SRW_searchRetrieveResponse *srw_res,
Z_DefaultDiagFormat *ddf) const;
+
+
};
}
}
}
}
-void yf::SRUtoZ3950::Impl::process(mp::Package &package)
+void yf::SRUtoZ3950::Impl::sru(mp::Package &package, Z_GDU *zgdu_req)
{
- Z_GDU *zgdu_req = package.request().get();
-
- // ignoring all non HTTP_Request packages
- if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request)){
- package.move();
- return;
- }
-
- // only working on HTTP_Request packages now
-
bool ok = true;
mp::odr odr_de(ODR_DECODE);
{
zurl = std::string(arg->value);
}
+ else if (!strcmp(arg->name, "x-max-sockets"))
+ {
+ package.origin().set_max_sockets(atoi(arg->value));
+ }
// filter acts as sink for SRU explain requests
ok = mp_util::check_sru_query_exists(package, odr_en,
sru_pdu_res, sr_req);
- if (ok && z3950_init_request(package, odr_en, zurl, sru_pdu_res))
+ if (ok && z3950_init_request(package, odr_en,
+ zurl, sru_pdu_res, sru_pdu_req))
{
ok = z3950_search_request(package, odr_en,
sru_pdu_res, sr_req, zurl);
YAZ_SRW_UNSUPP_OPERATION, "scan");
// to be used when we do scan
- if (false && z3950_init_request(package, odr_en, zurl, sru_pdu_res))
+ if (false && z3950_init_request(package, odr_en, zurl, sru_pdu_res,
+ sru_pdu_req))
{
z3950_scan_request(package, odr_en, sru_pdu_res, sr_req);
z3950_close_request(package);
}
+void yf::SRUtoZ3950::Impl::process(mp::Package &package)
+{
+ Z_GDU *zgdu_req = package.request().get();
+
+ // ignoring all non HTTP_Request packages
+ if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request)){
+ package.move();
+ return;
+ }
+
+ // only working on HTTP_Request packages now
+
+ // see if HTTP request is already being executed..
+ // we consider only the SRU - GET case..
+ if (zgdu_req->u.HTTP_Request->content_len == 0)
+ {
+ const char *path = zgdu_req->u.HTTP_Request->path;
+ boost::mutex::scoped_lock lock(m_mutex);
+ while (1)
+ {
+ ActiveUrlMap::iterator it = m_active_urls.find(path);
+ if (it == m_active_urls.end())
+ {
+ m_active_urls[path] = 1;
+ break;
+ }
+ yaz_log(YLOG_LOG, "Waiting for %s to complete", path);
+ m_cond_url_ready.wait(lock);
+ }
+ }
+ sru(package, zgdu_req);
+ if (zgdu_req->u.HTTP_Request->content_len == 0)
+ {
+ const char *path = zgdu_req->u.HTTP_Request->path;
+ boost::mutex::scoped_lock lock(m_mutex);
+
+ ActiveUrlMap::iterator it = m_active_urls.find(path);
+
+ m_active_urls.erase(it);
+ m_cond_url_ready.notify_all();
+ }
+}
+
bool
yf::SRUtoZ3950::Impl::z3950_init_request(mp::Package &package,
mp::odr &odr_en,
std::string zurl,
- Z_SRW_PDU *sru_pdu_res) const
+ Z_SRW_PDU *sru_pdu_res,
+ const Z_SRW_PDU *sru_pdu_req) const
{
// prepare Z3950 package
Package z3950_package(package.session(), package.origin());
// set initRequest APDU
Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_initRequest);
Z_InitRequest *init_req = apdu->u.initRequest;
+
//TODO: add user name in apdu
//TODO: add user passwd in apdu
//init_req->idAuthentication = org_init->idAuthentication;
Z_Query *z_query = (Z_Query *) odr_malloc(odr_en, sizeof(Z_Query));
z_searchRequest->query = z_query;
- if (!z3950_build_query(odr_en, z_query,
- (const SRW_query&)sr_req->query,
- sr_req->query_type))
+ if (!z3950_build_query(odr_en, z_query, sr_req))
{
yaz_add_srw_diagnostic(odr_en,
&(sru_pdu_res->u.response->diagnostics),
}
bool yf::SRUtoZ3950::Impl::z3950_build_query(mp::odr &odr_en, Z_Query *z_query,
- const SRW_query &query,
- SRW_query_type query_type) const
+ const Z_SRW_searchRetrieveRequest *req
+ ) const
{
- if (query_type == Z_SRW_query_type_cql)
+ if (req->query_type == Z_SRW_query_type_cql)
{
Z_External *ext = (Z_External *)
odr_malloc(odr_en, sizeof(*ext));
ext->indirect_reference = 0;
ext->descriptor = 0;
ext->which = Z_External_CQL;
- ext->u.cql = const_cast<char *>(query.cql);
+ ext->u.cql = odr_strdup(odr_en, req->query.cql);
z_query->which = Z_Query_type_104;
z_query->u.type_104 = ext;
return true;
}
- if (query_type == Z_SRW_query_type_pqf)
+ if (req->query_type == Z_SRW_query_type_pqf)
{
Z_RPNQuery *RPNquery;
YAZ_PQF_Parser pqf_parser;
pqf_parser = yaz_pqf_create ();
- RPNquery = yaz_pqf_parse (pqf_parser, odr_en, query.pqf);
+ RPNquery = yaz_pqf_parse (pqf_parser, odr_en, req->query.pqf);
if (!RPNquery)
{
std::cout << "TODO: Handeling of bad PQF\n";
/*
* Local variables:
* c-basic-offset: 4
+ * c-file-style: "Stroustrup"
* indent-tabs-mode: nil
- * c-file-style: "stroustrup"
* End:
* vim: shiftwidth=4 tabstop=8 expandtab
*/
+