ca63da7f48c1c6026ffdf335edba476b9e220eec
[yazproxy-moved-to-github.git] / src / t-server.cpp
1 /*
2  * Copyright (c) 1998-2005, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: t-server.cpp,v 1.3 2005-09-11 20:06:54 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             break;
62         case Z_APDU_searchRequest:
63             sleep(5);
64             apdu = zget_APDU(odr, Z_APDU_searchResponse);
65             break;
66         default:
67             apdu = zget_APDU(odr, Z_APDU_close);
68             m_close_flag = 1;
69             break;
70         }
71         if (apdu)
72             m_output = new GDU(apdu);
73     }
74     yaz_log(YLOG_LOG, "Auth_Msg:handle end");
75     odr_destroy(odr);
76     return this;
77 }
78
79 class MyServer : public Z_Assoc {
80 public:
81     ~MyServer();
82     MyServer(IPDU_Observable *the_PDU_Observable,
83              Msg_Thread *m_my_thread
84         );
85     IPDU_Observer* sessionNotify(IPDU_Observable *the_PDU_Observable,
86                                  int fd);
87
88     void recv_GDU(Z_GDU *apdu, int len);
89
90     void failNotify();
91     void timeoutNotify();
92     void connectNotify();
93
94     int m_no_requests;
95     int m_delete_flag;
96 private:
97     yazpp_1::GDUQueue m_in_queue;
98     Msg_Thread *m_my_thread;
99 };
100
101 void Auth_Msg::result()
102 {
103     m_front->m_no_requests--;
104     if (!m_front->m_delete_flag)
105     {
106         if (m_output)
107         {
108             int len;
109             m_front->send_GDU(m_output->get(), &len);
110         }
111         if (m_close_flag)
112         {
113             m_front->close();
114             m_front->m_delete_flag = 1;
115         }
116     }
117     if (m_front->m_delete_flag && m_front->m_no_requests == 0)
118         delete m_front;
119 }
120
121 MyServer::MyServer(IPDU_Observable *the_PDU_Observable,
122                    Msg_Thread *my_thread
123 )
124     :  Z_Assoc(the_PDU_Observable)
125 {
126     m_my_thread = my_thread;
127     m_no_requests = 0;
128     m_delete_flag = 0;
129     yaz_log(YLOG_LOG, "Construct Myserver=%p", this);
130 }
131
132 IPDU_Observer *MyServer::sessionNotify(IPDU_Observable
133                                        *the_PDU_Observable, int fd)
134 {
135     MyServer *my = new MyServer(the_PDU_Observable, m_my_thread);
136     yaz_log(YLOG_LOG, "New session %s", the_PDU_Observable->getpeername());
137     return my;
138 }
139
140 MyServer::~MyServer()
141 {
142     yaz_log(YLOG_LOG, "Destroy Myserver=%p", this);
143 }
144
145 void MyServer::recv_GDU(Z_GDU *apdu, int len)
146 {
147     GDU *gdu = new GDU(apdu);
148     Auth_Msg *m = new Auth_Msg(gdu, this);
149     m_no_requests++;
150     m_my_thread->put(m);    
151 }
152
153 void MyServer::failNotify()
154 {
155     m_delete_flag = 1;
156     if (m_no_requests == 0)
157         delete this;
158     
159 }
160
161 void MyServer::timeoutNotify()
162 {
163     m_delete_flag = 1;
164     if (m_no_requests == 0)
165         delete this;
166 }
167
168 void MyServer::connectNotify()
169 {
170
171 }
172
173 void usage(const char *prog)
174 {
175     fprintf (stderr, "%s: [-a log] [-v level] [-T] @:port\n", prog);
176     exit (1);
177 }
178
179 int main(int argc, char **argv)
180 {
181     char *arg;
182     char *prog = *argv;
183     int thread_flag = 0;
184     int ret;
185     const char *addr = "tcp:@:9999";
186     char *apdu_log = 0;
187
188     while ((ret = options("a:v:T", argv, argc, &arg)) != -2)
189     {
190         switch (ret)
191         {
192         case 0:
193             addr = xstrdup(arg);
194             break;
195         case 'a':
196             apdu_log = xstrdup(arg);
197             break;
198         case 'v':
199             yaz_log_init_level (yaz_log_mask_str(arg));
200             break;
201         case 'T':
202             thread_flag = 1;
203             break;
204         default:
205             usage(prog);
206             return 1;
207         }
208     }
209
210     SocketManager mySocketManager;
211
212     PDU_Assoc *my_PDU_Assoc = 0;
213     
214     MyServer *z = 0;
215
216     Msg_Thread *my_thread = new Msg_Thread(&mySocketManager);
217
218 #if YAZ_POSIX_THREADS
219     if (thread_flag)
220         my_PDU_Assoc = new PDU_AssocThread(&mySocketManager);
221     else
222         my_PDU_Assoc = new PDU_Assoc(&mySocketManager);
223 #else
224     my_PDU_Assoc = new PDU_Assoc(&mySocketManager);
225 #endif
226     
227     z = new MyServer(my_PDU_Assoc, my_thread);
228     z->server(addr);
229     if (apdu_log)
230     {
231         yaz_log (YLOG_LOG, "set_APDU_log %s", apdu_log);
232         z->set_APDU_log(apdu_log);
233     }
234
235     while (mySocketManager.processEvent() > 0)
236         ;
237     delete z;
238     delete my_thread;
239     return 0;    
240 }
241 /*
242  * Local variables:
243  * c-basic-offset: 4
244  * indent-tabs-mode: nil
245  * End:
246  * vim: shiftwidth=4 tabstop=8 expandtab
247  */
248