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
9 ** http://www.apache.org/licenses/LICENSE-2.0
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.
18 #ifndef APREQ_MODULE_H
19 #define APREQ_MODULE_H
21 #include "apreq_cookie.h"
22 #include "apreq_parser.h"
23 #include "apreq_error.h"
30 * @file apreq_module.h
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.
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 */
46 /** the allocator, which persists at least as long as the pool */
47 apr_bucket_alloc_t *bucket_alloc;
52 * @brief Vtable describing the necessary module functions.
56 typedef struct apreq_module_t {
57 /** name of this apreq module */
59 /** magic number identifying the module and version */
60 apr_uint32_t magic_number;
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 **);
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 *);
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 *);
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);
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);
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 *);
102 * Defines the module-specific status codes which
103 * are commonly considered to be non-fatal.
105 * @param s status code returned by an apreq_module_t method.
107 * @return 1 if s is fatal, 0 otherwise.
110 unsigned apreq_module_status_is_error(apr_status_t s) {
115 case APREQ_ERROR_NODATA:
116 case APREQ_ERROR_NOPARSER:
117 case APREQ_ERROR_NOHEADER:
126 * Expose the parsed "cookie" header associated to this handle.
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.
132 * @return APR_SUCCESS or a module-specific error status code.
135 apr_status_t apreq_jar(apreq_handle_t *req, const apr_table_t **t)
137 return req->module->jar(req,t);
141 * Expose the parsed "query string" associated to this handle.
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.
147 * @return APR_SUCCESS or a module-specific error status code.
150 apr_status_t apreq_args(apreq_handle_t *req, const apr_table_t **t)
152 return req->module->args(req,t);
156 * Expose the parsed "request body" associated to this handle.
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.
162 * @return APR_SUCCESS or a module-specific error status code.
165 apr_status_t apreq_body(apreq_handle_t *req, const apr_table_t **t)
167 return req->module->body(req, t);
172 * Fetch the first cookie with the given name.
174 * @param req The request handle
175 * @param name Case-insensitive cookie name.
177 * @return First matching cookie, or NULL if none match.
180 apreq_cookie_t *apreq_jar_get(apreq_handle_t *req, const char *name)
182 return req->module->jar_get(req, name);
186 * Fetch the first query string param with the given name.
188 * @param req The request handle
189 * @param name Case-insensitive param name.
191 * @return First matching param, or NULL if none match.
194 apreq_param_t *apreq_args_get(apreq_handle_t *req, const char *name)
196 return req->module->args_get(req, name);
200 * Fetch the first body param with the given name.
202 * @param req The request handle
203 * @param name Case-insensitive cookie name.
205 * @return First matching param, or NULL if none match.
208 apreq_param_t *apreq_body_get(apreq_handle_t *req, const char *name)
210 return req->module->body_get(req, name);
214 * Fetch the active body parser.
216 * @param req The request handle
217 * @param parser Points to the active parser on return.
219 * @return APR_SUCCESS or module-specific error.
223 apr_status_t apreq_parser_get(apreq_handle_t *req,
224 const apreq_parser_t **parser)
226 return req->module->parser_get(req, parser);
231 * Set the body parser for this request.
233 * @param req The request handle
234 * @param parser New parser to use.
236 * @return APR_SUCCESS or module-specific error.
239 apr_status_t apreq_parser_set(apreq_handle_t *req,
240 apreq_parser_t *parser)
242 return req->module->parser_set(req, parser);
246 * Add a parser hook for this request.
248 * @param req The request handle
249 * @param hook Hook to add.
251 * @return APR_SUCCESS or module-specific error.
254 apr_status_t apreq_hook_add(apreq_handle_t *req, apreq_hook_t *hook)
256 return req->module->hook_add(req, hook);
261 * Set the active brigade limit.
263 * @param req The handle.
264 * @param bytes New limit to use.
266 * @return APR_SUCCESS or module-specific error.
270 apr_status_t apreq_brigade_limit_set(apreq_handle_t *req,
273 return req->module->brigade_limit_set(req, bytes);
277 * Get the active brigade limit.
279 * @param req The handle.
280 * @param bytes Pointer to resulting (current) limit.
282 * @return APR_SUCCESS or a module-specific error,
283 * which may leave bytes undefined.
286 apr_status_t apreq_brigade_limit_get(apreq_handle_t *req,
289 return req->module->brigade_limit_get(req, bytes);
293 * Set the active read limit.
295 * @param req The handle.
296 * @param bytes New limit to use.
298 * @return APR_SUCCESS or a module-specific error.
302 apr_status_t apreq_read_limit_set(apreq_handle_t *req,
305 return req->module->read_limit_set(req, bytes);
309 * Get the active read limit.
311 * @param req The request handle.
312 * @param bytes Pointer to resulting (current) limit.
314 * @return APR_SUCCESS or a module-specific error,
315 * which may leave bytes undefined.
318 apr_status_t apreq_read_limit_get(apreq_handle_t *req,
321 return req->module->read_limit_get(req, bytes);
325 * Set the active temp directory.
327 * @param req The handle.
328 * @param path New path to use; may be NULL.
330 * @return APR_SUCCESS or a module-specific error .
333 apr_status_t apreq_temp_dir_set(apreq_handle_t *req, const char *path)
335 return req->module->temp_dir_set(req, path);
339 * Get the active temp directory.
341 * @param req The handle.
342 * @param path Resulting path to temp dir.
344 * @return APR_SUCCESS implies path is valid, but may also be NULL.
345 * Any other return value is module-specific, and may leave
349 apr_status_t apreq_temp_dir_get(apreq_handle_t *req, const char **path)
351 return req->module->temp_dir_get(req, path);
357 * Convenience macro for defining a module by mapping
358 * a function prefix to an associated apreq_module_t structure.
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
364 * @param mmn Magic number (i.e. version number) of this module.
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, \
378 * Create an apreq handle which is suitable for a CGI program. It
379 * reads input from stdin and writes output to stdout.
381 * @param pool Pool associated to this handle.
383 * @return New handle; can only be NULL if the pool allocation failed.
385 * @remarks The handle gets cached in the pool's userdata, so subsequent
386 * calls will retrieve the original cached handle.
388 APREQ_DECLARE(apreq_handle_t*) apreq_handle_cgi(apr_pool_t *pool);
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).
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
402 * @return new handle; can only be NULL if the pool allocation failed.
404 APREQ_DECLARE(apreq_handle_t*) apreq_handle_custom(apr_pool_t *pool,
405 const char *query_string,
407 apreq_parser_t *parser,
408 apr_uint64_t read_limit,
409 apr_bucket_brigade *in);
412 * Find the first query string parameter or body parameter with the
413 * specified name. The match is case-insensitive.
415 * @param req request handle.
416 * @param key desired parameter name
418 * @return The first matching parameter (with args searched first) or NULL.
420 APREQ_DECLARE(apreq_param_t *)apreq_param(apreq_handle_t *req, const char *key);
423 * Find the first cookie with the specified name.
424 * The match is case-insensitive.
426 * @param req request handle.
427 * @param name desired cookie name
429 * @return The first matching cookie or NULL.
431 #define apreq_cookie(req, name) apreq_jar_get(req, name)
434 * Returns a table containing key-value pairs for the full request
437 * @param req request handle
438 * @param p allocates the returned table.
440 * @return table representing all available params; is never NULL.
442 APREQ_DECLARE(apr_table_t *) apreq_params(apreq_handle_t *req, apr_pool_t *p);
446 * Returns a table containing all request cookies.
448 * @param req the apreq request handle
449 * @param p Allocates the returned table.
451 APREQ_DECLARE(apr_table_t *)apreq_cookies(apreq_handle_t *req, apr_pool_t *p);
457 #endif /* APREQ_MODULE_H */