]> granicus.if.org Git - apache/blob - include/apreq_module.h
mod_ssl: Fix SSL_CLIENT_VERIFY value when "SSLVerifyClient optional_no_ca" and
[apache] / include / apreq_module.h
1 /*
2 **  Licensed to the Apache Software Foundation (ASF) under one or more
3 ** contributor license agreements.  See the NOTICE file distributed with
4 ** this work for additional information regarding copyright ownership.
5 ** The ASF licenses this file to You under the Apache License, Version 2.0
6 ** (the "License"); you may not use this file except in compliance with
7 ** the License.  You may obtain a copy of the License at
8 **
9 **      http://www.apache.org/licenses/LICENSE-2.0
10 **
11 **  Unless required by applicable law or agreed to in writing, software
12 **  distributed under the License is distributed on an "AS IS" BASIS,
13 **  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 **  See the License for the specific language governing permissions and
15 **  limitations under the License.
16 */
17
18 #ifndef APREQ_MODULE_H
19 #define APREQ_MODULE_H
20
21 #include "apreq_cookie.h"
22 #include "apreq_parser.h"
23 #include "apreq_error.h"
24
25 #ifdef  __cplusplus
26  extern "C" {
27 #endif
28
29 /**
30  * @file apreq_module.h
31  * @brief Module API
32  * @ingroup libapreq2
33  */
34
35
36 /**
37  * An apreq handle associated with a module. The structure
38  * may have variable size, because the module may append its own data
39  * structures after it.
40  */
41 typedef struct apreq_handle_t {
42     /** the apreq module which implements this handle */
43     const struct apreq_module_t *module;
44     /** the pool which defines the lifetime of the parsed data */
45     apr_pool_t *pool;
46     /** the allocator, which persists at least as long as the pool */
47     apr_bucket_alloc_t *bucket_alloc;
48
49 } apreq_handle_t;
50
51 /**
52  * @brief Vtable describing the necessary module functions.
53  */
54
55
56 typedef struct apreq_module_t {
57     /** name of this apreq module */
58     const char *name;
59     /** magic number identifying the module and version */
60     apr_uint32_t magic_number;
61
62     /** get a table with all cookies */
63     apr_status_t (*jar)(apreq_handle_t *, const apr_table_t **);
64     /** get a table with all query string parameters */
65     apr_status_t (*args)(apreq_handle_t *, const apr_table_t **);
66     /** get a table with all body parameters */
67     apr_status_t (*body)(apreq_handle_t *, const apr_table_t **);
68
69     /** get a cookie by its name */
70     apreq_cookie_t *(*jar_get)(apreq_handle_t *, const char *);
71     /** get a query string parameter by its name */
72     apreq_param_t *(*args_get)(apreq_handle_t *, const char *);
73     /** get a body parameter by its name */
74     apreq_param_t *(*body_get)(apreq_handle_t *, const char *);
75
76     /** gets the parser associated with the request body */
77     apr_status_t (*parser_get)(apreq_handle_t *, const apreq_parser_t **);
78     /** manually set a parser for the request body */
79     apr_status_t (*parser_set)(apreq_handle_t *, apreq_parser_t *);
80     /** add a hook function */
81     apr_status_t (*hook_add)(apreq_handle_t *, apreq_hook_t *);
82
83     /** determine the maximum in-memory bytes a brigade may use */
84     apr_status_t (*brigade_limit_get)(apreq_handle_t *, apr_size_t *);
85     /** set the maximum in-memory bytes a brigade may use */
86     apr_status_t (*brigade_limit_set)(apreq_handle_t *, apr_size_t);
87
88     /** determine the maximum amount of data that will be fed into a parser */
89     apr_status_t (*read_limit_get)(apreq_handle_t *, apr_uint64_t *);
90     /** set the maximum amount of data that will be fed into a parser */
91     apr_status_t (*read_limit_set)(apreq_handle_t *, apr_uint64_t);
92
93     /** determine the directory used by the parser for temporary files */
94     apr_status_t (*temp_dir_get)(apreq_handle_t *, const char **);
95     /** set the directory used by the parser for temporary files */
96     apr_status_t (*temp_dir_set)(apreq_handle_t *, const char *);
97
98 } apreq_module_t;
99
100
101 /**
102  * Defines the module-specific status codes which
103  * are commonly considered to be non-fatal.
104  *
105  * @param s status code returned by an apreq_module_t method.
106  *
107  * @return 1 if s is fatal, 0 otherwise.
108  */
109 static APR_INLINE
110 unsigned apreq_module_status_is_error(apr_status_t s) {
111     switch (s) {
112     case APR_SUCCESS:
113     case APR_INCOMPLETE:
114     case APR_EINIT:
115     case APREQ_ERROR_NODATA:
116     case APREQ_ERROR_NOPARSER:
117     case APREQ_ERROR_NOHEADER:
118         return 0;
119     default:
120         return 1;
121     }
122 }
123
124
125 /**
126  * Expose the parsed "cookie" header associated to this handle.
127  *
128  * @param req The request handle
129  * @param t   The resulting table, which will either be NULL or a
130  *            valid table object on return.
131  *
132  * @return    APR_SUCCESS or a module-specific error status code.
133  */
134 static APR_INLINE
135 apr_status_t apreq_jar(apreq_handle_t *req, const apr_table_t **t)
136 {
137     return req->module->jar(req,t);
138 }
139
140 /**
141  * Expose the parsed "query string" associated to this handle.
142  *
143  * @param req The request handle
144  * @param t   The resulting table, which will either be NULL or a
145  *            valid table object on return.
146  *
147  * @return    APR_SUCCESS or a module-specific error status code.
148  */
149 static APR_INLINE
150 apr_status_t apreq_args(apreq_handle_t *req, const apr_table_t **t)
151 {
152     return req->module->args(req,t);
153 }
154
155 /**
156  * Expose the parsed "request body" associated to this handle.
157  *
158  * @param req The request handle
159  * @param t   The resulting table, which will either be NULL or a
160  *            valid table object on return.
161  *
162  * @return    APR_SUCCESS or a module-specific error status code.
163  */
164 static APR_INLINE
165 apr_status_t apreq_body(apreq_handle_t *req, const apr_table_t **t)
166 {
167     return req->module->body(req, t);
168 }
169
170
171 /**
172  * Fetch the first cookie with the given name.
173  *
174  * @param req  The request handle
175  * @param name Case-insensitive cookie name.
176  *
177  * @return     First matching cookie, or NULL if none match.
178  */
179 static APR_INLINE
180 apreq_cookie_t *apreq_jar_get(apreq_handle_t *req, const char *name)
181 {
182     return req->module->jar_get(req, name);
183 }
184
185 /**
186  * Fetch the first query string param with the given name.
187  *
188  * @param req  The request handle
189  * @param name Case-insensitive param name.
190  *
191  * @return     First matching param, or NULL if none match.
192  */
193 static APR_INLINE
194 apreq_param_t *apreq_args_get(apreq_handle_t *req, const char *name)
195 {
196     return req->module->args_get(req, name);
197 }
198
199 /**
200  * Fetch the first body param with the given name.
201  *
202  * @param req  The request handle
203  * @param name Case-insensitive cookie name.
204  *
205  * @return     First matching param, or NULL if none match.
206  */
207 static APR_INLINE
208 apreq_param_t *apreq_body_get(apreq_handle_t *req, const char *name)
209 {
210     return req->module->body_get(req, name);
211 }
212
213 /**
214  * Fetch the active body parser.
215  *
216  * @param req    The request handle
217  * @param parser Points to the active parser on return.
218  *
219  * @return       APR_SUCCESS or module-specific error.
220  *
221  */
222 static APR_INLINE
223 apr_status_t apreq_parser_get(apreq_handle_t *req,
224                               const apreq_parser_t **parser)
225 {
226     return req->module->parser_get(req, parser);
227 }
228
229
230 /**
231  * Set the body parser for this request.
232  *
233  * @param req    The request handle
234  * @param parser New parser to use.
235  *
236  * @return       APR_SUCCESS or module-specific error.
237  */
238 static APR_INLINE
239 apr_status_t apreq_parser_set(apreq_handle_t *req,
240                               apreq_parser_t *parser)
241 {
242     return req->module->parser_set(req, parser);
243 }
244
245 /**
246  * Add a parser hook for this request.
247  *
248  * @param req  The request handle
249  * @param hook Hook to add.
250  *
251  * @return     APR_SUCCESS or module-specific error.
252  */
253 static APR_INLINE
254 apr_status_t apreq_hook_add(apreq_handle_t *req, apreq_hook_t *hook)
255 {
256     return req->module->hook_add(req, hook);
257 }
258
259
260 /**
261  * Set the active brigade limit.
262  *
263  * @param req   The handle.
264  * @param bytes New limit to use.
265  *
266  * @return APR_SUCCESS or module-specific error.
267  *
268  */
269 static APR_INLINE
270 apr_status_t apreq_brigade_limit_set(apreq_handle_t *req,
271                                      apr_size_t bytes)
272 {
273     return req->module->brigade_limit_set(req, bytes);
274 }
275
276 /**
277  * Get the active brigade limit.
278  *
279  * @param req   The handle.
280  * @param bytes Pointer to resulting (current) limit.
281  *
282  * @return APR_SUCCESS or a module-specific error,
283  *         which may leave bytes undefined.
284  */
285 static APR_INLINE
286 apr_status_t apreq_brigade_limit_get(apreq_handle_t *req,
287                                      apr_size_t *bytes)
288 {
289     return req->module->brigade_limit_get(req, bytes);
290 }
291
292 /**
293  * Set the active read limit.
294  *
295  * @param req   The handle.
296  * @param bytes New limit to use.
297  *
298  * @return APR_SUCCESS or a module-specific error.
299  *
300  */
301 static APR_INLINE
302 apr_status_t apreq_read_limit_set(apreq_handle_t *req,
303                                   apr_uint64_t bytes)
304 {
305     return req->module->read_limit_set(req, bytes);
306 }
307
308 /**
309  * Get the active read limit.
310  *
311  * @param req   The request handle.
312  * @param bytes Pointer to resulting (current) limit.
313  *
314  * @return APR_SUCCESS or a module-specific error,
315  *         which may leave bytes undefined.
316  */
317 static APR_INLINE
318 apr_status_t apreq_read_limit_get(apreq_handle_t *req,
319                                   apr_uint64_t *bytes)
320 {
321     return req->module->read_limit_get(req, bytes);
322 }
323
324 /**
325  * Set the active temp directory.
326  *
327  * @param req  The handle.
328  * @param path New path to use; may be NULL.
329  *
330  * @return APR_SUCCESS or a module-specific error .
331  */
332 static APR_INLINE
333 apr_status_t apreq_temp_dir_set(apreq_handle_t *req, const char *path)
334 {
335     return req->module->temp_dir_set(req, path);
336 }
337
338 /**
339  * Get the active temp directory.
340  *
341  * @param req   The handle.
342  * @param path  Resulting path to temp dir.
343  *
344  * @return APR_SUCCESS implies path is valid, but may also be NULL.
345  *         Any other return value is module-specific, and may leave
346  *         path undefined.
347  */
348 static APR_INLINE
349 apr_status_t apreq_temp_dir_get(apreq_handle_t *req, const char **path)
350 {
351     return req->module->temp_dir_get(req, path);
352 }
353
354
355
356 /**
357  * Convenience macro for defining a module by mapping
358  * a function prefix to an associated apreq_module_t structure.
359  *
360  * @param pre Prefix to define new module.  All attributes of
361  *            the apreq_module_t struct are defined with this as their
362  *            prefix. The generated struct is named by appending "_module" to
363  *            the prefix.
364  * @param mmn Magic number (i.e. version number) of this module.
365  */
366 #define APREQ_MODULE(pre, mmn) const apreq_module_t     \
367   pre##_module = { #pre, mmn,                           \
368   pre##_jar,        pre##_args,       pre##_body,       \
369   pre##_jar_get,    pre##_args_get,   pre##_body_get,   \
370   pre##_parser_get, pre##_parser_set, pre##_hook_add,   \
371   pre##_brigade_limit_get, pre##_brigade_limit_set,     \
372   pre##_read_limit_get,    pre##_read_limit_set,        \
373   pre##_temp_dir_get,      pre##_temp_dir_set,          \
374   }
375
376
377 /**
378  * Create an apreq handle which is suitable for a CGI program. It
379  * reads input from stdin and writes output to stdout.
380  *
381  * @param pool Pool associated to this handle.
382  *
383  * @return New handle; can only be NULL if the pool allocation failed.
384  *
385  * @remarks The handle gets cached in the pool's userdata, so subsequent
386  *          calls will retrieve the original cached handle.
387  */
388 APREQ_DECLARE(apreq_handle_t*) apreq_handle_cgi(apr_pool_t *pool);
389
390 /**
391  * Create a custom apreq handle which knows only some static
392  * values. Useful if you want to test the parser code or if you have
393  * got data from a custom source (neither Apache 2 nor CGI).
394  *
395  * @param pool         allocates the parse data,
396  * @param query_string parsed into args table
397  * @param cookie       value of the request "Cookie" header
398  * @param parser       parses the request body
399  * @param read_limit   maximum bytes to read from the body
400  * @param in           brigade containing the request body
401  *
402  * @return new handle; can only be NULL if the pool allocation failed.
403  */
404 APREQ_DECLARE(apreq_handle_t*) apreq_handle_custom(apr_pool_t *pool,
405                                                    const char *query_string,
406                                                    const char *cookie,
407                                                    apreq_parser_t *parser,
408                                                    apr_uint64_t read_limit,
409                                                    apr_bucket_brigade *in);
410
411 /**
412  * Find the first query string parameter or body parameter with the
413  * specified name.  The match is case-insensitive.
414  *
415  * @param req request handle.
416  * @param key desired parameter name
417  *
418  * @return The first matching parameter (with args searched first) or NULL.
419  */
420 APREQ_DECLARE(apreq_param_t *)apreq_param(apreq_handle_t *req, const char *key);
421
422 /**
423  * Find the first cookie with the specified name.
424  * The match is case-insensitive.
425  *
426  * @param req request handle.
427  * @param name desired cookie name
428  *
429  * @return The first matching cookie or NULL.
430  */
431 #define apreq_cookie(req, name) apreq_jar_get(req, name)
432
433 /**
434  * Returns a table containing key-value pairs for the full request
435  * (args + body).
436  *
437  * @param req request handle
438  * @param p   allocates the returned table.
439  *
440  * @return table representing all available params; is never NULL.
441  */
442 APREQ_DECLARE(apr_table_t *) apreq_params(apreq_handle_t *req, apr_pool_t *p);
443
444
445 /**
446  * Returns a table containing all request cookies.
447  *
448  * @param req the apreq request handle
449  * @param p Allocates the returned table.
450  */
451 APREQ_DECLARE(apr_table_t *)apreq_cookies(apreq_handle_t *req, apr_pool_t *p);
452
453 #ifdef __cplusplus
454  }
455 #endif
456
457 #endif /* APREQ_MODULE_H */