1 /* $Id: filter_session_shared.cpp,v 1.5 2006-01-09 21:20:15 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_SearchRequest *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_SearchRequest *req,
108 yaz_log(YLOG_LOG, "Got search");
110 SessionListMap::iterator it = m_session_list_map.find(package.session());
111 if (it == m_session_list_map.end())
114 package.response() = odr.create_close(
115 Z_Close_protocolError,
116 "no session for search request in session_shared");
117 package.session().close();
121 Package search_package(it->second->m_session, package.origin());
122 search_package.copy_filter(package);
123 search_package.request() = package.request();
125 search_package.move();
127 // transfer to frontend
128 package.response() = search_package.response();
131 void yf::SessionShared::Rep::handle_init(Z_InitRequest *req, Package &package)
133 yaz_log(YLOG_LOG, "Got init");
135 SessionShared::InitKey key;
137 yaz_oi_get_string_oidval(&req->otherInfo, VAL_PROXY, 1, 0);
141 if (!req->idAuthentication)
143 yaz_log(YLOG_LOG, "No authentication");
147 Z_IdAuthentication *auth = req->idAuthentication;
150 case Z_IdAuthentication_open:
151 yaz_log(YLOG_LOG, "open auth open=%s", auth->u.open);
152 key.m_open = auth->u.open;
154 case Z_IdAuthentication_idPass:
155 yaz_log(YLOG_LOG, "idPass user=%s group=%s pass=%s",
156 auth->u.idPass->userId, auth->u.idPass->groupId,
157 auth->u.idPass->password);
158 if (auth->u.idPass->userId)
159 key.m_user = auth->u.idPass->userId;
160 if (auth->u.idPass->groupId)
161 key.m_group = auth->u.idPass->groupId;
162 if (auth->u.idPass->password)
163 key.m_password = auth->u.idPass->password;
165 case Z_IdAuthentication_anonymous:
166 yaz_log(YLOG_LOG, "anonymous");
169 yaz_log(YLOG_LOG, "other");
172 InitListMap::iterator it = m_init_list_map.find(key);
173 if (it == m_init_list_map.end())
175 yaz_log(YLOG_LOG, "New KEY");
177 // building new package with original init and new session
178 SharedList l(new SessionShared::List); // new session for backend
180 Package init_package(l->m_session, package.origin());
181 init_package.copy_filter(package);
182 init_package.request() = package.request();
186 // transfer to frontend
187 package.response() = init_package.response();
189 // check that we really got Z39.50 Init Response
190 Z_GDU *gdu = init_package.response().get();
191 if (gdu && gdu->which == Z_GDU_Z3950
192 && gdu->u.z3950->which == Z_APDU_initResponse)
194 // save the init response
195 l->m_init_response = init_package.response();
197 // save session and init response for later
198 m_init_list_map[key] = l;
200 m_session_list_map[package.session()] = l;
205 yaz_log(YLOG_LOG, "Existing KEY");
206 package.response() = it->second->m_init_response;
208 m_session_list_map[package.session()] = it->second;
212 void yf::SessionShared::process(Package &package) const
214 // don't tell the backend if the "fronent" filter closes..
215 // we want to keep them alive
216 if (package.session().is_closed())
218 m_p->m_session_list_map.erase(package.session());
222 Z_GDU *gdu = package.request().get();
224 if (gdu && gdu->which == Z_GDU_Z3950)
226 Z_APDU *apdu = gdu->u.z3950;
230 case Z_APDU_initRequest:
231 m_p->handle_init(apdu->u.initRequest, package);
233 case Z_APDU_searchRequest:
234 m_p->handle_search(apdu->u.searchRequest, package);
238 package.response() = odr.create_close(
239 Z_Close_protocolError,
240 "cannot handle a package of this type");
241 package.session().close();
245 if (package.session().is_closed()) {
246 m_p->m_session_list_map.erase(package.session());
250 package.move(); // Not Z39.50 or not Init
253 static yp2::filter::Base* filter_creator()
255 return new yp2::filter::SessionShared;
259 struct yp2_filter_struct yp2_filter_session_shared = {
271 * indent-tabs-mode: nil
272 * c-file-style: "stroustrup"
274 * vim: shiftwidth=4 tabstop=8 expandtab