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 __SIMPLE_API_H
22 #define __SIMPLE_API_H
23 
24 #include "c-icap.h"
25 #include "request.h"
26 
27 #ifdef __cplusplus
28 extern "C"
29 {
30 #endif
31 
32 /**
33  \defgroup HTTP API for HTTP object manipulation
34  \ingroup API
35  * Macros, functions and structures used for manipulating the encupsulated
36  * HTTP objects (HTTP requests or HTTP responses).
37  */
38 
39 /**
40  \defgroup UTILITY utility funtions
41  \ingroup API
42  * Utility functions
43  */
44 
45 /*The following defines are request related and should be moved to request.h include file*/
46 /**
47  \def ci_req_lock_data(ci_request_t)
48  \ingroup REQUEST
49  * Lock a ci_request_t object. After called the c-icap server stops sending
50  * body data to the ICAP client.
51  \param req is pointer to an object of type ci_request_t
52  */
53 #define ci_req_lock_data(req) ((req)->data_locked = 1)
54 
55 /**
56  \def ci_req_unlock_data(ci_request_t)
57  \ingroup REQUEST
58  * Unlock a ci_request_t object. When called the c-icap server will start
59  * sending body data to the ICAP client.
60  \param req is pointer to an object of type ci_request_t
61  */
62 #define ci_req_unlock_data(req) ((req)->data_locked = 0)
63 
64 /**
65  \def ci_req_hasbody(ci_request_t)
66  \ingroup REQUEST
67  \param req  is pointer to an object of type ci_request_t
68  \return true (non zero int) if the ICAP request contains body data else zero
69  */
70 #define ci_req_hasbody(req) ((req)->hasbody)
71 
72 /**
73  \def ci_req_type(ci_request_t)
74  \ingroup REQUEST
75  \return  ICAP_OPTIONS, ICAP_REQMOD or ICAP_RESPMOD if the ICAP request is
76  * options, request modification or response modification ICAP request
77  */
78 #define ci_req_type(req) ((req)->type)
79 
80 /**
81  \def ci_req_preview_size(ci_request_t)
82  \ingroup REQUEST
83  \param req  is pointer to an object of type ci_request_t
84  \return The ICAP preview size
85  */
86 #define ci_req_preview_size(req) ((req)->preview) /*The preview data size*/
87 
88 /**
89  \def ci_req_allow204(ci_request_t)
90  \ingroup REQUEST
91  \param req  is pointer to an object of type ci_request_t
92  \return True (non zero int) if the ICAP request supports "Allow 204"
93  */
94 #define ci_req_allow204(req) ((req)->allow204)
95 
96 /**
97  \def ci_req_allow206(ci_request_t)
98  \ingroup REQUEST
99  \param req  is pointer to an object of type ci_request_t
100  \return True (non zero int) if the ICAP request supports "Allow 206"
101  */
102 #define ci_req_allow206(req) ((req)->allow206)
103 
104 /**
105  \def ci_req_allow206_outside_preview(ci_request_t)
106  \ingroup REQUEST
107  \param req  is pointer to an object of type ci_request_t
108  \return True (non zero int) if the ICAP request supports "Allow 206" outside
109  *       preview requests
110  */
111 #define ci_req_allow206_outside_preview(req) ((req)->allow206 && (req)->allow204)
112 
113 
114 /**
115  \def ci_req_sent_data(ci_request_t)
116  \ingroup REQUEST
117  \param req  is pointer to an object of type ci_request_t
118  \return True (non zero int) if the c-icap server has send data to the client
119  */
120 #define ci_req_sent_data(req)((req)->status)
121 
122 /**
123  \def ci_req_hasalldata(ci_request_t)
124  \ingroup REQUEST
125  \param req is pointer to an object of type ci_request_t
126  \return True (non zero int) if the ICAP client has sent all the data
127  *       (headers and body data) to the ICAP server
128  */
129 #define ci_req_hasalldata(req)((req)->eof_received)
130 
131 /**
132  * Decodes a base64 encoded string.
133  \ingroup UTILITY
134  *
135  \param str   is a buffer which holds the base64 encoded data
136  \param result    is a buffer where the decoded data will be stored
137  \param len    is the length of the result buffer
138  \return the number of decoded bytes
139  */
140 CI_DECLARE_FUNC(int) ci_base64_decode(const char *str,char *result,int len);
141 
142 /**
143  * Produces a base64 encoded string.
144  \ingroup UTILITY
145  *
146  \param data   is a buffer which holds the data to be encoded
147  \param datalen    is the length of the data buffer
148  \param out    is a buffer where the encoded data will be stored
149  \param outlen    is the length of the out buffer
150  \return the number of decoded bytes
151  */
152 CI_DECLARE_FUNC(int) ci_base64_encode(const unsigned char *data, size_t datalen, char *out, size_t outlen);
153 
154 enum {
155     CI_ENCODE_UNKNOWN = -1,
156     CI_ENCODE_NONE = 0,
157     CI_ENCODE_GZIP,
158     CI_ENCODE_DEFLATE,
159     CI_ENCODE_BZIP2,
160     CI_ENCODE_BROTLI
161 };
162 
163 /**
164  * Return the encoding method integer representation from string.
165  \ingroup UTILITY
166  *
167  \param content_encoding The content encoding name
168  \return the CI_ENCODE_* representation
169 */
170 CI_DECLARE_FUNC(int) ci_encoding_method(const char *content_encoding);
171 
172 /**
173  * Uncompress a zipped string.
174  \ingroup UTILITY
175  *
176  \param compress_method CI_ENCODE_GZIP, CI_ENCODED_DEFLATE or CI_CI_ENCODE_BZIP2
177  \param buf   is a buffer which holds the zipped data
178  \param len is the length of the buffer buf
179  \param unzipped_buf  is the buffer where to store unzipped data
180  \param unzipped_buf_len  is the length of the buffer to store unzipped data,
181  *      and updated with the length of unzipped data
182  \return CI_OK on success CI_ERROR on error
183  */
184 CI_DECLARE_FUNC(int) ci_uncompress_preview(int compress_method, const char *buf, int len, char *unzipped_buf, int *unzipped_buf_len);
185 
186 enum CI_UNCOMPRESS_ERRORS {
187     CI_UNCOMP_ERR_BOMB = -4,
188     CI_UNCOMP_ERR_CORRUPT = -3,
189     CI_UNCOMP_ERR_OUTPUT = -2,
190     CI_UNCOMP_ERR_ERROR = -1,
191     CI_UNCOMP_ERR_NONE = 0,
192     CI_UNCOMP_OK = 1,
193 };
194 
195 enum CI_COMPRESS_ERRORS {
196     CI_COMP_ERR_BOMB = -4,
197     CI_COMP_ERR_CORRUPT = -3,
198     CI_COMP_ERR_OUTPUT = -2,
199     CI_COMP_ERR_ERROR = -1,
200     CI_COMP_ERR_NONE = 0,
201     CI_COMP_OK = 1,
202 };
203 
204 /**
205  * Return a string representation of a decompress error code.
206  \ingroup UTILITY
207  *
208  \param err a CI_UNCOMPRESS_ERRORS error code
209 */
210 CI_DECLARE_FUNC(const char *) ci_decompress_error(int err);
211 
212 /**
213    Deprecated
214  */
215 CI_DECLARE_FUNC(const char *) ci_inflate_error(int err);
216 
217 struct ci_membuf;
218 struct ci_simple_file;
219 
220 /*  Data Decompression core functions */
221 
222 /**
223  * Uncompress any compressed data that c-icap understands and writes the output to the outbuf
224  * object, regardless of algorithm
225  \ingroup UTILITY
226  *
227  \param encoding_format   is the enum for the encoding type
228  \param inbuf   is a buffer which holds the zipped data
229  \param inlen is the length of the buffer buf
230  \param outbuf where to put unzipped data
231  \param max_size if it is greater than zero, the output data limit
232  \return CI_UNCOMP_OK on success, CI_UNCOMP_ERR_NONE, if maxsize exceed, an
233  *       CI_UNCOMPRESS_ERRORS code otherwise
234  */
235 CI_DECLARE_FUNC(int) ci_decompress_to_membuf(int encoding_format, const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
236 
237 /**
238  \ingroup UTILITY
239  \copydoc ci_decompress_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
240  */
241 CI_DECLARE_FUNC(int) ci_decompress_to_simple_file(int encoding_format, const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
242 
243 /**
244  * Uncompress deflate/gzip compressed data and writes the output to the outbuf
245  * object
246  \ingroup UTILITY
247  *
248  \param inbuf   is a buffer which holds the zipped data
249  \param inlen is the length of the buffer buf
250  \param outbuf where to put unzipped data
251  \param max_size if it is greater than zero, the output data limit
252  \return CI_UNCOMP_OK on success, CI_UNCOMP_ERR_NONE, if maxsize exceed, an
253  *       CI_UNCOMPRESS_ERRORS code otherwise
254  */
255 CI_DECLARE_FUNC(int) ci_inflate_to_membuf(const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
256 
257 /**
258  \ingroup UTILITY
259  \copydoc ci_inflate_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
260  */
261 CI_DECLARE_FUNC(int) ci_inflate_to_simple_file(const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
262 
263 /**
264  * Uncompress bzip2 compressed data and writes the output to the outbuf object
265  \ingroup UTILITY
266  *
267  \param inbuf   is a buffer which holds the zipped data
268  \param inlen is the length of the buffer buf
269  \param outbuf where to put unzipped data
270  \param max_size if it is greater than zero, the output data limit
271  \return CI_UNCOMP_OK on success, CI_UNCOMP_ERR_NONE, if maxsize exceed, an
272  *       CI_UNCOMPRESS_ERRORS code otherwise
273  */
274 CI_DECLARE_FUNC(int) ci_bzunzip_to_membuf(const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
275 
276 /**
277  \ingroup UTILITY
278  \copydoc ci_bzunzip_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
279  */
280 CI_DECLARE_FUNC(int) ci_bzunzip_to_simple_file(const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
281 
282 /**
283  * Uncompress brotli compressed data and writes the output to the outbuf object
284  \ingroup UTILITY
285  *
286  \param inbuf   is a buffer which holds the zipped data
287  \param inlen is the length of the buffer buf
288  \param outbuf where to put unzipped data
289  \param max_size if it is greater than zero, the output data limit
290  \return CI_UNCOMP_OK on success, CI_UNCOMP_ERR_NONE, if maxsize exceed, an
291  *       CI_UNCOMPRESS_ERRORS code otherwise
292  */
293 CI_DECLARE_FUNC(int) ci_brinflate_to_membuf(const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
294 
295 /**
296  \ingroup UTILITY
297  \copydoc ci_brinflate_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
298  */
299 CI_DECLARE_FUNC(int) ci_brinflate_to_simple_file(const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
300 
301 /*  Data Compression core functions */
302 
303 /**
304  * Compress any uncompressed data that c-icap understands and writes the output to the outbuf
305  * object, regardless of algorithm
306  \ingroup UTILITY
307  *
308  \param encoding_format   is the enum for the encoding type
309  \param inbuf   is a buffer which holds the unzipped data
310  \param inlen is the length of the buffer buf
311  \param outbuf where to put zipped data
312  \param max_size if it is greater than zero, the output data limit
313  \return CI_COMP_OK on success, CI_COMP_ERR_NONE, if maxsize exceed, an
314  *       CI_COMPRESS_ERRORS code otherwise
315  */
316 CI_DECLARE_FUNC(int) ci_compress_to_membuf(int encoding_format, const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
317 
318 /**
319  \ingroup UTILITY
320  \copydoc ci_compress_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
321  */
322 CI_DECLARE_FUNC(int) ci_compress_to_simple_file(int encoding_format, const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
323 
324 /**
325  * Compress deflate uncompressed data and writes the output to the outbuf
326  * object
327  \ingroup UTILITY
328  *
329  \param inbuf   is a buffer which holds the unzipped data
330  \param inlen is the length of the buffer buf
331  \param outbuf where to put zipped data
332  \param max_size if it is greater than zero, the output data limit
333  \return CI_COMP_OK on success, CI_COMP_ERR_NONE, if maxsize exceed, an
334  *       CI_COMPRESS_ERRORS code otherwise
335  */
336 CI_DECLARE_FUNC(int) ci_deflate_to_membuf(const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
337 
338 /**
339  \ingroup UTILITY
340  \copydoc ci_deflate_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
341  */
342 CI_DECLARE_FUNC(int) ci_deflate_to_simple_file(const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
343 
344 /**
345  * Compress gzip uncompressed data and writes the output to the outbuf
346  * object
347  \ingroup UTILITY
348  *
349  \param inbuf   is a buffer which holds the unzipped data
350  \param inlen is the length of the buffer buf
351  \param outbuf where to put zipped data
352  \param max_size if it is greater than zero, the output data limit
353  \return CI_COMP_OK on success, CI_COMP_ERR_NONE, if maxsize exceed, an
354  *       CI_COMPRESS_ERRORS code otherwise
355  */
356 CI_DECLARE_FUNC(int) ci_gzip_to_membuf(const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
357 
358 /**
359  \ingroup UTILITY
360  \copydoc ci_deflate_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
361  */
362 CI_DECLARE_FUNC(int) ci_gzip_to_simple_file(const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
363 
364 /**
365  * Compress bzip2 uncompressed data and writes the output to the outbuf object
366  \ingroup UTILITY
367  *
368  \param inbuf   is a buffer which holds the unzipped data
369  \param inlen is the length of the buffer buf
370  \param outbuf where to put zipped data
371  \param max_size if it is greater than zero, the output data limit
372  \return CI_COMP_OK on success, CI_COMP_ERR_NONE, if maxsize exceed, an
373  *       CI_COMPRESS_ERRORS code otherwise
374  */
375 CI_DECLARE_FUNC(int) ci_bzzip_to_membuf(const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
376 
377 /**
378  \ingroup UTILITY
379  \copydoc ci_bzzip_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
380  */
381 CI_DECLARE_FUNC(int) ci_bzzip_to_simple_file(const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
382 
383 /**
384  * Compress brotli uncompressed data and writes the output to the outbuf object
385  \ingroup UTILITY
386  *
387  \param inbuf   is a buffer which holds the unzipped data
388  \param inlen is the length of the buffer buf
389  \param outbuf where to put zipped data
390  \param max_size if it is greater than zero, the output data limit
391  \return CI_COMP_OK on success, CI_COMP_ERR_NONE, if maxsize exceed, an
392  *       CI_COMPRESS_ERRORS code otherwise
393  */
394 CI_DECLARE_FUNC(int) ci_brdeflate_to_membuf(const char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size);
395 
396 /**
397  \ingroup UTILITY
398  \copydoc ci_brdeflate_to_membuf(char *inbuf, size_t inlen, struct ci_membuf *outbuf, ci_off_t max_size)
399  */
400 CI_DECLARE_FUNC(int) ci_brdeflate_to_simple_file(const char *inbuf, size_t inlen, struct ci_simple_file *outbuf, ci_off_t max_size);
401 
402 /**
403  * Decodes a base64 encoded string, and also allocate memory for the result.
404  \ingroup UTILITY
405  *
406  \param str is a buffer which holds the base64 encoded data
407  \return a pointer to the decoded string. It uses malloc to allocate space for
408  *       the decoded string so the free function should used to release the
409  *       allocated memory.
410  */
411 CI_DECLARE_FUNC(char *) ci_base64_decode_dup(const char *str);
412 
413 /**
414  */
415 /**
416  * Returns the HTTP response headers.
417  \ingroup HTTP
418  *
419  * This function is only valid for an ICAP responce modification request. If
420  * the ICAP request is not responce modification ICAP request or there are
421  * not response headers (HTTP 0.9) the function returns NULL.
422  \param req A pointer to the current ICAP request object.
423  \return Pointer to the HTTP response headers or NULL.
424  */
425 CI_DECLARE_FUNC(ci_headers_list_t *) ci_http_response_headers(ci_request_t *req);
426 
427 /**
428  \ingroup HTTP
429  \brief Returns the HTTP request headers.
430  *
431  * This function can used for an responce or request modification ICAP request
432  * to get the HTTP request headers
433  \param req is a pointer to the current ICAP request object.
434  \return Pointer to the HTTP request headers or NULL if fails.
435  */
436 CI_DECLARE_FUNC(ci_headers_list_t *) ci_http_request_headers(ci_request_t *req);
437 
438 /**
439  \ingroup HTTP
440  \brief Add a custom header to the HTTP response headers.
441  *
442  * This function can used to add custom headers to the HTTP response and can
443  * be used only for response modification ICAP requests
444  \param req is a pointer to the current ICAP request object.
445  \param header is a string contains the header in the form "Header: value"
446  \return Pointer to the header or NULL if fails.
447  */
448 CI_DECLARE_FUNC(const char *) ci_http_response_add_header(ci_request_t *req, const char *header);
449 
450 /**
451  \ingroup HTTP
452  \brief Add a custom header to the HTTP request headers.
453  *
454  * This function can used to add custom headers to the HTTP request and can be
455  * used only for request modification ICAP requests
456  \param req is a pointer to the current ICAP request object.
457  \param header is a string contains the header in the form "Header: value"
458  \return Pointer to the header or NULL if fails.
459  */
460 CI_DECLARE_FUNC(const char *) ci_http_request_add_header(ci_request_t *req, const char *header);
461 
462 /**
463  \ingroup HTTP
464  \brief Remove a header from the HTTP response headers.
465  *
466  * This function can used to remove a header from the HTTP response and can be
467  * used only for response modification ICAP requests
468  \param req is a pointer to the current ICAP request object.
469  \param header is a string contains the header name
470  \return Non zero if success or zero otherwise
471  */
472 CI_DECLARE_FUNC(int) ci_http_response_remove_header(ci_request_t *req, const char *header);
473 
474 /**
475  \ingroup HTTP
476  \brief Remove a header from the HTTP request headers.
477  *
478  * This function can used to remove a header from the HTTP request and can be
479  * used only for request modification ICAP requests
480  \param req is a pointer to the current ICAP request object.
481  \param header is a string contains the header name
482  \return Non zero if success or zero otherwise
483  */
484 CI_DECLARE_FUNC(int) ci_http_request_remove_header(ci_request_t *req, const char *header);
485 
486 /**
487  \ingroup HTTP
488  \brief Get the value of the requested header from the HTTP response headers.
489  *
490  * This function can used to get the value of a header from the HTTP response
491  * headers. It can be used only for response modification ICAP requests
492  \param req is a pointer to the current ICAP request object.
493  \param head_name is a string contains the header name
494  \return A string with the header value on success NULL otherwise
495  */
496 CI_DECLARE_FUNC(const char *) ci_http_response_get_header(ci_request_t *req, const char *head_name);
497 
498 /**
499  \ingroup HTTP
500  \brief Get the value of the requested header from the HTTP request headers.
501  *
502  * This function can used to get the value of a header from the HTTP request
503  * headers. It can be used on both request and response modification ICAP
504  * requests.
505  \param req is a pointer to the current ICAP request object.
506  \param head_name is a string contains the header name
507  \return A string with the header value on success NULL otherwise
508  */
509 CI_DECLARE_FUNC(const char *) ci_http_request_get_header(ci_request_t *req, const char *head_name);
510 
511 /**
512  \ingroup HTTP
513  \brief Completelly erase and initialize the  HTTP response headers.
514  *
515  * This function is usefull when the full rewrite of the HTTP response is
516  * required. After this function called, the HTTP response should be filled
517  * with new HTTP headers, before send back to the ICAP client.
518  * An example of usage of this function is in antivirus service when a
519  * virus detected in HTTP response, so the service blocks the response and
520  * sends a new HTTP object (a new html page, with HTTP headers) informing
521  * the user about the virus.
522  * It can be used with response modification ICAP requests.
523  \param req is a pointer to the current ICAP request object.
524  \return non zero on success zero otherwise
525  */
526 CI_DECLARE_FUNC(int) ci_http_response_reset_headers(ci_request_t *req);
527 
528 /**
529  \ingroup HTTP
530  \brief Completelly erase and initialize the  HTTP request headers.
531  *
532  * This function is usefull when an HTTP request required should replaced by
533  * an other.After this function called, the HTTP request should filled with
534  * new HTTP headers, before send back to the ICAP client.
535  * An example use is to implement an HTTP redirector.
536  * It can be used with request modification ICAP requests.
537  \param req is a pointer to the current ICAP request object.
538  \return non zero on success zero otherwise
539  */
540 CI_DECLARE_FUNC(int) ci_http_request_reset_headers(ci_request_t *req);
541 
542 /**
543  \ingroup HTTP
544  \brief Creates a new HTTP response.
545  *
546  * This function is usefull when the service wants to respond with a self
547  * created message to a response or request modification ICAP request.
548  * It can be used with both request and response modification ICAP requests.
549  \param req is a pointer to the current ICAP request object.
550  \param has_reshdr if it is non zero the HTTP response contrains HTTP headers
551  *      (a non HTTP 0.9 response)
552  \param has_body if it is non zero the HTTP response contains HTTP body data
553  \return non zero on success zero otherwise
554  */
555 CI_DECLARE_FUNC(int) ci_http_response_create(ci_request_t *req, int has_reshdr, int has_body);
556 
557 /**
558  \ingroup HTTP
559  \brief Creates a new HTTP request.
560  *
561  * This function is usefull to develop icap clients
562  \param req is a pointer to the current ICAP request object.
563  \param has_body if it is non zero the HTTP request contains HTTP body data
564  \return non zero on success zero otherwise
565  */
566 CI_DECLARE_FUNC(int) ci_http_request_create(ci_request_t *req, int has_body);
567 
568 /**
569  \ingroup HTTP
570  \brief Returns the value of the Content-Length header of the HTTP response
571  *      or HTTP request for a response modification or request modification ICAP
572  *      requests respectively.
573  *
574  * If the header Content-Length is not included in HTTP response
575  * It can be used with both request and response modification ICAP requests.
576  \param req is a pointer to the current ICAP request object.
577  \return The content length on success or a negative number otherwise
578  */
579 CI_DECLARE_FUNC(ci_off_t) ci_http_content_length(ci_request_t *req);
580 
581 /**
582  * Return the encoding method integer representation from string.
583  \ingroup UTILITY
584  *
585  \param req is a pointer to the current ICAP request object.
586  \return the content encoding, CI_ENCODE_NONE for no encoding or CI_ENCODE_UNKNOWN for non RESPMOD ICAP requests
587 */
588 CI_DECLARE_FUNC(int) ci_http_response_content_encoding(ci_request_t *req);
589 
590 /**
591  \ingroup HTTP
592  \brief Returns the request line (e.g "GET /index.html HTTP 1.0") from http
593  *      request headers
594  *
595  * It can be used with both request and response modification ICAP requests.
596  \param req is a pointer to the current ICAP request object.
597  \return The request line in success or NULL otherwise
598  */
599 CI_DECLARE_FUNC(const char *) ci_http_request(ci_request_t *req);
600 
601 /**
602  \ingroup HTTP
603  \brief Returns the URL (e.g "http://www.chtsanti.net") from http request
604  *
605  * It can be used with both request and response modification ICAP requests.
606  \param req is a pointer to the current ICAP request object.
607  \param buf a buffer to store the url
608  \param buf_size the "buf" buffer size
609  \return The bytes written to the "buf" buffer
610  */
611 CI_DECLARE_FUNC(int) ci_http_request_url(ci_request_t * req, char *buf, int buf_size);
612 
613 /**
614  \ingroup HTTP
615  \brief Return the http client ip address if this information is available
616  \param req is a pointer to the current ICAP request object.
617  \return A const pointer to a ci_ip_t object contain the client ip address
618  *       or NULL
619  */
620 CI_DECLARE_FUNC(const ci_ip_t *) ci_http_client_ip(ci_request_t * req);
621 
622 /**
623  \ingroup REQUEST
624  \brief Add an icap X-header to the icap response headers
625  *
626  * It can be used with both request and response modification ICAP requests.
627  \param req is a pointer to the current ICAP request object.
628  \param header is the header to add in the form "Header: Value"
629  \return pointer to the header in success or NULL otherwise
630  */
631 CI_DECLARE_FUNC(const char *) ci_icap_add_xheader(ci_request_t *req, const char *header);
632 
633 /**
634  \ingroup REQUEST
635  \brief Append the icap X-headers to the icap response headers
636  *
637  * It can be used with both request and response modification ICAP requests.
638  \param req is a pointer to the current ICAP request object.
639  \param headers is a pointer to the headers object to add
640  \return pointer to the header in success or NULL otherwise
641  */
642 CI_DECLARE_FUNC(int) ci_icap_append_xheaders(ci_request_t *req, ci_headers_list_t *headers);
643 
644 
645 #ifdef __CI_COMPAT
646 #define ci_respmod_headers           ci_http_response_headers
647 #define ci_reqmod_headers            ci_http_request_headers
648 #define ci_respmod_add_header        ci_http_response_add_header
649 #define ci_reqmod_add_header         ci_http_request_add_header
650 #define ci_respmod_remove_header     ci_http_response_remove_header
651 #define ci_reqmod_remove_header      ci_http_request_remove_header
652 #define ci_respmod_get_header        ci_http_response_get_header
653 #define ci_reqmod_get_header         ci_http_request_get_header
654 #define ci_respmod_reset_headers     ci_http_response_reset_headers
655 #define ci_reqmod_reset_headers      ci_http_request_reset_headers
656 #define ci_request_create_respmod    ci_http_response_create
657 #define ci_content_lenght            ci_http_content_length
658 #define ci_request_add_xheader       ci_icap_add_xheader
659 #endif
660 
661 #ifdef __cplusplus
662 }
663 #endif
664 
665 #endif
666 
667