]> granicus.if.org Git - apache/blob - modules/filters/mod_include.h
15a3b7b61e2adc6f56542900ade047823df6dcc7
[apache] / modules / filters / mod_include.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  * Portions of this software are based upon public domain software
55  * originally written at the National Center for Supercomputing Applications,
56  * University of Illinois, Urbana-Champaign.
57  */
58
59 #ifndef _MOD_INCLUDE_H
60 #define _MOD_INCLUDE_H 1
61
62 #define STARTING_SEQUENCE "<!--#"
63 #define ENDING_SEQUENCE "-->"
64
65 #define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"
66 #define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z"
67 #define SIZEFMT_BYTES 0
68 #define SIZEFMT_KMG 1
69 #define TMP_BUF_SIZE 1024
70 #if APR_CHARSET_EBCDIC
71 #define RAW_ASCII_CHAR(ch)  apr_xlate_conv_byte(ap_hdrs_from_ascii, (unsigned char)ch)
72 #else /*APR_CHARSET_EBCDIC*/
73 #define RAW_ASCII_CHAR(ch)  (ch)
74 #endif /*APR_CHARSET_EBCDIC*/
75
76 /* just need some arbitrary non-NULL pointer which can't also be a request_rec */
77 #define NESTED_INCLUDE_MAGIC    (&include_module)
78
79 /****************************************************************************
80  * Used to keep context information during parsing of a request for SSI tags.
81  * This is especially useful if the tag stretches across multiple buckets or
82  * brigades. This keeps track of which buckets need to be replaced with the
83  * content generated by the SSI tag.
84  *
85  * state: PRE_HEAD - State prior to finding the first character of the 
86  *                   STARTING_SEQUENCE. Next state is PARSE_HEAD.
87  *        PARSE_HEAD - State entered once the first character of the
88  *                     STARTING_SEQUENCE is found and exited when the
89  *                     the full STARTING_SEQUENCE has been matched or
90  *                     a match failure occurs. Next state is PRE_HEAD
91  *                     or PARSE_TAG.
92  *        PARSE_TAG - State entered once the STARTING sequence has been
93  *                    matched. It is exited when the first character in
94  *                    ENDING_SEQUENCE is found. Next state is PARSE_TAIL.
95  *        PARSE_TAIL - State entered from PARSE_TAG state when the first
96  *                     character in ENDING_SEQUENCE is encountered. This
97  *                     state is exited when the ENDING_SEQUENCE has been
98  *                     completely matched, or when a match failure occurs.
99  *                     Next state is PARSE_TAG or PARSED.
100  *        PARSED - State entered from PARSE_TAIL once the complete 
101  *                 ENDING_SEQUENCE has been matched. The SSI tag is
102  *                 processed and the SSI buckets are replaced with the
103  *                 SSI content during this state.
104  * parse_pos: Current matched position within the STARTING_SEQUENCE or
105  *            ENDING_SEQUENCE during the PARSE_HEAD and PARSE_TAIL states.
106  *            This is especially useful when the sequence spans brigades.
107  * X_start_bucket: These point to the buckets containing the first character
108  *                 of the STARTING_SEQUENCE, the first non-whitespace
109  *                 character of the tag, and the first character in the
110  *                 ENDING_SEQUENCE (head_, tag_, and tail_ respectively).
111  *                 The buckets are kept intact until the PARSED state is
112  *                 reached, at which time the tag is consolidated and the
113  *                 buckets are released. The buckets that these point to
114  *                 have all been set aside in the ssi_tag_brigade (along
115  *                 with all of the intervening buckets).
116  * X_start_index: The index points within the specified bucket contents
117  *                where the first character of the STARTING_SEQUENCE,
118  *                the first non-whitespace character of the tag, and the
119  *                first character in the ENDING_SEQUENCE can be found
120  *                (head_, tag_, and tail_ respectively).
121  * combined_tag: Once the PARSED state is reached the tag is collected from
122  *               the bucket(s) in the ssi_tag_brigade into this contiguous
123  *               buffer. The buckets in the ssi_tag_brigade are released
124  *               and the tag is processed.
125  * curr_tag_pos: Ptr to the combined_tag buffer indicating the current
126  *               parse position.
127  * tag_length: The number of bytes in the actual tag (excluding the
128  *             STARTING_SEQUENCE, leading and trailing whitespace,
129  *             and ENDING_SEQUENCE). This length is computed as the
130  *             buckets are parsed and set aside during the PARSE_TAG state.
131  * ssi_tag_brigade: The temporary brigade used by this filter to set aside
132  *                  the buckets containing parts of the ssi tag and headers.
133  */
134 typedef enum {PRE_HEAD, PARSE_HEAD, PARSE_DIRECTIVE, PARSE_TAG, PARSE_TAIL, PARSED} states;
135 typedef struct include_filter_ctx {
136     states       state;
137     long         flags;    /* See the FLAG_XXXXX definitions. */
138     int          if_nesting_level;
139     apr_size_t   parse_pos;
140     int          bytes_parsed;
141     
142     apr_bucket   *head_start_bucket;
143     apr_size_t   head_start_index;
144
145     apr_bucket   *tag_start_bucket;
146     apr_size_t   tag_start_index;
147
148     apr_bucket   *tail_start_bucket;
149     apr_size_t   tail_start_index;
150
151     char        *combined_tag;
152     char        *curr_tag_pos;
153     apr_size_t   directive_length;
154     apr_size_t   tag_length;
155
156     apr_size_t   error_length;
157     char         error_str[MAX_STRING_LEN];
158     char         time_str[MAX_STRING_LEN];
159
160     apr_bucket_brigade *ssi_tag_brigade;
161 } include_ctx_t;
162
163 /* These flags are used to set flag bits. */
164 #define FLAG_PRINTING         0x00000001  /* Printing conditional lines. */
165 #define FLAG_COND_TRUE        0x00000002  /* Conditional eval'd to true. */
166 #define FLAG_SIZE_IN_BYTES    0x00000004  /* Sizes displayed in bytes.   */
167 #define FLAG_NO_EXEC          0x00000008  /* No Exec in current context. */
168
169 /* These flags are used to clear flag bits. */
170 #define FLAG_SIZE_ABBREV      0xFFFFFFFB  /* Reset SIZE_IN_BYTES bit.    */
171 #define FLAG_CLEAR_PRINT_COND 0xFFFFFFFC  /* Reset PRINTING and COND_TRUE*/
172 #define FLAG_CLEAR_PRINTING   0xFFFFFFFE  /* Reset just PRINTING bit.    */
173
174 #define CREATE_ERROR_BUCKET(cntx, t_buck, h_ptr, ins_head)        \
175 {                                                                 \
176     apr_size_t e_wrt;                                             \
177     t_buck = apr_bucket_heap_create(cntx->error_str,              \
178                                   cntx->error_length, 1, &e_wrt); \
179     APR_BUCKET_INSERT_BEFORE(h_ptr, t_buck);                      \
180                                                                   \
181     if (ins_head == NULL) {                                       \
182         ins_head = t_buck;                                        \
183     }                                                             \
184 }
185
186 #define SPLIT_AND_PASS_PRETAG_BUCKETS(brgd, cntxt, next)          \
187 if ((APR_BRIGADE_EMPTY(cntxt->ssi_tag_brigade)) &&                \
188     (cntxt->head_start_bucket != NULL)) {                         \
189     apr_bucket_brigade *tag_plus;                                 \
190     int rv;                                                       \
191                                                                   \
192     tag_plus = apr_brigade_split(brgd, cntxt->head_start_bucket); \
193     rv = ap_pass_brigade(next, brgd);                             \
194     if (rv != APR_SUCCESS) {                                      \
195         return rv;                                                \
196     }                                                             \
197     cntxt->bytes_parsed = 0;                                      \
198     brgd = tag_plus;                                              \
199 }
200
201
202 typedef int (include_handler_fn_t)(include_ctx_t *ctx, apr_bucket_brigade **bb,
203                        request_rec *r, ap_filter_t *f, apr_bucket *head_ptr, 
204                        apr_bucket **inserted_head);
205
206 APR_DECLARE_OPTIONAL_FN(void, ap_ssi_get_tag_and_value, (include_ctx_t *ctx,
207                                                         char **tag,
208                                                         char **tag_val,
209                                                         int dodecode));
210 APR_DECLARE_OPTIONAL_FN(void, ap_ssi_parse_string, (request_rec *r,
211                                                     const char *in,
212                                                     char *out,
213                                                     size_t length,
214                                                     int leave_name));
215 APR_DECLARE_OPTIONAL_FN(void, ap_register_include_handler, 
216                         (char *tag, include_handler_fn_t *func));
217
218 #endif /* MOD_INCLUDE */