]> granicus.if.org Git - apache/blob - include/util_filter.h
Add a couple of GCC attribute tags to printf style functions. This also
[apache] / include / util_filter.h
1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  *    if any, must include the following acknowledgment:
21  *       "This product includes software developed by the
22  *        Apache Software Foundation (http://www.apache.org/)."
23  *    Alternately, this acknowledgment may appear in the software itself,
24  *    if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Apache" and "Apache Software Foundation" must
27  *    not be used to endorse or promote products derived from this
28  *    software without prior written permission. For written
29  *    permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache",
32  *    nor may "Apache" appear in their name, without prior written
33  *    permission of the Apache Software Foundation.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation.  For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  */
54
55 #ifndef AP_FILTER_H
56 #define AP_FILTER_H
57
58 #include "apr.h"
59 #include "apr_buckets.h"
60
61 #include "httpd.h"
62
63 #if APR_HAVE_STDARG_H
64 #include <stdarg.h>
65 #endif
66
67 #ifdef __cplusplus
68 extern "C" {
69 #endif
70
71 /**
72  * @package Apache filter library
73  */
74
75 #define AP_NOBODY_WROTE         -1
76 #define AP_NOBODY_READ          -2
77 #define AP_FILTER_ERROR         -3
78
79 /**
80  * @heading ap_input_mode_t - input filtering modes 
81  * 
82  * AP_MODE_BLOCKING
83  *
84  *   The filter shouldn't return until data is received or EOF is hit
85  *   or an error occurs.
86  *
87  * AP_MODE_NONBLOCKING
88  *
89  *   The filter should process any available data/status as normal,
90  *   but will not wait for additional data.
91  *
92  * AP_MODE_PEEK
93  *
94  *   The filter should return APR_SUCCESS if data is available or
95  *   APR_EOF otherwise.  The filter must not return any buckets of
96  *   data.  Data returned on a subsequent call, when mode is
97  *   AP_MODE_BLOCKING or AP_MODE_NONBLOCKING.
98  */
99 typedef enum {
100     AP_MODE_BLOCKING,
101     AP_MODE_NONBLOCKING,
102     AP_MODE_PEEK
103 } ap_input_mode_t;
104
105 /*
106  * FILTER CHAIN
107  *
108  * Filters operate using a "chaining" mechanism. The filters are chained
109  * together into a sequence. When output is generated, it is passed through
110  * each of the filters on this chain, until it reaches the end (or "bottom")
111  * and is placed onto the network.
112  *
113  * The top of the chain, the code generating the output, is typically called
114  * a "content generator." The content generator's output is fed into the
115  * filter chain using the standard Apache output mechanisms: ap_rputs(),
116  * ap_rprintf(), ap_rwrite(), etc.
117  *
118  * Each filter is defined by a callback. This callback takes the output from
119  * the previous filter (or the content generator if there is no previous
120  * filter), operates on it, and passes the result to the next filter in the
121  * chain. This pass-off is performed using the ap_fc_* functions, such as
122  * ap_fc_puts(), ap_fc_printf(), ap_fc_write(), etc.
123  *
124  * When content generation is complete, the system will pass an "end of
125  * stream" marker into the filter chain. The filters will use this to flush
126  * out any internal state and to detect incomplete syntax (for example, an
127  * unterminated SSI directive).
128  */
129
130 /* forward declare the filter type */
131 typedef struct ap_filter_t ap_filter_t;
132
133 /*
134  * ap_filter_func:
135  *
136  * This function type is used for filter callbacks. It will be passed a
137  * pointer to "this" filter, and a "bucket" containing the content to be
138  * filtered.
139  *
140  * In filter->ctx, the callback will find its context. This context is
141  * provided here, so that a filter may be installed multiple times, each
142  * receiving its own per-install context pointer.
143  *
144  * Callbacks are associated with a filter definition, which is specified
145  * by name. See ap_register_input_filter() and ap_register_output_filter()
146  * for setting the association between a name for a filter and its 
147  * associated callback (and other information).
148  *
149  * The *bucket structure (and all those referenced by ->next and ->prev)
150  * should be considered "const". The filter is allowed to modify the
151  * next/prev to insert/remove/replace elements in the bucket list, but
152  * the types and values of the individual buckets should not be altered.
153  *
154  * The return value of a filter should be an APR status value.
155  */
156 typedef apr_status_t (*ap_out_filter_func)(ap_filter_t *f, apr_bucket_brigade *b);
157 typedef apr_status_t (*ap_in_filter_func)(ap_filter_t *f, apr_bucket_brigade *b, 
158                                           ap_input_mode_t mode);
159 typedef union ap_filter_func {
160     ap_out_filter_func out_func;
161     ap_in_filter_func in_func;
162 } ap_filter_func;
163
164 /**
165  * @heading Filter Types
166  *
167  * ap_filter_type:
168  *
169  * Filters have different types/classifications. These are used to group
170  * and sort the filters to properly sequence their operation.
171  *
172  * AP_FTYPE_CONTENT:
173  *     These filters are used to alter the content that is passed through
174  *     them. Examples are SSI or PHP.
175  *
176  * AP_FTYPE_HTTP_HEADER: (XXX somebody rename me or get rid of me please)
177  *     This special type ensures that the HTTP header filter ends up in
178  *     the proper location in the filter chain.
179  *
180  * AP_FTYPE_TRANSCODE:
181  *     These filters implement transport encodings (e.g., chunking).
182  *
183  * AP_FTYPE_CONNECTION:
184  *     These filters will alter the content, but in ways that are more
185  *     strongly associated with the connection.  Examples are splitting
186  *     an HTTP connection into multiple requests and buffering HTTP
187  *     responses across multiple requests.
188  *
189  *     It is important to note that these types of filters are not allowed
190  *     in a sub-request. A sub-request's output can certainly be filtered
191  *     by AP_FTYPE_CONTENT filters, but all of the "final processing" is
192  *     determined by the main request.
193  *
194  * AP_FTYPE_NETWORK:
195  *     These filters don't alter the content.  They are responsible for
196  *     sending/receiving data to/from the client.
197  *
198  * The types have a particular sort order, which allows us to insert them
199  * into the filter chain in a determistic order. Within a particular grouping,
200  * the ordering is equivalent to the order of calls to ap_add_*_filter().
201  */
202 typedef enum {
203     AP_FTYPE_CONTENT     = 10,
204     AP_FTYPE_HTTP_HEADER = 20,
205     AP_FTYPE_TRANSCODE   = 30,
206     AP_FTYPE_CONNECTION  = 40,
207     AP_FTYPE_NETWORK     = 50
208 } ap_filter_type;
209
210 /*
211  * ap_filter_t:
212  *
213  * This is the request-time context structure for an installed filter (in
214  * the output filter chain). It provides the callback to use for filtering,
215  * the request this filter is associated with (which is important when
216  * an output chain also includes sub-request filters), the context for this
217  * installed filter, and the filter ordering/chaining fields.
218  *
219  * Filter callbacks are free to use ->ctx as they please, to store context
220  * during the filter process. Generally, this is superior over associating
221  * the state directly with the request. A callback should not change any of
222  * the other fields.
223  */
224
225 typedef struct ap_filter_rec_t ap_filter_rec_t;
226
227 /**
228  * This structure is used for recording information about the
229  * registered filters. It associates a name with the filter's callback
230  * and filter type.
231  *
232  * At the moment, these are simply linked in a chain, so a ->next pointer
233  * is available.
234  */
235 struct ap_filter_rec_t {
236     /** The registered name for this filter */
237     const char *name;
238     /** The function to call when this filter is invoked. */
239     ap_filter_func filter_func;
240     /** The type of filter, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION.  
241      * An AP_FTYPE_CONTENT filter modifies the data based on information 
242      * found in the content.  An AP_FTYPE_CONNECTION filter modifies the 
243      * data based on the type of connection.
244      */
245     ap_filter_type ftype;
246
247     /** The next filter_rec in the list */
248     struct ap_filter_rec_t *next;
249 };
250
251 /**
252  * The representation of a filter chain.  Each request has a list
253  * of these structures which are called in turn to filter the data.  Sub
254  * requests get an exact copy of the main requests filter chain.
255  */
256 struct ap_filter_t {
257      /** The internal representation of this filter.  This includes
258       *  the filter's name, type, and the actual function pointer.
259      */
260     ap_filter_rec_t *frec;
261
262     /** A place to store any data associated with the current filter */
263     void *ctx;
264
265     /** The next filter in the chain */
266     ap_filter_t *next;
267
268     /** The request_rec associated with the current filter.  If a sub-request
269      *  adds filters, then the sub-request is the request associated with the
270      *  filter.
271      */
272     request_rec *r;
273
274     /** The conn_rec associated with the current filter.  This is analogous
275      *  to the request_rec, except that it is used for input filtering.
276      */
277     conn_rec *c;
278 };
279
280 /**
281  * Get the current bucket brigade from the next filter on the filter
282  * stack.  The filter should return an apr_status_t value.  If the bottom-most 
283  * filter doesn't write to the network, then AP_NOBODY_READ is returned.
284  * @param filter The next filter in the chain
285  * @param bucket The current bucket brigade
286  * @param mode   AP_MODE_BLOCKING, AP_MODE_NONBLOCKING, or AP_MODE_PEEK
287  * @return apr_status_t value
288  * @deffunc apr_status_t ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, ap_input_mode_t mode)
289  */
290 AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, 
291                                         ap_input_mode_t mode);
292
293 /**
294  * Pass the current bucket brigade down to the next filter on the filter
295  * stack.  The filter should return an apr_status_t value.  If the bottom-most 
296  * filter doesn't write to the network, then AP_NOBODY_WROTE is returned.
297  * @param filter The next filter in the chain
298  * @param bucket The current bucket brigade
299  * @return apr_status_t value
300  * @deffunc apr_status_t ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket)
301  */
302 AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket);
303
304 /**
305  * This function is used to register an input filter with the system. 
306  * After this registration is performed, then a filter may be added 
307  * into the filter chain by using ap_add_input_filter() and simply 
308  * specifying the name.
309  *
310  * @param name The name to attach to the filter function
311  * @param filter_func The filter function to name
312  * @param ftype The type of filter function, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION
313  */
314 AP_DECLARE(void) ap_register_input_filter(const char *name,
315                                           ap_in_filter_func filter_func,
316                                           ap_filter_type ftype);
317 /**
318  * This function is used to register an output filter with the system. 
319  * After this registration is performed, then a filter may be added 
320  * into the filter chain by using ap_add_output_filter() and simply 
321  * specifying the name.
322  *
323  * @param name The name to attach to the filter function
324  * @param filter_func The filter function to name
325  * @param ftype The type of filter function, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION
326  * @see ::ap_add_output_filter
327  */
328 AP_DECLARE(void) ap_register_output_filter(const char *name,
329                                             ap_out_filter_func filter_func,
330                                             ap_filter_type ftype);
331
332 /*
333  * ap_add_filter():
334  *
335  * Adds a named filter into the filter chain on the specified request record.
336  * The filter will be installed with the specified context pointer.
337  *
338  * Filters added in this way will always be placed at the end of the filters
339  * that have the same type (thus, the filters have the same order as the
340  * calls to ap_add_filter). If the current filter chain contains filters
341  * from another request, then this filter will be added before those other
342  * filters.
343  * 
344  * To re-iterate that last comment.  This function is building a FIFO
345  * list of filters.  Take note of that when adding your filter to the chain.
346  */
347 /**
348  * Add a filter to the current connection.  Filters are added in a FIFO manner.
349  * The first filter added will be the first filter called.
350  * @param name The name of the filter to add
351  * @param r The request to add this filter for (or NULL if it isn't associated with a request)
352  * @param c The connection to add the fillter for
353  * @deffunc void ap_add_input_filter(const char *name, void *ctx, request_rec *r, conn_rec *c)
354  */
355 AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
356                                               request_rec *r, conn_rec *c);
357
358 /**
359  * Add a filter to the current request.  Filters are added in a FIFO manner.
360  * The first filter added will be the first filter called.
361  * @param name The name of the filter to add
362  * @param ctx Context data to set in the filter
363  * @param r The request to add this filter for (or NULL if it isn't associated with a request)
364  * @param c The connection to add this filter for
365  * @deffunc void ap_add_output_filter(const char *name, void *ctx, request_rec *r, conn_rec *c)
366  */
367 AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, 
368                                                request_rec *r, conn_rec *c);
369
370 AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f);
371
372 /* The next two filters are for abstraction purposes only.  They could be
373  * done away with, but that would require that we break modules if we ever
374  * want to change our filter registration method.  The basic idea, is that
375  * all filters have a place to store data, the ctx pointer.  These functions
376  * fill out that pointer with a bucket brigade, and retrieve that data on
377  * the next call.  The nice thing about these functions, is that they
378  * automatically concatenate the bucket brigades together for you.  This means
379  * that if you have already stored a brigade in the filters ctx pointer, then
380  * when you add more it will be tacked onto the end of that brigade.  When
381  * you retrieve data, if you pass in a bucket brigade to the get function,
382  * it will append the current brigade onto the one that you are retrieving.
383  */
384
385 /**
386  * prepare a bucket brigade to be setaside.  If a different brigade was 
387  * set-aside earlier, then the two brigades are concatenated together.
388  * @param f The current filter
389  * @param save_to The brigade that was previously set-aside.  Regardless, the
390  *             new bucket brigade is returned in this location.
391  * @param b The bucket brigade to save aside.  This brigade is always empty
392  *          on return
393  * @deffunc apr_status_t ap_save_brigade(ap_filter_t *f, apr_bucket_brigade **save_to, apr_bucket_brigade **b)
394  */
395 AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f, apr_bucket_brigade **save_to,
396                                          apr_bucket_brigade **b);    
397
398 /**
399  * Flush function for apr_brigade_* calls.  This calls ap_pass_brigade
400  * to flush the brigade if the brigade buffer overflows.
401  * @param bb The brigade to flush
402  * @param ctx The filter to pass the brigade to
403  * @deffunc apr_status_t ap_filter_flush(apr_bucket_brigade *bb, void *ctx)
404  */
405 AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb, void *ctx);
406
407 /**
408  * Flush the current brigade down the filter stack
409  * @param f the next filter in the stack
410  * @param bb The brigade to flush
411  * @deffunc apr_status_t ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb)
412  */
413 AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb);
414
415 /**
416  * Write a buffer for the current filter, buffering if possible.
417  * @param f the filter doing the writing
418  * @param bb The brigade to buffer into
419  * @param data The data to write
420  * @param nbyte The number of bytes in the data
421  * @deffunc int ap_fwrite(ap_filter_t *f, apr_bucket_brigade *bb, const char *data, apr_ssize_t nbyte)
422  */
423 #define ap_fwrite(f, bb, data, nbyte) \
424         apr_brigade_write(bb, ap_filter_flush, (f)->next, data, nbyte)
425
426 /**
427  * Write a buffer for the current filter, buffering if possible.
428  * @param f the filter doing the writing
429  * @param bb The brigade to buffer into
430  * @param str The string to write
431  * @deffunc int ap_fputs(ap_filter_t *f, apr_bucket_brigade *bb, const char *str)
432  */
433 #define ap_fputs(f, bb, str) \
434         apr_brigade_puts(bb, ap_filter_flush, (f)->next, str)
435
436 /**
437  * Write a character for the current filter, buffering if possible.
438  * @param f the filter doing the writing
439  * @param bb The brigade to buffer into
440  * @param c The character to write
441  * @deffunc int ap_fputc(ap_filter_t *f, apr_bucket_brigade *bb, char c)
442  */
443 #define ap_fputc(f, bb, c) \
444         apr_brigade_putc(bb, ap_filter_flush, (f)->next, c)
445
446 /**
447  * Write an unspecified number of strings to the current filter
448  * @param f the filter doing the writing
449  * @param bb The brigade to buffer into
450  * @param ... The strings to write
451  * @deffunc int ap_fputstrs(ap_filter_t *f, apr_bucket_brigade *bb, ...)
452  */
453 AP_DECLARE_NONSTD(int) ap_fputstrs(ap_filter_t *f, apr_bucket_brigade *bb, ...);
454
455 /**
456  * Output data to the filter in printf format
457  * @param f the filter doing the writing
458  * @param bb The brigade to buffer into
459  * @param fmt The format string
460  * @param ... The argumets to use to fill out the format string
461  * @deffunc int ap_fprintf(ap_filter_t *f, apr_bucket_brigade *bb, const char *fmt, ...)
462  */
463 AP_DECLARE_NONSTD(int) ap_fprintf(ap_filter_t *f, apr_bucket_brigade *bb, const char *fmt, ...)
464         __attribute__((format(printf,3,4)));                                    
465
466 #ifdef __cplusplus
467 }
468 #endif
469
470 #endif  /* !AP_FILTER_H */