Proxy with QOS support. XML config. Better logging
[yazpp-moved-to-github.git] / src / yaz-proxy-config.cpp
1 /*
2  * Copyright (c) 1998-2003, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: yaz-proxy-config.cpp,v 1.1 2003-10-01 13:13:51 adam Exp $
6  */
7
8 #include <yaz/log.h>
9 #include <yaz++/proxy.h>
10
11 Yaz_ProxyConfig::Yaz_ProxyConfig()
12 {
13     m_copy = 0;
14 #if HAVE_XML2
15     m_docPtr = 0;
16     m_proxyPtr = 0;
17 #endif
18 }
19
20 Yaz_ProxyConfig::~Yaz_ProxyConfig()
21 {
22 #if HAVE_XML2
23     if (!m_copy && m_docPtr)
24         xmlFreeDoc(m_docPtr);
25 #endif
26 }
27
28 void Yaz_ProxyConfig::operator=(const Yaz_ProxyConfig &conf)
29 {
30 #if HAVE_XML2
31     m_docPtr = conf.m_docPtr;
32     m_proxyPtr = conf.m_proxyPtr;
33 #endif
34     m_copy = 1;
35 }
36
37 int Yaz_ProxyConfig::read_xml(const char *fname)
38 {
39 #if HAVE_XML2
40     xmlDocPtr ndoc = xmlParseFile(fname);
41
42     if (!ndoc)
43     {
44         yaz_log(LOG_WARN, "Config file %s not found or parse error", fname);
45         return -1;  // no good
46     }
47     xmlNodePtr proxyPtr = xmlDocGetRootElement(ndoc);
48     if (!proxyPtr || proxyPtr->type != XML_ELEMENT_NODE ||
49         strcmp((const char *) proxyPtr->name, "proxy"))
50     {
51         yaz_log(LOG_WARN, "No proxy element in %s", fname);
52         xmlFreeDoc(ndoc);
53         return -1;
54     }
55     m_proxyPtr = proxyPtr;
56
57     // OK: release previous and make it the current one.
58     if (m_docPtr)
59         xmlFreeDoc(m_docPtr);
60     m_docPtr = ndoc;
61     return 0;
62 #else
63     return -2;
64 #endif
65 }
66
67 #if HAVE_XML2
68 const char *Yaz_ProxyConfig::get_text(xmlNodePtr ptr)
69 {
70     for(ptr = ptr->children; ptr; ptr = ptr->next)
71         if (ptr->type == XML_TEXT_NODE)
72         {
73             xmlChar *t = ptr->content;
74             if (t)
75             {
76                 while (*t == ' ')
77                     t++;
78                 return (const char *) t;
79             }
80         }
81     return 0;
82 }
83 #endif
84
85 #if HAVE_XML2
86 void Yaz_ProxyConfig::return_limit(xmlNodePtr ptr,
87                                    int *limit_bw,
88                                    int *limit_pdu,
89                                    int *limit_req)
90 {
91     for (ptr = ptr->children; ptr; ptr = ptr->next)
92     {
93         if (ptr->type == XML_ELEMENT_NODE 
94             && !strcmp((const char *) ptr->name, "bandwidth"))
95         {
96             const char *t = get_text(ptr);
97             if (t)
98                 *limit_bw = atoi(t);
99         }
100         if (ptr->type == XML_ELEMENT_NODE 
101             && !strcmp((const char *) ptr->name, "retrieve"))
102         {
103             const char *t = get_text(ptr);
104             if (t)
105                 *limit_req = atoi(t);
106         }
107         if (ptr->type == XML_ELEMENT_NODE 
108             && !strcmp((const char *) ptr->name, "pdu"))
109         {
110             const char *t = get_text(ptr);
111             if (t)
112                 *limit_pdu = atoi(t);
113         }
114     }
115 }
116 #endif
117
118 #if HAVE_XML2
119 void Yaz_ProxyConfig::return_target_info(xmlNodePtr ptr,
120                                          const char **url,
121                                          int *keepalive,
122                                          int *limit_bw,
123                                          int *limit_pdu,
124                                          int *limit_req)
125 {
126     ptr = ptr->children;
127     for (; ptr; ptr = ptr->next)
128     {
129         if (ptr->type == XML_ELEMENT_NODE 
130             && !strcmp((const char *) ptr->name, "url"))
131         {
132             const char *t = get_text(ptr);
133             if (t)
134                 *url = t;
135         }
136         if (ptr->type == XML_ELEMENT_NODE 
137             && !strcmp((const char *) ptr->name, "keepalive"))
138         {
139             const char *t = get_text(ptr);
140             if (!t || *t == '1')
141                 *keepalive = 1;
142             else
143                 *keepalive = 0;
144         }
145         if (ptr->type == XML_ELEMENT_NODE 
146             && !strcmp((const char *) ptr->name, "limit"))
147             return_limit(ptr, limit_bw, limit_pdu, limit_req);
148     }
149 }
150 #endif
151
152 void Yaz_ProxyConfig::get_target_info(const char *name,
153                                       const char **url,
154                                       int *keepalive,
155                                       int *limit_bw,
156                                       int *limit_pdu,
157                                       int *limit_req)
158 {
159 #if HAVE_XML2
160     xmlNodePtr ptr;
161     if (!m_proxyPtr)
162     {
163         *url = name;
164         return;
165     }
166     for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
167     {
168         if (ptr->type == XML_ELEMENT_NODE &&
169             !strcmp((const char *) ptr->name, "target"))
170         {
171             // default one ? 
172             if (!name)
173             {
174                 // <target default="1"> ?
175                 struct _xmlAttr *attr;
176                 for (attr = ptr->properties; attr; attr = attr->next)
177                     if (!strcmp((const char *) attr->name, "default") &&
178                         attr->children && attr->children->type == XML_TEXT_NODE)
179                     {
180                         xmlChar *t = attr->children->content;
181                         if (!t || *t == '1')
182                         {
183                             return_target_info(ptr, url, keepalive,
184                                                limit_bw, limit_pdu, limit_req);
185                             return;
186                         }
187                     }
188             }
189             else
190             {
191                 // <target name="name"> ?
192                 struct _xmlAttr *attr;
193                 for (attr = ptr->properties; attr; attr = attr->next)
194                     if (!strcmp((const char *) attr->name, "name"))
195                     {
196                         if (attr->children
197                             && attr->children->type==XML_TEXT_NODE
198                             && attr->children->content 
199                             && (!strcmp((const char *) attr->children->content,
200                                         name)
201                                 || !strcmp((const char *) attr->children->content,
202                                            "*")))
203                         {
204                             *url = name;
205                             return_target_info(ptr, url, keepalive,
206                                                limit_bw, limit_pdu, limit_req);
207                             return;
208                         }
209                     }
210             }
211         }
212     }
213 #else
214     *url = name;
215     return;
216 #endif
217 }
218
219