upload apache
[bottlenecks.git] / rubbos / app / apache2 / include / mod_include.h
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef _MOD_INCLUDE_H
18 #define _MOD_INCLUDE_H 1
19
20 #include "apr_pools.h"
21 #include "apr_optional.h"
22
23 #define STARTING_SEQUENCE "<!--#"
24 #define ENDING_SEQUENCE "-->"
25
26 #define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"
27 #define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z"
28 #define SIZEFMT_BYTES 0
29 #define SIZEFMT_KMG 1
30 #define TMP_BUF_SIZE 1024
31 #if APR_CHARSET_EBCDIC
32 #define RAW_ASCII_CHAR(ch)  apr_xlate_conv_byte(ap_hdrs_from_ascii, (unsigned char)ch)
33 #else /*APR_CHARSET_EBCDIC*/
34 #define RAW_ASCII_CHAR(ch)  (ch)
35 #endif /*APR_CHARSET_EBCDIC*/
36
37 /****************************************************************************
38  * Used to keep context information during parsing of a request for SSI tags.
39  * This is especially useful if the tag stretches across multiple buckets or
40  * brigades. This keeps track of which buckets need to be replaced with the
41  * content generated by the SSI tag.
42  *
43  * state: PRE_HEAD - State prior to finding the first character of the 
44  *                   STARTING_SEQUENCE. Next state is PARSE_HEAD.
45  *        PARSE_HEAD - State entered once the first character of the
46  *                     STARTING_SEQUENCE is found and exited when the
47  *                     the full STARTING_SEQUENCE has been matched or
48  *                     a match failure occurs. Next state is PRE_HEAD
49  *                     or PARSE_TAG.
50  *        PARSE_TAG - State entered once the STARTING sequence has been
51  *                    matched. It is exited when the first character in
52  *                    ENDING_SEQUENCE is found. Next state is PARSE_TAIL.
53  *        PARSE_TAIL - State entered from PARSE_TAG state when the first
54  *                     character in ENDING_SEQUENCE is encountered. This
55  *                     state is exited when the ENDING_SEQUENCE has been
56  *                     completely matched, or when a match failure occurs.
57  *                     Next state is PARSE_TAG or PARSED.
58  *        PARSED - State entered from PARSE_TAIL once the complete 
59  *                 ENDING_SEQUENCE has been matched. The SSI tag is
60  *                 processed and the SSI buckets are replaced with the
61  *                 SSI content during this state.
62  * parse_pos: Current matched position within the STARTING_SEQUENCE or
63  *            ENDING_SEQUENCE during the PARSE_HEAD and PARSE_TAIL states.
64  *            This is especially useful when the sequence spans brigades.
65  * X_start_bucket: These point to the buckets containing the first character
66  *                 of the STARTING_SEQUENCE, the first non-whitespace
67  *                 character of the tag, and the first character in the
68  *                 ENDING_SEQUENCE (head_, tag_, and tail_ respectively).
69  *                 The buckets are kept intact until the PARSED state is
70  *                 reached, at which time the tag is consolidated and the
71  *                 buckets are released. The buckets that these point to
72  *                 have all been set aside in the ssi_tag_brigade (along
73  *                 with all of the intervening buckets).
74  * X_start_index: The index points within the specified bucket contents
75  *                where the first character of the STARTING_SEQUENCE,
76  *                the first non-whitespace character of the tag, and the
77  *                first character in the ENDING_SEQUENCE can be found
78  *                (head_, tag_, and tail_ respectively).
79  * combined_tag: Once the PARSED state is reached the tag is collected from
80  *               the bucket(s) in the ssi_tag_brigade into this contiguous
81  *               buffer. The buckets in the ssi_tag_brigade are released
82  *               and the tag is processed.
83  * curr_tag_pos: Ptr to the combined_tag buffer indicating the current
84  *               parse position.
85  * tag_length: The number of bytes in the actual tag (excluding the
86  *             STARTING_SEQUENCE, leading and trailing whitespace,
87  *             and ENDING_SEQUENCE). This length is computed as the
88  *             buckets are parsed and set aside during the PARSE_TAG state.
89  * ssi_tag_brigade: The temporary brigade used by this filter to set aside
90  *                  the buckets containing parts of the ssi tag and headers.
91  */
92
93 /* I keep this stuff here, because of binary compat. It probably doesn't care,
94  * but who knows ...?
95  */
96 #ifdef MOD_INCLUDE_REDESIGN
97 typedef enum {PRE_HEAD, BLOW_PARSE_HEAD, BLOW_PARSE_DIRECTIVE, PARSE_TAG,
98               BLOW_PARSE_TAIL, PARSED} states;
99 #else
100 typedef enum {PRE_HEAD, PARSE_HEAD, PARSE_DIRECTIVE, PARSE_TAG, PARSE_TAIL,
101               PARSED} states;
102 #endif
103
104 /** forward referenced as it needs to be held on the context */
105 typedef struct bndm_t bndm_t;
106
107 typedef struct include_filter_ctx {
108     states       state;
109     long         flags;    /* See the FLAG_XXXXX definitions. */
110     int          if_nesting_level;
111     apr_size_t   parse_pos;
112     int          bytes_parsed;
113     apr_status_t status;
114     int          output_now;
115     int          output_flush;
116     
117     apr_bucket   *head_start_bucket;
118     apr_size_t   head_start_index;
119
120     apr_bucket   *tag_start_bucket;
121     apr_size_t   tag_start_index;
122
123     apr_bucket   *tail_start_bucket;
124     apr_size_t   tail_start_index;
125
126     char        *combined_tag;
127     char        *curr_tag_pos;
128     apr_size_t   directive_length;
129     apr_size_t   tag_length;
130
131     char         *error_str;
132     char         *error_str_override;
133     char         *time_str;
134     char         *time_str_override;
135     apr_pool_t   *pool;
136
137     apr_bucket_brigade *ssi_tag_brigade;
138     bndm_t       *start_seq_pat;
139     char         *start_seq;
140     int          start_seq_len;
141     char         *end_seq;
142     char         *re_string;
143     regmatch_t   (*re_result)[10];
144 } include_ctx_t;
145
146 /* These flags are used to set flag bits. */
147 #define FLAG_PRINTING         0x00000001  /* Printing conditional lines. */
148 #define FLAG_COND_TRUE        0x00000002  /* Conditional eval'd to true. */
149 #define FLAG_SIZE_IN_BYTES    0x00000004  /* Sizes displayed in bytes.   */
150 #define FLAG_NO_EXEC          0x00000008  /* No Exec in current context. */
151
152 /* These flags are used to clear flag bits. */
153 #define FLAG_SIZE_ABBREV      0xFFFFFFFB  /* Reset SIZE_IN_BYTES bit.    */
154 #define FLAG_CLEAR_PRINT_COND 0xFFFFFFFC  /* Reset PRINTING and COND_TRUE*/
155 #define FLAG_CLEAR_PRINTING   0xFFFFFFFE  /* Reset just PRINTING bit.    */
156
157 #define CREATE_ERROR_BUCKET(cntx, t_buck, h_ptr, ins_head)        \
158 {                                                                 \
159     /* XXX: it'd probably be nice to use a pool bucket here */    \
160     t_buck = apr_bucket_heap_create(cntx->error_str,              \
161                                     strlen(cntx->error_str),      \
162                                     NULL, h_ptr->list);           \
163     APR_BUCKET_INSERT_BEFORE(h_ptr, t_buck);                      \
164                                                                   \
165     if (ins_head == NULL) {                                       \
166         ins_head = t_buck;                                        \
167     }                                                             \
168 }
169
170 /* Make sure to check the return code rc. If it is anything other
171  *   than APR_SUCCESS, then you should return this value up the
172  *   call chain.
173  */
174 #define SPLIT_AND_PASS_PRETAG_BUCKETS(brgd, cntxt, next, rc)          \
175 if ((APR_BRIGADE_EMPTY((cntxt)->ssi_tag_brigade)) &&                  \
176     ((cntxt)->head_start_bucket != NULL)) {                           \
177     apr_bucket_brigade *tag_plus;                                     \
178                                                                       \
179     tag_plus = apr_brigade_split((brgd), (cntxt)->head_start_bucket); \
180     if ((cntxt)->output_flush) {                                      \
181         APR_BRIGADE_INSERT_TAIL((brgd), apr_bucket_flush_create((brgd)->bucket_alloc));   \
182     }                                                                 \
183     (rc) = ap_pass_brigade((next), (brgd));                           \
184     (cntxt)->bytes_parsed = 0;                                        \
185     (brgd) = tag_plus;                                                \
186 }
187
188
189 typedef int (include_handler_fn_t)(include_ctx_t *ctx, apr_bucket_brigade **bb,
190                        request_rec *r, ap_filter_t *f, apr_bucket *head_ptr, 
191                        apr_bucket **inserted_head);
192
193 APR_DECLARE_OPTIONAL_FN(void, ap_ssi_get_tag_and_value, (include_ctx_t *ctx,
194                                                          char **tag,
195                                                          char **tag_val,
196                                                          int dodecode));
197 APR_DECLARE_OPTIONAL_FN(char*, ap_ssi_parse_string, (request_rec *r,
198                                                     include_ctx_t *ctx,
199                                                     const char *in,
200                                                     char *out,
201                                                     apr_size_t length,
202                                                     int leave_name));
203 APR_DECLARE_OPTIONAL_FN(void, ap_register_include_handler, 
204                         (char *tag, include_handler_fn_t *func));
205
206 #endif /* MOD_INCLUDE */