diff options
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | include/ap_mmn.h | 3 | ||||
-rw-r--r-- | include/util_filter.h | 18 | ||||
-rw-r--r-- | modules/experimental/mod_cache.c | 3 | ||||
-rw-r--r-- | modules/experimental/mod_case_filter.c | 2 | ||||
-rw-r--r-- | modules/experimental/mod_case_filter_in.c | 2 | ||||
-rw-r--r-- | modules/experimental/mod_charset_lite.c | 4 | ||||
-rw-r--r-- | modules/experimental/mod_ext_filter.c | 4 | ||||
-rw-r--r-- | modules/filters/mod_deflate.c | 4 | ||||
-rw-r--r-- | modules/filters/mod_include.c | 23 | ||||
-rw-r--r-- | modules/http/http_core.c | 9 | ||||
-rw-r--r-- | modules/metadata/mod_headers.c | 3 | ||||
-rw-r--r-- | modules/proxy/proxy_ftp.c | 3 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_io.c | 4 | ||||
-rw-r--r-- | modules/test/mod_bucketeer.c | 2 | ||||
-rw-r--r-- | server/config.c | 27 | ||||
-rw-r--r-- | server/core.c | 15 | ||||
-rw-r--r-- | server/util_filter.c | 10 |
18 files changed, 110 insertions, 31 deletions
@@ -1,5 +1,10 @@ Changes with Apache 2.0.40 + *) Add a filter_init parameter to the filter registration functions + so that a filter can execute arbitrary code before the handlers + are invoked. This resolves a problem where mod_include requests + would incorrectly return a 304. [Justin Erenkrantz] + *) Fix a long-standing bug in 2.0, CGI scripts were being called with relative paths instead of absolute paths. Apache 1.3 used absolute paths for everything except for SuExec, this brings back diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 58b7a7fc43..35b3438940 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -109,12 +109,13 @@ * 20020602 (2.0.37-dev) Bucket API change (metadata buckets) * 20020612 (2.0.38-dev) Changed server_rec->[keep_alive_]timeout to apr time * 20020625 (2.0.40-dev) Changed conn_rec->keepalive to an enumeration + * 20020628 (2.0.40-dev) Added filter_init to filter registration functions */ #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */ #ifndef MODULE_MAGIC_NUMBER_MAJOR -#define MODULE_MAGIC_NUMBER_MAJOR 20020625 +#define MODULE_MAGIC_NUMBER_MAJOR 20020628 #endif #define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ diff --git a/include/util_filter.h b/include/util_filter.h index 88f0587947..0a9954e04a 100644 --- a/include/util_filter.h +++ b/include/util_filter.h @@ -153,12 +153,19 @@ typedef struct ap_filter_t ap_filter_t; * for setting the association between a name for a filter and its * associated callback (and other information). * + * If the initialization function argument passed to the registration + * functions is non-NULL, it will be called iff the filter is in the input + * or output filter chains and before any data is generated to allow the + * filter to prepare for processing. + * * The *bucket structure (and all those referenced by ->next and ->prev) * should be considered "const". The filter is allowed to modify the * next/prev to insert/remove/replace elements in the bucket list, but * the types and values of the individual buckets should not be altered. * - * The return value of a filter should be an APR status value. + * For the input and output filters, the return value of a filter should be + * an APR status value. For the init function, the return value should + * be an HTTP error code or OK if it was successful. * * @ingroup filter * @{ @@ -170,6 +177,7 @@ typedef apr_status_t (*ap_in_filter_func)(ap_filter_t *f, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes); +typedef int (*ap_init_filter_func)(ap_filter_t *f); typedef union ap_filter_func { ap_out_filter_func out_func; @@ -242,6 +250,8 @@ struct ap_filter_rec_t { const char *name; /** The function to call when this filter is invoked. */ ap_filter_func filter_func; + /** The function to call before the handlers are invoked. */ + ap_init_filter_func filter_init_func; /** The type of filter, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION. * An AP_FTYPE_CONTENT filter modifies the data based on information * found in the content. An AP_FTYPE_CONNECTION filter modifies the @@ -259,8 +269,8 @@ struct ap_filter_rec_t { * requests get an exact copy of the main requests filter chain. */ struct ap_filter_t { - /** The internal representation of this filter. This includes - * the filter's name, type, and the actual function pointer. + /** The internal representation of this filter. This includes + * the filter's name, type, and the actual function pointer. */ ap_filter_rec_t *frec; @@ -324,6 +334,7 @@ AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *filter, */ AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name, ap_in_filter_func filter_func, + ap_init_filter_func filter_init, ap_filter_type ftype); /** * This function is used to register an output filter with the system. @@ -339,6 +350,7 @@ AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name, */ AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name, ap_out_filter_func filter_func, + ap_init_filter_func filter_init, ap_filter_type ftype); /** diff --git a/modules/experimental/mod_cache.c b/modules/experimental/mod_cache.c index a11a5a5ca0..d55a099752 100644 --- a/modules/experimental/mod_cache.c +++ b/modules/experimental/mod_cache.c @@ -981,6 +981,7 @@ register_hooks(apr_pool_t *p) */ ap_register_output_filter("CACHE_IN", cache_in_filter, + NULL, AP_FTYPE_CONTENT_SET); /* CACHE_OUT must go into the filter chain before SUBREQ_CORE to * handle subrequsts. Decrementing filter type by 1 ensures this @@ -988,9 +989,11 @@ register_hooks(apr_pool_t *p) */ ap_register_output_filter("CACHE_OUT", cache_out_filter, + NULL, AP_FTYPE_CONTENT_SET-1); ap_register_output_filter("CACHE_CONDITIONAL", cache_conditional_filter, + NULL, AP_FTYPE_CONTENT_SET); ap_hook_post_config(cache_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); } diff --git a/modules/experimental/mod_case_filter.c b/modules/experimental/mod_case_filter.c index 869d763373..5aaab7744e 100644 --- a/modules/experimental/mod_case_filter.c +++ b/modules/experimental/mod_case_filter.c @@ -98,7 +98,7 @@ static const command_rec CaseFilterCmds[] = static void CaseFilterRegisterHooks(apr_pool_t *p) { ap_hook_insert_filter(CaseFilterInsertFilter,NULL,NULL,APR_HOOK_MIDDLE); - ap_register_output_filter(s_szCaseFilterName,CaseFilterOutFilter, + ap_register_output_filter(s_szCaseFilterName,CaseFilterOutFilter,NULL, AP_FTYPE_RESOURCE); } diff --git a/modules/experimental/mod_case_filter_in.c b/modules/experimental/mod_case_filter_in.c index 8e25763cff..bda8aacf81 100644 --- a/modules/experimental/mod_case_filter_in.c +++ b/modules/experimental/mod_case_filter_in.c @@ -182,7 +182,7 @@ static void CaseFilterInRegisterHooks(apr_pool_t *p) { ap_hook_insert_filter(CaseFilterInInsertFilter, NULL, NULL, APR_HOOK_MIDDLE); - ap_register_input_filter(s_szCaseFilterName, CaseFilterInFilter, + ap_register_input_filter(s_szCaseFilterName, CaseFilterInFilter, NULL, AP_FTYPE_RESOURCE); } diff --git a/modules/experimental/mod_charset_lite.c b/modules/experimental/mod_charset_lite.c index 2b1fc9ffa8..48f13060f8 100644 --- a/modules/experimental/mod_charset_lite.c +++ b/modules/experimental/mod_charset_lite.c @@ -1105,9 +1105,9 @@ static void charset_register_hooks(apr_pool_t *p) { ap_hook_fixups(find_code_page, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_insert_filter(xlate_insert_filter, NULL, NULL, APR_HOOK_REALLY_LAST); - ap_register_output_filter(XLATEOUT_FILTER_NAME, xlate_out_filter, + ap_register_output_filter(XLATEOUT_FILTER_NAME, xlate_out_filter, NULL, AP_FTYPE_RESOURCE); - ap_register_input_filter(XLATEIN_FILTER_NAME, xlate_in_filter, + ap_register_input_filter(XLATEIN_FILTER_NAME, xlate_in_filter, NULL, AP_FTYPE_RESOURCE); } diff --git a/modules/experimental/mod_ext_filter.c b/modules/experimental/mod_ext_filter.c index ef95399855..b028ab4300 100644 --- a/modules/experimental/mod_ext_filter.c +++ b/modules/experimental/mod_ext_filter.c @@ -312,12 +312,12 @@ static const char *define_filter(cmd_parms *cmd, void *dummy, const char *args) */ if (filter->mode == OUTPUT_FILTER) { /* XXX need a way to ensure uniqueness among all filters */ - ap_register_output_filter(filter->name, ef_output_filter, AP_FTYPE_RESOURCE); + ap_register_output_filter(filter->name, ef_output_filter, NULL, AP_FTYPE_RESOURCE); } #if 0 /* no input filters yet */ else if (filter->mode == INPUT_FILTER) { /* XXX need a way to ensure uniqueness among all filters */ - ap_register_input_filter(filter->name, ef_input_filter, AP_FTYPE_RESOURCE); + ap_register_input_filter(filter->name, ef_input_filter, NULL, AP_FTYPE_RESOURCE); } #endif else { diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c index 82b2d9ff23..83e45446df 100644 --- a/modules/filters/mod_deflate.c +++ b/modules/filters/mod_deflate.c @@ -760,9 +760,9 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, static void register_hooks(apr_pool_t *p) { - ap_register_output_filter(deflateFilterName, deflate_out_filter, + ap_register_output_filter(deflateFilterName, deflate_out_filter, NULL, AP_FTYPE_CONTENT_SET); - ap_register_input_filter(deflateFilterName, deflate_in_filter, + ap_register_input_filter(deflateFilterName, deflate_in_filter, NULL, AP_FTYPE_CONTENT_SET); } diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c index 4e96695831..9a52aec9dd 100644 --- a/modules/filters/mod_include.c +++ b/modules/filters/mod_include.c @@ -3323,6 +3323,26 @@ static const char *set_xbithack(cmd_parms *cmd, void *xbp, const char *arg) return NULL; } +static int includes_setup(ap_filter_t *f) +{ + include_dir_config *conf = + (include_dir_config *)ap_get_module_config(f->r->per_dir_config, + &include_module); + + /* When our xbithack value isn't set to full or our platform isn't + * providing group-level protection bits or our group-level bits do not + * have group-execite on, we will set the no_local_copy value to 1 so + * that we will not send 304s. + */ + if ((*conf->xbithack != xbithack_full) + || !(f->r->finfo.valid & APR_FINFO_GPROT) + || !(f->r->finfo.protection & APR_GEXECUTE)) { + f->r->no_local_copy = 1; + } + + return OK; +} + static apr_status_t includes_filter(ap_filter_t *f, apr_bucket_brigade *b) { request_rec *r = f->r; @@ -3556,7 +3576,8 @@ static void register_hooks(apr_pool_t *p) APR_REGISTER_OPTIONAL_FN(ap_register_include_handler); ap_hook_post_config(include_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); ap_hook_fixups(include_fixup, NULL, NULL, APR_HOOK_LAST); - ap_register_output_filter("INCLUDES", includes_filter, AP_FTYPE_RESOURCE); + ap_register_output_filter("INCLUDES", includes_filter, includes_setup, + AP_FTYPE_RESOURCE); } module AP_MODULE_DECLARE_DATA include_module = diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 9db75533fc..8bd0fb7e8d 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -330,15 +330,16 @@ static void register_hooks(apr_pool_t *p) ap_hook_create_request(http_create_request, NULL, NULL, APR_HOOK_REALLY_LAST); ap_http_input_filter_handle = ap_register_input_filter("HTTP_IN", ap_http_filter, - AP_FTYPE_PROTOCOL); + NULL, AP_FTYPE_PROTOCOL); ap_http_header_filter_handle = ap_register_output_filter("HTTP_HEADER", ap_http_header_filter, - AP_FTYPE_PROTOCOL); + NULL, AP_FTYPE_PROTOCOL); ap_chunk_filter_handle = - ap_register_output_filter("CHUNK", chunk_filter, AP_FTYPE_TRANSCODE); + ap_register_output_filter("CHUNK", chunk_filter, + NULL, AP_FTYPE_TRANSCODE); ap_byterange_filter_handle = ap_register_output_filter("BYTERANGE", ap_byterange_filter, - AP_FTYPE_PROTOCOL); + NULL, AP_FTYPE_PROTOCOL); ap_method_registry_init(p); } diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c index dee922a66e..cf42cdfb43 100644 --- a/modules/metadata/mod_headers.c +++ b/modules/metadata/mod_headers.c @@ -620,7 +620,8 @@ static void register_hooks(apr_pool_t *p) ap_hook_pre_config(header_pre_config,NULL,NULL,APR_HOOK_MIDDLE); ap_hook_insert_filter(ap_headers_insert_output_filter, NULL, NULL, APR_HOOK_LAST); ap_hook_fixups(ap_headers_fixup, NULL, NULL, APR_HOOK_LAST); - ap_register_output_filter("FIXUP_HEADERS_OUT", ap_headers_output_filter, AP_FTYPE_CONTENT_SET); + ap_register_output_filter("FIXUP_HEADERS_OUT", ap_headers_output_filter, + NULL, AP_FTYPE_CONTENT_SET); } module AP_MODULE_DECLARE_DATA headers_module = diff --git a/modules/proxy/proxy_ftp.c b/modules/proxy/proxy_ftp.c index a4c77d3a41..dea106ad96 100644 --- a/modules/proxy/proxy_ftp.c +++ b/modules/proxy/proxy_ftp.c @@ -1926,7 +1926,8 @@ static void ap_proxy_ftp_register_hook(apr_pool_t *p) proxy_hook_scheme_handler(ap_proxy_ftp_handler, NULL, NULL, APR_HOOK_MIDDLE); proxy_hook_canon_handler(ap_proxy_ftp_canon, NULL, NULL, APR_HOOK_MIDDLE); /* filters */ - ap_register_output_filter("PROXY_SEND_DIR", ap_proxy_send_dir_filter, AP_FTYPE_RESOURCE); + ap_register_output_filter("PROXY_SEND_DIR", ap_proxy_send_dir_filter, + NULL, AP_FTYPE_RESOURCE); } module AP_MODULE_DECLARE_DATA proxy_ftp_module = { diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 47e76329c4..cdb6c965c6 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -943,8 +943,8 @@ void ssl_io_filter_init(conn_rec *c, SSL *ssl) void ssl_io_filter_register(apr_pool_t *p) { - ap_register_input_filter (ssl_io_filter, ssl_io_filter_Input, AP_FTYPE_CONNECTION + 5); - ap_register_output_filter (ssl_io_filter, ssl_io_filter_Output, AP_FTYPE_CONNECTION + 5); + ap_register_input_filter (ssl_io_filter, ssl_io_filter_Input, NULL, AP_FTYPE_CONNECTION + 5); + ap_register_output_filter (ssl_io_filter, ssl_io_filter_Output, NULL, AP_FTYPE_CONNECTION + 5); return; } diff --git a/modules/test/mod_bucketeer.c b/modules/test/mod_bucketeer.c index 6738cd69cc..f8e4130a48 100644 --- a/modules/test/mod_bucketeer.c +++ b/modules/test/mod_bucketeer.c @@ -201,7 +201,7 @@ static apr_status_t bucketeer_out_filter(ap_filter_t *f, static void register_hooks(apr_pool_t * p) { ap_register_output_filter(bucketeerFilterName, bucketeer_out_filter, - AP_FTYPE_RESOURCE-1); + NULL, AP_FTYPE_RESOURCE-1); } static const command_rec bucketeer_filter_cmds[] = { diff --git a/server/config.c b/server/config.c index d8932345da..1de9930119 100644 --- a/server/config.c +++ b/server/config.c @@ -335,6 +335,20 @@ AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p) return create_empty_config(p); } +static int ap_invoke_filter_init(ap_filter_t *filters) +{ + while (filters) { + if (filters->frec->filter_init_func) { + int result = filters->frec->filter_init_func(filters); + if (result != OK) { + return result; + } + } + filters = filters->next; + } + return OK; +} + AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r) { const char *handler; @@ -352,6 +366,19 @@ AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r) */ ap_run_insert_filter(r); + /* Before continuing, allow each filter that is in the two chains to + * run their init function to let them do any magic before we could + * start generating data. + */ + result = ap_invoke_filter_init(r->input_filters); + if (result != OK) { + return result; + } + result = ap_invoke_filter_init(r->output_filters); + if (result != OK) { + return result; + } + if (!r->handler) { handler = r->content_type ? r->content_type : ap_default_type(r); if ((p=ap_strchr_c(handler, ';')) != NULL) { diff --git a/server/core.c b/server/core.c index 23f7641ab3..3a066f5ecf 100644 --- a/server/core.c +++ b/server/core.c @@ -4098,21 +4098,22 @@ static void register_hooks(apr_pool_t *p) ap_core_input_filter_handle = ap_register_input_filter("CORE_IN", core_input_filter, - AP_FTYPE_NETWORK); + NULL, AP_FTYPE_NETWORK); ap_net_time_filter_handle = ap_register_input_filter("NET_TIME", net_time_filter, - AP_FTYPE_PROTOCOL); + NULL, AP_FTYPE_PROTOCOL); ap_content_length_filter_handle = ap_register_output_filter("CONTENT_LENGTH", ap_content_length_filter, - AP_FTYPE_PROTOCOL); + NULL, AP_FTYPE_PROTOCOL); ap_core_output_filter_handle = ap_register_output_filter("CORE", core_output_filter, - AP_FTYPE_NETWORK); + NULL, AP_FTYPE_NETWORK); ap_subreq_core_filter_handle = ap_register_output_filter("SUBREQ_CORE", ap_sub_req_output_filter, - AP_FTYPE_CONTENT_SET); - ap_old_write_func = ap_register_output_filter("OLD_WRITE", - ap_old_write_filter, AP_FTYPE_RESOURCE - 10); + NULL, AP_FTYPE_CONTENT_SET); + ap_old_write_func = + ap_register_output_filter("OLD_WRITE", ap_old_write_filter, + NULL, AP_FTYPE_RESOURCE - 10); } AP_DECLARE_DATA module core_module = { diff --git a/server/util_filter.c b/server/util_filter.c index 314ff69695..30cfa090e4 100644 --- a/server/util_filter.c +++ b/server/util_filter.c @@ -234,6 +234,7 @@ AP_DECLARE(ap_filter_rec_t *)ap_get_input_filter_handle(const char *name) static ap_filter_rec_t *register_filter(const char *name, ap_filter_func filter_func, + ap_init_filter_func filter_init, ap_filter_type ftype, filter_trie_node **reg_filter_set) { @@ -266,6 +267,7 @@ static ap_filter_rec_t *register_filter(const char *name, frec->name = normalized_name; } frec->filter_func = filter_func; + frec->filter_init_func = filter_init; frec->ftype = ftype; apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup, @@ -275,20 +277,24 @@ static ap_filter_rec_t *register_filter(const char *name, AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name, ap_in_filter_func filter_func, + ap_init_filter_func filter_init, ap_filter_type ftype) { ap_filter_func f; f.in_func = filter_func; - return register_filter(name, f, ftype, ®istered_input_filters); + return register_filter(name, f, filter_init, ftype, + ®istered_input_filters); } AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name, ap_out_filter_func filter_func, + ap_init_filter_func filter_init, ap_filter_type ftype) { ap_filter_func f; f.out_func = filter_func; - return register_filter(name, f, ftype, ®istered_output_filters); + return register_filter(name, f, filter_init, ftype, + ®istered_output_filters); } static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx, |