1 /* $Id: filter_session_shared.cpp,v 1.6 2006-01-13 15:09:35 adam Exp $
2 Copyright (c) 2005, Index Data.
10 #include "package.hpp"
12 #include <boost/thread/mutex.hpp>
13 #include <boost/shared_ptr.hpp>
16 #include "filter_session_shared.hpp"
20 #include <yaz/otherinfo.h>
21 #include <yaz/diagbib1.h>
26 namespace yf = yp2::filter;
30 class SessionShared::Rep {
31 friend class SessionShared;
32 void handle_init(Z_InitRequest *req, Package &package);
33 void handle_search(Z_APDU *req, Package &package);
35 typedef boost::shared_ptr<SessionShared::List> SharedList;
37 typedef std::map<SessionShared::InitKey,SharedList> InitListMap;
38 InitListMap m_init_list_map;
40 typedef std::map<Session,SharedList> SessionListMap;
41 SessionListMap m_session_list_map;
44 class SessionShared::InitKey {
45 friend class SessionShared;
46 friend class SessionShared::Rep;
51 std::string m_password;
53 bool operator < (const SessionShared::InitKey &k) const;
55 class SessionShared::List {
57 yazpp_1::GDU m_init_response; // init response for backend
58 Session m_session; // session for backend
67 bool yf::SessionShared::InitKey::operator < (const SessionShared::InitKey
70 if (m_vhost < k.m_vhost)
72 else if (m_vhost < k.m_vhost)
75 if (m_open < k.m_open)
77 else if (m_open > k.m_open)
80 if (m_user < k.m_user)
82 else if (m_user > k.m_user)
85 if (m_group < k.m_group)
87 else if (m_group > k.m_group)
90 if (m_password < k.m_password)
92 else if (m_password > k.m_password)
97 yf::SessionShared::SessionShared() : m_p(new Rep)
101 yf::SessionShared::~SessionShared()
105 void yf::SessionShared::Rep::handle_search(Z_APDU *apdu_req,
108 yaz_log(YLOG_LOG, "Got search");
110 // Z_SearchRequest *req = apdu_req->u.searchRequest;
112 SessionListMap::iterator it = m_session_list_map.find(package.session());
113 if (it == m_session_list_map.end())
117 odr.create_close(apdu_req,
118 Z_Close_protocolError,
119 "no session for search request in session_shared");
120 package.session().close();
124 Package search_package(it->second->m_session, package.origin());
125 search_package.copy_filter(package);
126 search_package.request() = package.request();
128 search_package.move();
130 // transfer to frontend
131 package.response() = search_package.response();
134 void yf::SessionShared::Rep::handle_init(Z_InitRequest *req, Package &package)
136 yaz_log(YLOG_LOG, "Got init");
138 SessionShared::InitKey key;
140 yaz_oi_get_string_oidval(&req->otherInfo, VAL_PROXY, 1, 0);
144 if (!req->idAuthentication)
146 yaz_log(YLOG_LOG, "No authentication");
150 Z_IdAuthentication *auth = req->idAuthentication;
153 case Z_IdAuthentication_open:
154 yaz_log(YLOG_LOG, "open auth open=%s", auth->u.open);
155 key.m_open = auth->u.open;
157 case Z_IdAuthentication_idPass:
158 yaz_log(YLOG_LOG, "idPass user=%s group=%s pass=%s",
159 auth->u.idPass->userId, auth->u.idPass->groupId,
160 auth->u.idPass->password);
161 if (auth->u.idPass->userId)
162 key.m_user = auth->u.idPass->userId;
163 if (auth->u.idPass->groupId)
164 key.m_group = auth->u.idPass->groupId;
165 if (auth->u.idPass->password)
166 key.m_password = auth->u.idPass->password;
168 case Z_IdAuthentication_anonymous:
169 yaz_log(YLOG_LOG, "anonymous");
172 yaz_log(YLOG_LOG, "other");
175 InitListMap::iterator it = m_init_list_map.find(key);
176 if (it == m_init_list_map.end())
178 yaz_log(YLOG_LOG, "New KEY");
180 // building new package with original init and new session
181 SharedList l(new SessionShared::List); // new session for backend
183 Package init_package(l->m_session, package.origin());
184 init_package.copy_filter(package);
185 init_package.request() = package.request();
189 // transfer to frontend
190 package.response() = init_package.response();
192 // check that we really got Z39.50 Init Response
193 Z_GDU *gdu = init_package.response().get();
194 if (gdu && gdu->which == Z_GDU_Z3950
195 && gdu->u.z3950->which == Z_APDU_initResponse)
197 // save the init response
198 l->m_init_response = init_package.response();
200 // save session and init response for later
201 m_init_list_map[key] = l;
203 m_session_list_map[package.session()] = l;
208 yaz_log(YLOG_LOG, "Existing KEY");
209 package.response() = it->second->m_init_response;
211 m_session_list_map[package.session()] = it->second;
215 void yf::SessionShared::process(Package &package) const
217 // don't tell the backend if the "fronent" filter closes..
218 // we want to keep them alive
219 if (package.session().is_closed())
221 m_p->m_session_list_map.erase(package.session());
225 Z_GDU *gdu = package.request().get();
227 if (gdu && gdu->which == Z_GDU_Z3950)
229 Z_APDU *apdu = gdu->u.z3950;
233 case Z_APDU_initRequest:
234 m_p->handle_init(apdu->u.initRequest, package);
236 case Z_APDU_searchRequest:
237 m_p->handle_search(apdu, package);
242 odr.create_close(apdu, Z_Close_protocolError,
243 "cannot handle a package of this type");
244 package.session().close();
248 if (package.session().is_closed()) {
249 m_p->m_session_list_map.erase(package.session());
253 package.move(); // Not Z39.50 or not Init
256 static yp2::filter::Base* filter_creator()
258 return new yp2::filter::SessionShared;
262 struct yp2_filter_struct yp2_filter_session_shared = {
274 * indent-tabs-mode: nil
275 * c-file-style: "stroustrup"
277 * vim: shiftwidth=4 tabstop=8 expandtab