
minfrin at apache
May 9, 2008, 2:59 PM
Post #1 of 1
(15 views)
Permalink
|
|
svn commit: r654952 - in /httpd/httpd/trunk: CHANGES modules/filters/mod_request.c modules/filters/mod_request.h server/request.c
|
|
Author: minfrin Date: Fri May 9 14:59:02 2008 New Revision: 654952 URL: http://svn.apache.org/viewvc?rev=654952&view=rev Log: mod_request: Insert the KEPT_BODY filter via the insert_filter hook instead of during fixups. Add a safety check to ensure the filters cannot be inserted more than once. [Graham Leggett, Ruediger Pluem] Modified: httpd/httpd/trunk/CHANGES httpd/httpd/trunk/modules/filters/mod_request.c httpd/httpd/trunk/modules/filters/mod_request.h httpd/httpd/trunk/server/request.c Modified: httpd/httpd/trunk/CHANGES URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=654952&r1=654951&r2=654952&view=diff ============================================================================== --- httpd/httpd/trunk/CHANGES [utf-8] (original) +++ httpd/httpd/trunk/CHANGES [utf-8] Fri May 9 14:59:02 2008 @@ -2,6 +2,11 @@ Changes with Apache 2.3.0 [ When backported to 2.2.x, remove entry from this file ] + *) mod_request: Insert the KEPT_BODY filter via the insert_filter + hook instead of during fixups. Add a safety check to ensure the + filters cannot be inserted more than once. [Graham Leggett, + Rüdiger Pluem] + *) core: Do not allow Options ALL if not all options are allowed to be overwritten. PR 44262 [Michał Grzędzicki <lazy iq.pl>] Modified: httpd/httpd/trunk/modules/filters/mod_request.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_request.c?rev=654952&r1=654951&r2=654952&view=diff ============================================================================== --- httpd/httpd/trunk/modules/filters/mod_request.c (original) +++ httpd/httpd/trunk/modules/filters/mod_request.c Fri May 9 14:59:02 2008 @@ -185,7 +185,7 @@ if (kept_body) { apr_table_unset(r->headers_in, "Transfer-Encoding"); apr_brigade_length(kept_body, 1, &length); - apr_table_set(r->headers_in, "Content-Length", apr_off_t_toa(r->pool, length)); + apr_table_setn(r->headers_in, "Content-Length", apr_off_t_toa(r->pool, length)); } return OK; @@ -307,13 +307,11 @@ * NOTE: File upload is not yet supported, but can be without change * to the function call. */ -AP_DECLARE(int) ap_parse_request_form(request_rec * r, apr_array_header_t ** ptr, +AP_DECLARE(int) ap_parse_request_form(request_rec * r, ap_filter_t * f, + apr_array_header_t ** ptr, apr_size_t num, apr_size_t size) { - request_dir_conf *dconf; - apr_off_t left = 0; - apr_bucket_brigade *bb = NULL, *kept_body = NULL; - apr_bucket *e; + apr_bucket_brigade *bb = NULL; int seen_eos = 0; char buffer[HUGE_STRING_LEN + 1]; const char *ct; @@ -333,18 +331,15 @@ return ap_discard_request_body(r); } - dconf = ap_get_module_config(r->per_dir_config, - &request_module); - if (dconf->keep_body > 0) { - left = dconf->keep_body; - kept_body = apr_brigade_create(r->pool, r->connection->bucket_alloc); + if (!f) { + f = r->input_filters; } bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); do { apr_bucket *bucket = NULL, *last = NULL; - int rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + int rv = ap_get_brigade(f, bb, AP_MODE_READBYTES, APR_BLOCK_READ, HUGE_STRING_LEN); if (rv != APR_SUCCESS) { apr_brigade_destroy(bb); @@ -460,24 +455,6 @@ } } - /* If we have been asked to, keep the data up until the - * configured limit. If the limit is exceeded, we return an - * HTTP_REQUEST_ENTITY_TOO_LARGE response so the caller is - * clear the server couldn't handle their request. - */ - if (kept_body) { - if (len <= left) { - apr_bucket_copy(bucket, &e); - APR_BRIGADE_INSERT_TAIL(kept_body, e); - left -= len; - } - else { - apr_brigade_destroy(bb); - apr_brigade_destroy(kept_body); - return HTTP_REQUEST_ENTITY_TOO_LARGE; - } - } - } apr_brigade_cleanup(bb); @@ -492,34 +469,69 @@ APR_BRIGADE_INSERT_TAIL(pair->value, b); } - if (kept_body) { - r->kept_body = kept_body; - } - return OK; } /** - * Fixups hook. + * Check whether this filter is not already present. + */ +static int request_is_filter_present(request_rec * r, ap_filter_rec_t *fn) +{ + ap_filter_t * f = r->input_filters; + while (f) { + if (f->frec == fn) { + return 1; + } + f = f->next; + } + return 0; +} + +/** + * Insert filter hook. * * Add the KEEP_BODY filter to the request, if the admin wants to keep * the body using the KeptBodySize directive. * + * As a precaution, any pre-existing instances of either the kept_body or + * keep_body filters will be removed before the filter is added. + * * @param r The request */ -static int request_fixups(request_rec * r) +AP_DECLARE(void) ap_request_insert_filter(request_rec * r) { request_dir_conf *conf = ap_get_module_config(r->per_dir_config, &request_module); - if (conf->keep_body) { - ap_add_input_filter_handle(ap_keep_body_input_filter_handle, - NULL, r, r->connection); + if (r->kept_body) { + if (!request_is_filter_present(r, ap_kept_body_input_filter_handle)) { + ap_add_input_filter_handle(ap_kept_body_input_filter_handle, + NULL, r, r->connection); + } + } + else if (conf->keep_body) { + if (!request_is_filter_present(r, ap_kept_body_input_filter_handle)) { + ap_add_input_filter_handle(ap_keep_body_input_filter_handle, + NULL, r, r->connection); + } } - return OK; +} +/** + * Remove the kept_body and keep body filters from this specific request. + */ +AP_DECLARE(void) ap_request_remove_filter(request_rec * r) +{ + ap_filter_t * f = r->input_filters; + while (f) { + if (f->frec->filter_func.in_func == ap_kept_body_filter || + f->frec->filter_func.in_func == ap_keep_body_filter) { + ap_remove_input_filter(f); + } + f = f->next; + } } static void *create_request_dir_config(apr_pool_t *p, char *dummy) @@ -573,8 +585,10 @@ ap_kept_body_input_filter_handle = ap_register_input_filter(KEPT_BODY_FILTER, ap_kept_body_filter, kept_body_filter_init, AP_FTYPE_RESOURCE); - ap_hook_fixups(request_fixups, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_insert_filter(ap_request_insert_filter, NULL, NULL, APR_HOOK_LAST); APR_REGISTER_OPTIONAL_FN(ap_parse_request_form); + APR_REGISTER_OPTIONAL_FN(ap_request_insert_filter); + APR_REGISTER_OPTIONAL_FN(ap_request_remove_filter); } module AP_MODULE_DECLARE_DATA request_module = { Modified: httpd/httpd/trunk/modules/filters/mod_request.h URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_request.h?rev=654952&r1=654951&r2=654952&view=diff ============================================================================== --- httpd/httpd/trunk/modules/filters/mod_request.h (original) +++ httpd/httpd/trunk/modules/filters/mod_request.h Fri May 9 14:59:02 2008 @@ -66,6 +66,12 @@ ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes); +/* Optional function to add either the keep body filter or kept body filter as appropriate */ +AP_DECLARE(void) ap_request_insert_filter(request_rec * r); + +/* Optional function to remove either the keep body filter or kept body filter as appropriate */ +AP_DECLARE(void) ap_request_remove_filter(request_rec * r); + /** * Structure to store the contents of an HTTP form of the type * application/x-www-form-urlencoded. @@ -111,15 +117,21 @@ * NOTE: File upload is not yet supported, but can be without change * to the function call. */ -AP_DECLARE(int) ap_parse_request_form(request_rec * r, apr_array_header_t ** ptr, +AP_DECLARE(int) ap_parse_request_form(request_rec * r, ap_filter_t * f, + apr_array_header_t ** ptr, apr_size_t num, apr_size_t size); -APR_DECLARE_OPTIONAL_FN(int, ap_parse_request_form, (request_rec * r, apr_array_header_t ** ptr, +APR_DECLARE_OPTIONAL_FN(int, ap_parse_request_form, (request_rec * r, ap_filter_t * f, + apr_array_header_t ** ptr, apr_size_t num, apr_size_t size)); +APR_DECLARE_OPTIONAL_FN(void, ap_request_insert_filter, (request_rec * r)); + +APR_DECLARE_OPTIONAL_FN(void, ap_request_remove_filter, (request_rec * r)); + #ifdef __cplusplus } #endif -#endif /* !MOD_REQUEST_H */ +#endif /* !MOD_REQUEST_H */ /** @} */ Modified: httpd/httpd/trunk/server/request.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/request.c?rev=654952&r1=654951&r2=654952&view=diff ============================================================================== --- httpd/httpd/trunk/server/request.c (original) +++ httpd/httpd/trunk/server/request.c Fri May 9 14:59:02 2008 @@ -1645,13 +1645,6 @@ /* Pass on the kept body (if any) into the new request. */ rnew->kept_body = r->kept_body; - /* - * Add the KEPT_BODY filter, which will insert any body marked to be - * kept for the use of a subrequest, into the subrequest. - */ - ap_add_input_filter(KEPT_BODY_FILTER, - NULL, rnew, rnew->connection); - return rnew; }
|