/* This file is part of Metaproxy.
- Copyright (C) 2005-2009 Index Data
+ Copyright (C) 2005-2013 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
#include <time.h>
#include <yaz/log.h>
-#include "package.hpp"
-#include "util.hpp"
+#include <yazpp/timestat.h>
+#include <metaproxy/package.hpp>
+#include <metaproxy/util.hpp>
+#ifdef WIN32
+#include <windows.h>
+#endif
namespace mp = metaproxy_1;
namespace yf = mp::filter;
namespace filter {
class Limit::Ses {
public:
- Yaz_bw bw_stat;
- Yaz_bw pdu_stat;
- Yaz_bw search_stat;
+ yazpp_1::TimeStat bw_stat;
+ yazpp_1::TimeStat pdu_stat;
+ yazpp_1::TimeStat search_stat;
Ses() : bw_stat(60), pdu_stat(60), search_stat(60) {};
};
+
class Limit::Impl {
public:
Impl();
void process(metaproxy_1::Package & package);
void configure(const xmlNode * ptr);
private:
-
boost::mutex m_session_mutex;
std::map<mp::Session,Limit::Ses *> m_sessions;
-
int m_bw_max;
int m_pdu_max;
int m_search_max;
}
// define Pimpl wrapper forwarding to Impl
-
+
yf::Limit::Limit() : m_p(new Impl)
{
}
{ // must have a destructor because of boost::scoped_ptr
}
-void yf::Limit::configure(const xmlNode *xmlnode, bool test_only)
+void yf::Limit::configure(const xmlNode *xmlnode, bool test_only,
+ const char *path)
{
m_p->configure(xmlnode);
}
}
yf::Limit::Impl::~Impl()
-{
+{
}
void yf::Limit::Impl::configure(const xmlNode *ptr)
}
else
{
- throw mp::filter::FilterException("Bad element "
+ throw mp::filter::FilterException("Bad element "
+ std::string((const char *)
ptr->name));
}
void yf::Limit::Impl::process(mp::Package &package)
{
- package.move();
- int reduce = 0;
-
+ int sz = 0;
{
boost::mutex::scoped_lock scoped_lock(m_session_mutex);
yf::Limit::Ses *ses = 0;
- std::map<mp::Session,yf::Limit::Ses *>::iterator it =
+ std::map<mp::Session,yf::Limit::Ses *>::iterator it =
m_sessions.find(package.session());
if (it != m_sessions.end())
ses = it->second;
m_sessions[package.session()] = ses;
}
- int sz = package.request().get_size() + package.response().get_size();
-
- ses->bw_stat.add_bytes(sz);
- ses->pdu_stat.add_bytes(1);
-
+
Z_GDU *gdu = package.request().get();
if (gdu && gdu->which == Z_GDU_Z3950)
{
+ sz += package.request().get_size();
// we're getting a Z39.50 package
Z_APDU *apdu = gdu->u.z3950;
if (apdu->which == Z_APDU_searchRequest)
}
}
}
-
- yaz_log(YLOG_LOG, "sz = %d . total = %d", sz,
- ses->bw_stat.get_total());
-
+ }
+ package.move();
+ int reduce = 0;
+ {
+ boost::mutex::scoped_lock scoped_lock(m_session_mutex);
+
+ yf::Limit::Ses *ses = 0;
+
+ std::map<mp::Session,yf::Limit::Ses *>::iterator it =
+ m_sessions.find(package.session());
+ if (it != m_sessions.end())
+ ses = it->second;
+ else
+ {
+ ses = new yf::Limit::Ses;
+ m_sessions[package.session()] = ses;
+ }
+
+ sz += package.response().get_size();
+
+ ses->bw_stat.add_bytes(sz);
+ ses->pdu_stat.add_bytes(1);
+
int bw_total = ses->bw_stat.get_total();
int pdu_total = ses->pdu_stat.get_total();
int search_total = ses->search_stat.get_total();
-
+
if (m_search_max)
reduce += search_total / m_search_max;
if (m_bw_max)
}
}
if (package.session().is_closed())
+ {
m_sessions.erase(package.session());
+ delete ses;
+ }
}
if (reduce)
{
yaz_log(YLOG_LOG, "sleeping %d seconds", reduce);
+#ifdef WIN32
+ Sleep(reduce * 1000);
+#else
sleep(reduce);
+#endif
}
}
};
}
-// bandwidth class (taken from YAZ Proxy)
-
-Yaz_bw::Yaz_bw(int sz)
-{
- m_sec = 0;
- m_size = sz;
- m_bucket = new int[m_size];
- m_ptr = 0;
-}
-
-Yaz_bw::~Yaz_bw()
-{
- delete [] m_bucket;
-}
-
-int Yaz_bw::get_total()
-{
- add_bytes(0);
- int bw = 0;
- int i;
- for (i = 0; i<m_size; i++)
- bw += m_bucket[i];
- return bw;
-}
-
-void Yaz_bw::add_bytes(int b)
-{
- long now = time(0);
-
- if (now >= m_sec)
- {
- int d = now - m_sec;
- if (d > m_size)
- d = m_size;
- while (--d >= 0)
- {
- if (++m_ptr == m_size)
- m_ptr = 0;
- m_bucket[m_ptr] = 0;
- }
- m_bucket[m_ptr] += b;
- }
- m_sec = now;
-}
/*
* Local variables: