1 /* $Id: filter_session_shared.cpp,v 1.4 2006-01-04 11:55:31 adam Exp $
2 Copyright (c) 2005, Index Data.
11 #include "package.hpp"
13 #include <boost/thread/mutex.hpp>
14 #include <boost/shared_ptr.hpp>
17 #include "filter_session_shared.hpp"
21 #include <yaz/otherinfo.h>
22 #include <yaz/diagbib1.h>
27 namespace yf = yp2::filter;
31 class SessionShared::Rep {
32 friend class SessionShared;
33 void handle_init(Z_InitRequest *req, Package &package);
34 void handle_search(Z_SearchRequest *req, Package &package);
36 typedef boost::shared_ptr<SessionShared::List> SharedList;
38 typedef std::map<SessionShared::InitKey,SharedList> InitListMap;
39 InitListMap m_init_list_map;
41 typedef std::map<Session,SharedList> SessionListMap;
42 SessionListMap m_session_list_map;
45 class SessionShared::InitKey {
46 friend class SessionShared;
47 friend class SessionShared::Rep;
52 std::string m_password;
54 bool operator < (const SessionShared::InitKey &k) const;
56 class SessionShared::List {
58 yazpp_1::GDU m_init_response; // init response for backend
59 Session m_session; // session for backend
68 bool yf::SessionShared::InitKey::operator < (const SessionShared::InitKey
71 if (m_vhost < k.m_vhost)
73 else if (m_vhost < k.m_vhost)
76 if (m_open < k.m_open)
78 else if (m_open > k.m_open)
81 if (m_user < k.m_user)
83 else if (m_user > k.m_user)
86 if (m_group < k.m_group)
88 else if (m_group > k.m_group)
91 if (m_password < k.m_password)
93 else if (m_password > k.m_password)
98 yf::SessionShared::SessionShared() : m_p(new Rep)
102 yf::SessionShared::~SessionShared()
106 void yf::SessionShared::Rep::handle_search(Z_SearchRequest *req,
109 yaz_log(YLOG_LOG, "Got search");
111 SessionListMap::iterator it = m_session_list_map.find(package.session());
112 if (it == m_session_list_map.end())
115 package.response() = odr.create_close(
116 Z_Close_protocolError,
117 "no session for search request in session_shared");
118 package.session().close();
122 Package search_package(it->second->m_session, package.origin());
123 search_package.copy_filter(package);
124 search_package.request() = package.request();
126 search_package.move();
128 // transfer to frontend
129 package.response() = search_package.response();
132 void yf::SessionShared::Rep::handle_init(Z_InitRequest *req, Package &package)
134 yaz_log(YLOG_LOG, "Got init");
136 SessionShared::InitKey key;
138 yaz_oi_get_string_oidval(&req->otherInfo, VAL_PROXY, 1, 0);
142 if (!req->idAuthentication)
144 yaz_log(YLOG_LOG, "No authentication");
148 Z_IdAuthentication *auth = req->idAuthentication;
151 case Z_IdAuthentication_open:
152 yaz_log(YLOG_LOG, "open auth open=%s", auth->u.open);
153 key.m_open = auth->u.open;
155 case Z_IdAuthentication_idPass:
156 yaz_log(YLOG_LOG, "idPass user=%s group=%s pass=%s",
157 auth->u.idPass->userId, auth->u.idPass->groupId,
158 auth->u.idPass->password);
159 if (auth->u.idPass->userId)
160 key.m_user = auth->u.idPass->userId;
161 if (auth->u.idPass->groupId)
162 key.m_group = auth->u.idPass->groupId;
163 if (auth->u.idPass->password)
164 key.m_password = auth->u.idPass->password;
166 case Z_IdAuthentication_anonymous:
167 yaz_log(YLOG_LOG, "anonymous");
170 yaz_log(YLOG_LOG, "other");
173 InitListMap::iterator it = m_init_list_map.find(key);
174 if (it == m_init_list_map.end())
176 yaz_log(YLOG_LOG, "New KEY");
178 // building new package with original init and new session
179 SharedList l(new SessionShared::List); // new session for backend
181 Package init_package(l->m_session, package.origin());
182 init_package.copy_filter(package);
183 init_package.request() = package.request();
187 // transfer to frontend
188 package.response() = init_package.response();
190 // check that we really got Z39.50 Init Response
191 Z_GDU *gdu = init_package.response().get();
192 if (gdu && gdu->which == Z_GDU_Z3950
193 && gdu->u.z3950->which == Z_APDU_initResponse)
195 // save the init response
196 l->m_init_response = init_package.response();
198 // save session and init response for later
199 m_init_list_map[key] = l;
201 m_session_list_map[package.session()] = l;
206 yaz_log(YLOG_LOG, "Existing KEY");
207 package.response() = it->second->m_init_response;
209 m_session_list_map[package.session()] = it->second;
213 void yf::SessionShared::process(Package &package) const
215 // don't tell the backend if the "fronent" filter closes..
216 // we want to keep them alive
217 if (package.session().is_closed())
219 m_p->m_session_list_map.erase(package.session());
223 Z_GDU *gdu = package.request().get();
225 if (gdu && gdu->which == Z_GDU_Z3950)
227 Z_APDU *apdu = gdu->u.z3950;
231 case Z_APDU_initRequest:
232 m_p->handle_init(apdu->u.initRequest, package);
234 case Z_APDU_searchRequest:
235 m_p->handle_search(apdu->u.searchRequest, package);
239 package.response() = odr.create_close(
240 Z_Close_protocolError,
241 "cannot handle a package of this type");
242 package.session().close();
246 if (package.session().is_closed()) {
247 m_p->m_session_list_map.erase(package.session());
251 package.move(); // Not Z39.50 or not Init
254 static yp2::filter::Base* filter_creator()
256 return new yp2::filter::SessionShared;
260 struct yp2_filter_struct yp2_filter_session_shared = {
272 * indent-tabs-mode: nil
273 * c-file-style: "stroustrup"
275 * vim: shiftwidth=4 tabstop=8 expandtab