1 /*
2  *  Copyright (C) 2004-2008 Christos Tsantilas
3  *
4  *  This program is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2.1 of the License, or (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  *  MA  02110-1301  USA.
18  */
19 
20 
21 #ifndef __HEADERS_H
22 #define __HEADERS_H
23 
24 #include "c-icap.h"
25 
26 #ifdef __cplusplus
27 extern "C"
28 {
29 #endif
30 
31 /**
32  \defgroup HEADERS  Headers related API
33  \ingroup API
34  * Headers manipulation related API.
35  */
36 
37 enum ci_request_headers { ICAP_AUTHORIZATION, ICAP_ALLOW,
38                           ICAP_FROM, ICAP_HOST, ICAP_REFERER,
39                           ICAP_USERAGENT,ICAP_PREVIEW
40                         };
41 
42 
43 extern const char *ci_common_headers[];
44 extern const char *ci_request_headers[];
45 extern const char *ci_responce_headers[];
46 extern const char *ci_options_headers[];
47 
48 
49 enum ci_encapsulated_entities {ICAP_REQ_HDR, ICAP_RES_HDR,
50                                ICAP_REQ_BODY, ICAP_RES_BODY,
51                                ICAP_NULL_BODY,ICAP_OPT_BODY
52                               };
53 CI_DECLARE_DATA extern const char *ci_encaps_entities[];
54 
55 #ifdef __CYGWIN__
56 
57 const char *ci_encaps_entity_string(int e);
58 
59 #else
60 
61 #define ci_encaps_entity_string(e) (e <= ICAP_OPT_BODY && e >= ICAP_REQ_HDR?ci_encaps_entities[e]:"UNKNOWN")
62 
63 #endif
64 
65 /**
66  \typedef ci_headers_list_t
67  \ingroup HEADERS
68  * This is a struct which can store a set of headers.
69  * The developers should not touch ci_headers_list_t objects directly but
70  * they should use the documented macros and functions
71  */
72 typedef struct ci_headers_list {
73     int size;
74     int used;
75     char **headers;
76     int bufsize;
77     int bufused;
78     char *buf;
79     int packed;
80 } ci_headers_list_t;
81 
82 
83 typedef struct ci_encaps_entity {
84     int start;
85     int type;
86     void *entity;
87 } ci_encaps_entity_t;
88 
89 
90 #define BUFSIZE          4096
91 #define HEADERSTARTSIZE  64
92 #define HEADSBUFSIZE     BUFSIZE
93 #define MAX_HEADER_SIZE  1023
94 
95 #define ci_headers_not_empty(h) ((h)->used)
96 #define ci_headers_is_empty(h) ((h)->used == 0)
97 
98 /**
99  * Allocate memory for a ci_headers_list_t object and initialize it.
100  \ingroup HEADERS
101  \return the allocated object on success, NULL otherwise.
102  *
103  */
104 CI_DECLARE_FUNC(ci_headers_list_t *) ci_headers_create();
105 
106 /**
107  * Destroy a ci_headers_list_t object
108  \ingroup HEADERS
109  \param heads is a pointer to the ci_headers_list_t object to be destroyed
110  *
111  */
112 CI_DECLARE_FUNC(void) ci_headers_destroy(ci_headers_list_t *heads);
113 
114 /**
115  * Resets and initialize a ci_headers_list_t object
116  \ingroup HEADERS
117  \param heads pointer to the ci_headers_list_t object to be reset
118  *
119  */
120 CI_DECLARE_FUNC(void) ci_headers_reset(ci_headers_list_t *heads);
121 
122 CI_DECLARE_FUNC(int) ci_headers_setsize(ci_headers_list_t *heads, int size);
123 
124 /**
125  * Add a header to a ci_headers_list_t object
126  \ingroup HEADERS
127  \param heads is a pointer to the ci_headers_list_t object in which the header
128  *      will be added
129  \param header is the header to be added
130  \return Pointer to the newly add header on success, NULL otherwise
131  *
132  *example usage:
133  \code
134   ci_headers_add(heads,"Content-Length: 1025")
135  \endcode
136  *
137  */
138 CI_DECLARE_FUNC(const char *) ci_headers_add(ci_headers_list_t *heads, const char *header);
139 
140 /**
141  * Append a  headers list object to an other headers list
142  \ingroup HEADERS
143  \param heads is a pointer to the ci_headers_list_t object in which the
144  *      headers will be added
145  \param someheaders is a ci_headers_list_t object which contains the headers
146  *      will be added to the heads
147  \return non zero on success zero otherwise
148  */
149 CI_DECLARE_FUNC(int) ci_headers_addheaders(ci_headers_list_t *heads,const ci_headers_list_t *someheaders);
150 
151 /**
152  * Removes a header from a header list
153  \ingroup HEADERS
154  \param heads is a pointer to the ci_headers_list_t object
155  \param header is the name of the header to be removed
156  \return non zero on success, zero otherwise
157  *
158  *example usage:
159  \code
160   ci_headers_remove(heads,"Content-Length")
161  \endcode
162  *
163  */
164 CI_DECLARE_FUNC(int) ci_headers_remove(ci_headers_list_t *heads, const char *header);
165 
166 /**
167  * Search for a header in a header list
168  \ingroup HEADERS
169  \param heads is a pointer to the ci_headers_list_t object
170  \param header is the name of the header
171  \return a pointer to the start of the first occurrence of the header on
172  *       success, NULL otherwise
173  *
174  *example usage:
175  \code
176  char *head;
177  head = ci_headers_search(heads,"Content-Length")
178  \endcode
179  * In this example on success the head pointer will point to a
180  * \em "Content-Lenght: 1025" string
181  *
182  */
183 CI_DECLARE_FUNC(const char *)  ci_headers_search(ci_headers_list_t *heads, const char *header);
184 
185 /**
186  * Similar to ci_headers_search but also sets to a parameter the size of
187  * returned header
188  \ingroup HEADERS
189  */
190 CI_DECLARE_FUNC(const char *) ci_headers_search2(ci_headers_list_t * h, const char *header, size_t *return_size);
191 
192 /**
193  * Search for a header in a header list and return the value of the first
194  * occurrence of this header
195  \ingroup HEADERS
196  \param heads is a pointer to the ci_headers_list_t object
197  \param header is the name of the header
198  \return a pointer to the start of the header on success, NULL otherwise
199  *
200  *example usage:
201  \code
202  char *headval;
203  int content_length;
204  headval = ci_headers_value(heads,"Content-Length");
205  content_length = strtol(headval,NULL,10);
206  \endcode
207  *
208  */
209 CI_DECLARE_FUNC(const char *) ci_headers_value(ci_headers_list_t *heads, const char *header);
210 
211 /**
212  * Similar to ci_headers_search but also sets to a parameter the size of
213  * returned header value
214  \ingroup HEADERS
215  */
216 CI_DECLARE_FUNC(const char *) ci_headers_value2(ci_headers_list_t * h, const char *header, size_t *return_size);
217 
218 /**
219  * Search for a header in a header list and copy the value to a buffer if exist
220  \ingroup HEADERS
221  \param heads is a pointer to the ci_headers_list_t object
222  \param header is the name of the header
223  \param buf is the buffer to store header value
224 \param len is the size of the buffer buf
225 \return a pointer to the buf on success, NULL otherwise
226  *
227  *example usage:
228  \code
229  char *headval;
230  char buf[1024];
231  int content_length;
232  headval = ci_headers_copy_value(heads, "Content-Length", buf, sizeof(buf));
233  if (headval)
234      printf("Content-Length: %s\n", buf);
235  \endcode
236  *
237  */
238 CI_DECLARE_FUNC(const char *) ci_headers_copy_value(ci_headers_list_t *heads, const char *header, char *buf, size_t len);
239 
240 /**
241  * Run the given function for each header name/value pair
242  \ingroup HEADERS
243  \param heads is a pointer to the ci_headers_list_t object
244  \param data is a pointer to data which will passed as first argument to the
245  *      fn function
246  \param fn is a pointer to a function which will run for each header
247  *      name/value pair.
248  \return non zero on success, zero otherwise
249  */
250 CI_DECLARE_FUNC(int) ci_headers_iterate(ci_headers_list_t *heads, void *data, void (*fn)(void *data, const char  *header_name, const char  *header_value));
251 
252 /**
253  * Copy the headers to a buffer in a form they can be transmitted to the
254  * network.
255  * WARNING: It produces an non-NULL-terminated string.
256  \ingroup HEADERS
257  \param heads is a pointer to the ci_headers_list_t object
258  \param buf the buffer to store data.
259  \param size the size of buffer.
260  \return the size of written data, or zero if the headers does not fit to
261  *       buffer.
262  */
263 CI_DECLARE_FUNC(size_t) ci_headers_pack_to_buffer(ci_headers_list_t *heads, char *buf, size_t size);
264 
265 /**
266  * Get the first line of headers
267  \ingroup HEADERS
268  \param heads is a pointer to the ci_headers_list_t object
269  \return the first line on success, NULL otherwise
270 */
271 CI_DECLARE_FUNC(const char *) ci_headers_first_line(ci_headers_list_t *heads);
272 
273 /**
274  * Get the first line of headers and its size
275  \ingroup HEADERS
276  \param heads is a pointer to the ci_headers_list_t object
277  \param return_size where to store the size of first line in bytes
278  \return the first line on success, NULL otherwise
279 */
280 CI_DECLARE_FUNC(const char *) ci_headers_first_line2(ci_headers_list_t *heads, size_t *return_size);
281 
282 /*compatibility macro*/
283 #define ci_headers_copy_header_bytes ci_headers_pack_to_buffer
284 
285 /*The following headers are only used internally */
286 CI_DECLARE_FUNC(void) ci_headers_pack(ci_headers_list_t *heads);
287 CI_DECLARE_FUNC(int)  ci_headers_unpack(ci_headers_list_t *heads);
288 CI_DECLARE_FUNC(int)  sizeofheader(ci_headers_list_t *heads);
289 
290 CI_DECLARE_FUNC(ci_encaps_entity_t) *mk_encaps_entity(int type,int val);
291 CI_DECLARE_FUNC(void) destroy_encaps_entity(ci_encaps_entity_t *e);
292 CI_DECLARE_FUNC(int) get_encaps_type(const char *buf,int *val,char **endpoint);
293 CI_DECLARE_FUNC(int)  sizeofencaps(ci_encaps_entity_t *e);
294 
295 #ifdef __CI_COMPAT
296 #define ci_headers_make ci_header_create
297 #endif
298 
299 #ifdef __cplusplus
300 }
301 #endif
302 
303 #endif
304