SRW/SRU protocol support. CQL->PQF map for Z39.50/SRW/SRU
[yazpp-moved-to-github.git] / include / yaz++ / proxy.h
1 /*
2  * Copyright (c) 1998-2003, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: proxy.h,v 1.22 2003-12-16 14:17:01 adam Exp $
6  */
7
8 #include <yaz++/z-assoc.h>
9 #include <yaz++/z-query.h>
10 #include <yaz++/z-databases.h>
11 #include <yaz/cql.h>
12 #if HAVE_XML2
13 #include <libxml/parser.h>
14 #include <libxml/tree.h>
15 #endif
16
17 class Yaz_Proxy;
18
19 #define MAX_ZURL_PLEX 10
20
21 #define PROXY_LOG_APDU_CLIENT 1
22 #define PROXY_LOG_APDU_SERVER 2
23 #define PROXY_LOG_REQ_CLIENT 4
24 #define PROXY_LOG_REQ_SERVER 8
25
26 struct Yaz_RecordCache_Entry;
27
28 class YAZ_EXPORT Yaz_ProxyConfig {
29 public:
30     Yaz_ProxyConfig();
31     ~Yaz_ProxyConfig();
32     int read_xml(const char *fname);
33
34     int get_target_no(int no,
35                       const char **name,
36                       const char **url,
37                       int *limit_bw,
38                       int *limit_pdu,
39                       int *limit_req,
40                       int *target_idletime,
41                       int *client_idletime,
42                       int *max_clients,
43                       int *keepalive_limit_bw,
44                       int *keepalive_limit_pdu,
45                       int *pre_init,
46                       const char **cql2rpn);
47     
48     void get_generic_info(int *log_mask, int *max_clients);
49
50     void get_target_info(const char *name, const char **url,
51                          int *limit_bw, int *limit_pdu, int *limit_req,
52                          int *target_idletime, int *client_idletime,
53                          int *max_clients,
54                          int *keepalive_limit_bw, int *keepalive_limit_pdu,
55                          int *pre_init,
56                          const char **cql2rpn);
57
58     int check_query(ODR odr, const char *name, Z_Query *query, char **addinfo);
59     int check_syntax(ODR odr, const char *name,
60                      Odr_oid *syntax, char **addinfo);
61 private:
62     void operator=(const Yaz_ProxyConfig &conf);
63     int mycmp(const char *hay, const char *item, size_t len);
64 #if HAVE_XML2
65     xmlDocPtr m_docPtr;
66     xmlNodePtr m_proxyPtr;
67     void return_target_info(xmlNodePtr ptr, const char **url,
68                             int *limit_bw, int *limit_pdu, int *limit_req,
69                             int *target_idletime, int *client_idletime,
70                             int *keepalive_limit_bw, int *keepalive_limit_pdu,
71                             int *pre_init, const char **cql2rpn);
72     void return_limit(xmlNodePtr ptr,
73                       int *limit_bw, int *limit_pdu, int *limit_req);
74     int check_type_1(ODR odr, xmlNodePtr ptr, Z_RPNQuery *query,
75                      char **addinfo);
76     xmlNodePtr find_target_node(const char *name);
77     const char *get_text(xmlNodePtr ptr);
78     int check_type_1_attributes(ODR odr, xmlNodePtr ptr,
79                                 Z_AttributeList *attrs,
80                                 char **addinfo);
81     int check_type_1_structure(ODR odr, xmlNodePtr ptr, Z_RPNStructure *q,
82                                char **addinfo);
83 #endif
84     int m_copy;
85     int match_list(int v, const char *m);
86     int atoi_l(const char **cp);
87
88 };
89
90 class YAZ_EXPORT Yaz_RecordCache {
91  public:
92     Yaz_RecordCache ();
93     ~Yaz_RecordCache ();
94     void add (ODR o, Z_NamePlusRecordList *npr, int start, int hits);
95     
96     int lookup (ODR o, Z_NamePlusRecordList **npr, int start, int num,
97                 Odr_oid *syntax, Z_RecordComposition *comp);
98     void clear();
99
100     void copy_searchRequest(Z_SearchRequest *sr);
101     void copy_presentRequest(Z_PresentRequest *pr);
102     void set_max_size(int sz);
103  private:
104     NMEM m_mem;
105     Yaz_RecordCache_Entry *m_entries;
106     Z_SearchRequest *m_searchRequest;
107     Z_PresentRequest *m_presentRequest;
108     int match (Yaz_RecordCache_Entry *entry,
109                Odr_oid *syntax, int offset,
110                Z_RecordComposition *comp);
111     int m_max_size;
112 };
113
114 class YAZ_EXPORT Yaz_bw {
115  public:
116     Yaz_bw(int sz);
117     ~Yaz_bw();
118     void add_bytes(int m);
119     int get_total();
120  private:
121     long m_sec;   // time of most recent bucket
122     int *m_bucket;
123     int m_ptr;
124     int m_size;
125 };
126
127 /// Private class
128 class YAZ_EXPORT Yaz_ProxyClient : public Yaz_Z_Assoc {
129     friend class Yaz_Proxy;
130     Yaz_ProxyClient(IYaz_PDU_Observable *the_PDU_Observable,
131                     Yaz_Proxy *parent);
132     ~Yaz_ProxyClient();
133     void recv_GDU(Z_GDU *apdu, int len);
134     void recv_Z_PDU(Z_APDU *apdu, int len);
135     void recv_HTTP_response(Z_HTTP_Response *apdu, int len);
136     IYaz_PDU_Observer* sessionNotify
137         (IYaz_PDU_Observable *the_PDU_Observable, int fd);
138     void shutdown();
139     Yaz_Proxy *m_server;
140     void failNotify();
141     void timeoutNotify();
142     void connectNotify();
143     int send_to_target(Z_APDU *apdu);
144     const char *get_session_str();
145     char *m_cookie;
146     Yaz_ProxyClient *m_next;
147     Yaz_ProxyClient **m_prev;
148     int m_init_flag;
149     Yaz_Z_Query *m_last_query;
150     Yaz_Z_Databases m_last_databases;
151     char *m_last_resultSetId;
152     int m_last_ok;
153     int m_last_resultCount;
154     int m_sr_transform;
155     int m_seqno;
156     int m_waiting;
157     int m_resultSetStartPoint;
158     int m_bytes_sent;
159     int m_bytes_recv;
160     int m_pdu_recv;
161     ODR m_init_odr;
162     Z_APDU *m_initResponse;
163     Yaz_RecordCache m_cache;
164     void pre_init_client();
165     int m_target_idletime;
166     Yaz_Proxy *m_root;
167 };
168
169 class YAZ_EXPORT Yaz_cql2rpn {
170  public:
171     Yaz_cql2rpn();
172     ~Yaz_cql2rpn();
173     void set_pqf_file(const char *fname);
174     int query_transform(const char *cql, Z_RPNQuery **rpnquery, ODR o);
175  private:
176     cql_transform_t m_transform;
177 };
178
179
180 /// Information Retrieval Proxy Server.
181 class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc {
182  private:
183     char *get_cookie(Z_OtherInformation **otherInfo);
184     char *get_proxy(Z_OtherInformation **otherInfo);
185     Yaz_ProxyClient *get_client(Z_APDU *apdu, const char *cookie,
186                                 const char *proxy_host);
187     Z_APDU *result_set_optimize(Z_APDU *apdu);
188     void shutdown();
189     
190     Yaz_ProxyClient *m_client;
191     IYaz_PDU_Observable *m_PDU_Observable;
192     Yaz_ProxyClient *m_clientPool;
193     Yaz_Proxy *m_parent;
194     int m_seqno;
195     int m_max_clients;
196     int m_log_mask;
197     int m_keepalive_limit_bw;
198     int m_keepalive_limit_pdu;
199     int m_client_idletime;
200     int m_target_idletime;
201     char *m_proxyTarget;
202     char *m_default_target;
203     char *m_proxy_authentication;
204     long m_seed;
205     char *m_optimize;
206     int m_session_no;         // sequence for each client session
207     char m_session_str[30];  // session string (time:session_no)
208     Yaz_ProxyConfig *m_config;
209     char *m_config_fname;
210     int m_bytes_sent;
211     int m_bytes_recv;
212     int m_bw_max;
213     Yaz_bw m_bw_stat;
214     int m_pdu_max;
215     Yaz_bw m_pdu_stat;
216     Z_GDU *m_bw_hold_PDU;
217     int m_max_record_retrieve;
218     void handle_max_record_retrieve(Z_APDU *apdu);
219     void display_diagrecs(Z_DiagRec **pp, int num);
220     Z_Records *create_nonSurrogateDiagnostics(ODR o, int error,
221                                               const char *addinfo);
222
223     Z_APDU *handle_query_validation(Z_APDU *apdu);
224     Z_APDU *handle_query_transformation(Z_APDU *apdu);
225
226     Z_APDU *handle_syntax_validation(Z_APDU *apdu);
227     const char *load_balance(const char **url);
228     int m_reconfig_flag;
229     Yaz_ProxyConfig *check_reconfigure();
230     int m_request_no;
231     int m_invalid_session;
232     int m_marcxml_flag;
233     void convert_to_marcxml(Z_NamePlusRecordList *p);
234     Z_APDU *m_initRequest_apdu;
235     NMEM m_initRequest_mem;
236     Z_APDU *m_apdu_invalid_session;
237     NMEM m_mem_invalid_session;
238     int send_PDU_convert(Z_APDU *apdu, int *len);
239     ODR m_s2z_odr;
240     int m_s2z_hit_count;
241     int m_s2z_packing;
242     Z_APDU *m_s2z_init_apdu;
243     Z_APDU *m_s2z_search_apdu;
244     Z_APDU *m_s2z_present_apdu;
245     char *m_soap_ns;
246     int send_to_srw_client_error(int error);
247     int send_to_srw_client_ok(int hits, Z_Records *records);
248     int send_http_response(int code);
249     int send_srw_response(Z_SRW_PDU *srw_pdu);
250
251     int z_to_srw_diag(ODR o, Z_SRW_searchRetrieveResponse *srw_res,
252                       Z_DefaultDiagFormat *ddf);
253     int m_http_keepalive;
254     const char *m_http_version;
255     Yaz_cql2rpn m_cql2rpn;
256  public:
257     Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable,
258               Yaz_Proxy *parent = 0);
259     ~Yaz_Proxy();
260     void recv_GDU(Z_GDU *apdu, int len);
261     void handle_incoming_HTTP(Z_HTTP_Request *req);
262     void handle_incoming_Z_PDU(Z_APDU *apdu);
263     IYaz_PDU_Observer* sessionNotify
264         (IYaz_PDU_Observable *the_PDU_Observable, int fd);
265     void failNotify();
266     void timeoutNotify();
267     void connectNotify();
268     const char *option(const char *name, const char *value);
269     void set_default_target(const char *target);
270     void set_proxy_authentication (const char *auth);
271     char *get_proxy_target() { return m_proxyTarget; };
272     char *get_session_str() { return m_session_str; };
273     void set_max_clients(int m) { m_max_clients = m; };
274     void set_client_idletime (int t) { m_client_idletime = (t > 1) ? t : 600; };
275     void set_target_idletime (int t) { m_target_idletime = (t > 1) ? t : 600; };
276     int get_target_idletime () { return m_target_idletime; }
277     int set_config(const char *name);
278     void reconfig() { m_reconfig_flag = 1; }
279     int send_to_client(Z_APDU *apdu);
280     int server(const char *addr);
281     void pre_init();
282     int get_log_mask() { return m_log_mask; };
283     int handle_init_response_for_invalid_session(Z_APDU *apdu);
284 };
285