b7133a5bdbdf17e524f23f61ce7d7f6982e43c8e
[yazproxy-moved-to-github.git] / src / t-server.cpp
1 /*
2  * Copyright (c) 2005, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: t-server.cpp,v 1.6 2005-10-05 12:07:15 adam Exp $
6  */
7
8 #include <stdlib.h>
9 #include <pthread.h>
10 #include <yaz/log.h>
11 #include <yaz/diagbib1.h>
12 #include <yaz/options.h>
13 #include "msg-thread.h"
14 #include <yaz++/z-assoc.h>
15 #include <yaz++/pdu-assoc.h>
16 #include <yaz++/gdu.h>
17 #include <yaz++/socket-manager.h>
18
19 using namespace yazpp_1;
20
21 class MyServer;
22
23 class Auth_Msg : public IMsg_Thread {
24 public:
25     int m_close_flag;
26     GDU *m_gdu;
27     GDU *m_output;
28     MyServer *m_front;
29     IMsg_Thread *handle();
30     void result();
31     Auth_Msg(GDU *gdu, MyServer *front);
32     virtual ~Auth_Msg();
33 };
34
35 Auth_Msg::Auth_Msg(GDU *gdu, MyServer *front)
36 {
37     m_front = front;
38     m_output = 0;
39     m_gdu = gdu;
40     m_close_flag = 0;
41 }
42
43 Auth_Msg::~Auth_Msg()
44 {
45     delete m_output;
46     delete m_gdu;
47 }
48     
49 IMsg_Thread *Auth_Msg::handle()
50 {
51     ODR odr = odr_createmem(ODR_ENCODE);
52     yaz_log(YLOG_LOG, "Auth_Msg:handle begin");
53     Z_GDU *z_gdu = m_gdu->get();
54     if (z_gdu->which == Z_GDU_Z3950)
55     {
56         Z_APDU *apdu = 0;
57         switch(z_gdu->u.z3950->which)
58         {
59         case Z_APDU_initRequest:
60             apdu = zget_APDU(odr, Z_APDU_initResponse);
61             ODR_MASK_SET(apdu->u.initResponse->options, Z_Options_triggerResourceCtrl);
62             ODR_MASK_SET(apdu->u.initResponse->options, Z_Options_search);
63             ODR_MASK_SET(apdu->u.initResponse->options, Z_Options_present);
64             break;
65         case Z_APDU_searchRequest:
66             sleep(5);
67             apdu = zget_APDU(odr, Z_APDU_searchResponse);
68             break;
69         case Z_APDU_triggerResourceControlRequest:
70             break;
71         default:
72             apdu = zget_APDU(odr, Z_APDU_close);
73             m_close_flag = 1;
74             break;
75         }
76         if (apdu)
77             m_output = new GDU(apdu);
78     }
79     yaz_log(YLOG_LOG, "Auth_Msg:handle end");
80     odr_destroy(odr);
81     return this;
82 }
83
84 class MyServer : public Z_Assoc {
85 public:
86     ~MyServer();
87     MyServer(IPDU_Observable *the_PDU_Observable,
88              Msg_Thread *m_my_thread
89         );
90     IPDU_Observer* sessionNotify(IPDU_Observable *the_PDU_Observable,
91                                  int fd);
92
93     void recv_GDU(Z_GDU *apdu, int len);
94
95     void failNotify();
96     void timeoutNotify();
97     void connectNotify();
98
99     int m_no_requests;
100     int m_delete_flag;
101 private:
102     yazpp_1::GDUQueue m_in_queue;
103     Msg_Thread *m_my_thread;
104 };
105
106 void Auth_Msg::result()
107 {
108     m_front->m_no_requests--;
109     if (!m_front->m_delete_flag)
110     {
111         if (m_output)
112         {
113             int len;
114             m_front->send_GDU(m_output->get(), &len);
115         }
116         if (m_close_flag)
117         {
118             m_front->close();
119             m_front->m_delete_flag = 1;
120         }
121     }
122     if (m_front->m_delete_flag && m_front->m_no_requests == 0)
123         delete m_front;
124     delete this;
125 }
126
127 MyServer::MyServer(IPDU_Observable *the_PDU_Observable,
128                    Msg_Thread *my_thread
129 )
130     :  Z_Assoc(the_PDU_Observable)
131 {
132     m_my_thread = my_thread;
133     m_no_requests = 0;
134     m_delete_flag = 0;
135     yaz_log(YLOG_LOG, "Construct Myserver=%p", this);
136 }
137
138 IPDU_Observer *MyServer::sessionNotify(IPDU_Observable
139                                        *the_PDU_Observable, int fd)
140 {
141     MyServer *my = new MyServer(the_PDU_Observable, m_my_thread);
142     yaz_log(YLOG_LOG, "New session %s", the_PDU_Observable->getpeername());
143     return my;
144 }
145
146 MyServer::~MyServer()
147 {
148     yaz_log(YLOG_LOG, "Destroy Myserver=%p", this);
149 }
150
151 void MyServer::recv_GDU(Z_GDU *apdu, int len)
152 {
153     GDU *gdu = new GDU(apdu);
154     Auth_Msg *m = new Auth_Msg(gdu, this);
155     m_no_requests++;
156     m_my_thread->put(m);    
157 }
158
159 void MyServer::failNotify()
160 {
161     m_delete_flag = 1;
162     if (m_no_requests == 0)
163         delete this;
164     
165 }
166
167 void MyServer::timeoutNotify()
168 {
169     m_delete_flag = 1;
170     if (m_no_requests == 0)
171         delete this;
172 }
173
174 void MyServer::connectNotify()
175 {
176
177 }
178
179 void usage(const char *prog)
180 {
181     fprintf (stderr, "%s: [-a log] [-v level] [-T] @:port\n", prog);
182     exit (1);
183 }
184
185 int main(int argc, char **argv)
186 {
187     char *arg;
188     char *prog = *argv;
189     int thread_flag = 0;
190     int ret;
191     const char *addr = "tcp:@:9999";
192     char *apdu_log = 0;
193     int no_threads = 1;
194
195     while ((ret = options("n:a:v:T", argv, argc, &arg)) != -2)
196     {
197         switch (ret)
198         {
199         case 0:
200             addr = xstrdup(arg);
201             break;
202         case 'n':
203             no_threads = atoi(arg);
204             break;
205         case 'a':
206             apdu_log = xstrdup(arg);
207             break;
208         case 'v':
209             yaz_log_init_level (yaz_log_mask_str(arg));
210             break;
211         case 'T':
212             thread_flag = 1;
213             break;
214         default:
215             usage(prog);
216             return 1;
217         }
218     }
219
220     SocketManager mySocketManager;
221
222     PDU_Assoc *my_PDU_Assoc = 0;
223     
224     MyServer *z = 0;
225
226     Msg_Thread *my_thread = new Msg_Thread(&mySocketManager, no_threads);
227
228 #if YAZ_POSIX_THREADS
229     if (thread_flag)
230         my_PDU_Assoc = new PDU_AssocThread(&mySocketManager);
231     else
232         my_PDU_Assoc = new PDU_Assoc(&mySocketManager);
233 #else
234     my_PDU_Assoc = new PDU_Assoc(&mySocketManager);
235 #endif
236     
237     z = new MyServer(my_PDU_Assoc, my_thread);
238     z->server(addr);
239     if (apdu_log)
240     {
241         yaz_log (YLOG_LOG, "set_APDU_log %s", apdu_log);
242         z->set_APDU_log(apdu_log);
243     }
244
245     while (mySocketManager.processEvent() > 0)
246         ;
247     delete z;
248     delete my_thread;
249     return 0;    
250 }
251 /*
252  * Local variables:
253  * c-basic-offset: 4
254  * indent-tabs-mode: nil
255  * End:
256  * vim: shiftwidth=4 tabstop=8 expandtab
257  */
258