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