Skip to content

Commit a65043d

Browse files
author
Justin Erenkrantz
committed
Add a filter_init function to the filters so that a filter can execute
arbitrary code before the handlers are invoked. This resolves an issue with incorrect 304s on If-Modified-Since mod_include requests since ap_meets_conditions() is not aware that this is a dynamic request and it is not possible to satisfy 304 for these requests (unless xbithack full is on, of course). When mod_include runs as a filter, it is too late to set any flag since the handler is responsible for calling ap_meets_conditions(), which it should do before generating any data. If a module doesn't need to run such arbitrary code, it can just pass NULL as the argument and all is well. PR: 9673 Reviewed by: Ryan Bloom and others git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95906 13f79535-47bb-0310-9956-ffa450edef68
1 parent d6f99bc commit a65043d

18 files changed

Lines changed: 110 additions & 31 deletions

CHANGES

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
Changes with Apache 2.0.40
22

3+
*) Add a filter_init parameter to the filter registration functions
4+
so that a filter can execute arbitrary code before the handlers
5+
are invoked. This resolves a problem where mod_include requests
6+
would incorrectly return a 304. [Justin Erenkrantz]
7+
38
*) Fix a long-standing bug in 2.0, CGI scripts were being called
49
with relative paths instead of absolute paths. Apache 1.3 used
510
absolute paths for everything except for SuExec, this brings back

include/ap_mmn.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,13 @@
109109
* 20020602 (2.0.37-dev) Bucket API change (metadata buckets)
110110
* 20020612 (2.0.38-dev) Changed server_rec->[keep_alive_]timeout to apr time
111111
* 20020625 (2.0.40-dev) Changed conn_rec->keepalive to an enumeration
112+
* 20020628 (2.0.40-dev) Added filter_init to filter registration functions
112113
*/
113114

114115
#define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
115116

116117
#ifndef MODULE_MAGIC_NUMBER_MAJOR
117-
#define MODULE_MAGIC_NUMBER_MAJOR 20020625
118+
#define MODULE_MAGIC_NUMBER_MAJOR 20020628
118119
#endif
119120
#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
120121

include/util_filter.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,19 @@ typedef struct ap_filter_t ap_filter_t;
153153
* for setting the association between a name for a filter and its
154154
* associated callback (and other information).
155155
*
156+
* If the initialization function argument passed to the registration
157+
* functions is non-NULL, it will be called iff the filter is in the input
158+
* or output filter chains and before any data is generated to allow the
159+
* filter to prepare for processing.
160+
*
156161
* The *bucket structure (and all those referenced by ->next and ->prev)
157162
* should be considered "const". The filter is allowed to modify the
158163
* next/prev to insert/remove/replace elements in the bucket list, but
159164
* the types and values of the individual buckets should not be altered.
160165
*
161-
* The return value of a filter should be an APR status value.
166+
* For the input and output filters, the return value of a filter should be
167+
* an APR status value. For the init function, the return value should
168+
* be an HTTP error code or OK if it was successful.
162169
*
163170
* @ingroup filter
164171
* @{
@@ -170,6 +177,7 @@ typedef apr_status_t (*ap_in_filter_func)(ap_filter_t *f,
170177
ap_input_mode_t mode,
171178
apr_read_type_e block,
172179
apr_off_t readbytes);
180+
typedef int (*ap_init_filter_func)(ap_filter_t *f);
173181

174182
typedef union ap_filter_func {
175183
ap_out_filter_func out_func;
@@ -242,6 +250,8 @@ struct ap_filter_rec_t {
242250
const char *name;
243251
/** The function to call when this filter is invoked. */
244252
ap_filter_func filter_func;
253+
/** The function to call before the handlers are invoked. */
254+
ap_init_filter_func filter_init_func;
245255
/** The type of filter, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION.
246256
* An AP_FTYPE_CONTENT filter modifies the data based on information
247257
* found in the content. An AP_FTYPE_CONNECTION filter modifies the
@@ -259,8 +269,8 @@ struct ap_filter_rec_t {
259269
* requests get an exact copy of the main requests filter chain.
260270
*/
261271
struct ap_filter_t {
262-
/** The internal representation of this filter. This includes
263-
* the filter's name, type, and the actual function pointer.
272+
/** The internal representation of this filter. This includes
273+
* the filter's name, type, and the actual function pointer.
264274
*/
265275
ap_filter_rec_t *frec;
266276

@@ -324,6 +334,7 @@ AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *filter,
324334
*/
325335
AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,
326336
ap_in_filter_func filter_func,
337+
ap_init_filter_func filter_init,
327338
ap_filter_type ftype);
328339
/**
329340
* 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,
339350
*/
340351
AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name,
341352
ap_out_filter_func filter_func,
353+
ap_init_filter_func filter_init,
342354
ap_filter_type ftype);
343355

344356
/**

modules/experimental/mod_cache.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,16 +981,19 @@ register_hooks(apr_pool_t *p)
981981
*/
982982
ap_register_output_filter("CACHE_IN",
983983
cache_in_filter,
984+
NULL,
984985
AP_FTYPE_CONTENT_SET);
985986
/* CACHE_OUT must go into the filter chain before SUBREQ_CORE to
986987
* handle subrequsts. Decrementing filter type by 1 ensures this
987988
* happens.
988989
*/
989990
ap_register_output_filter("CACHE_OUT",
990991
cache_out_filter,
992+
NULL,
991993
AP_FTYPE_CONTENT_SET-1);
992994
ap_register_output_filter("CACHE_CONDITIONAL",
993995
cache_conditional_filter,
996+
NULL,
994997
AP_FTYPE_CONTENT_SET);
995998
ap_hook_post_config(cache_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
996999
}

modules/experimental/mod_case_filter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static const command_rec CaseFilterCmds[] =
9898
static void CaseFilterRegisterHooks(apr_pool_t *p)
9999
{
100100
ap_hook_insert_filter(CaseFilterInsertFilter,NULL,NULL,APR_HOOK_MIDDLE);
101-
ap_register_output_filter(s_szCaseFilterName,CaseFilterOutFilter,
101+
ap_register_output_filter(s_szCaseFilterName,CaseFilterOutFilter,NULL,
102102
AP_FTYPE_RESOURCE);
103103
}
104104

modules/experimental/mod_case_filter_in.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ static void CaseFilterInRegisterHooks(apr_pool_t *p)
182182
{
183183
ap_hook_insert_filter(CaseFilterInInsertFilter, NULL, NULL,
184184
APR_HOOK_MIDDLE);
185-
ap_register_input_filter(s_szCaseFilterName, CaseFilterInFilter,
185+
ap_register_input_filter(s_szCaseFilterName, CaseFilterInFilter, NULL,
186186
AP_FTYPE_RESOURCE);
187187
}
188188

modules/experimental/mod_charset_lite.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,9 +1105,9 @@ static void charset_register_hooks(apr_pool_t *p)
11051105
{
11061106
ap_hook_fixups(find_code_page, NULL, NULL, APR_HOOK_MIDDLE);
11071107
ap_hook_insert_filter(xlate_insert_filter, NULL, NULL, APR_HOOK_REALLY_LAST);
1108-
ap_register_output_filter(XLATEOUT_FILTER_NAME, xlate_out_filter,
1108+
ap_register_output_filter(XLATEOUT_FILTER_NAME, xlate_out_filter, NULL,
11091109
AP_FTYPE_RESOURCE);
1110-
ap_register_input_filter(XLATEIN_FILTER_NAME, xlate_in_filter,
1110+
ap_register_input_filter(XLATEIN_FILTER_NAME, xlate_in_filter, NULL,
11111111
AP_FTYPE_RESOURCE);
11121112
}
11131113

modules/experimental/mod_ext_filter.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,12 @@ static const char *define_filter(cmd_parms *cmd, void *dummy, const char *args)
312312
*/
313313
if (filter->mode == OUTPUT_FILTER) {
314314
/* XXX need a way to ensure uniqueness among all filters */
315-
ap_register_output_filter(filter->name, ef_output_filter, AP_FTYPE_RESOURCE);
315+
ap_register_output_filter(filter->name, ef_output_filter, NULL, AP_FTYPE_RESOURCE);
316316
}
317317
#if 0 /* no input filters yet */
318318
else if (filter->mode == INPUT_FILTER) {
319319
/* XXX need a way to ensure uniqueness among all filters */
320-
ap_register_input_filter(filter->name, ef_input_filter, AP_FTYPE_RESOURCE);
320+
ap_register_input_filter(filter->name, ef_input_filter, NULL, AP_FTYPE_RESOURCE);
321321
}
322322
#endif
323323
else {

modules/filters/mod_deflate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,9 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
760760

761761
static void register_hooks(apr_pool_t *p)
762762
{
763-
ap_register_output_filter(deflateFilterName, deflate_out_filter,
763+
ap_register_output_filter(deflateFilterName, deflate_out_filter, NULL,
764764
AP_FTYPE_CONTENT_SET);
765-
ap_register_input_filter(deflateFilterName, deflate_in_filter,
765+
ap_register_input_filter(deflateFilterName, deflate_in_filter, NULL,
766766
AP_FTYPE_CONTENT_SET);
767767
}
768768

modules/filters/mod_include.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3323,6 +3323,26 @@ static const char *set_xbithack(cmd_parms *cmd, void *xbp, const char *arg)
33233323
return NULL;
33243324
}
33253325

3326+
static int includes_setup(ap_filter_t *f)
3327+
{
3328+
include_dir_config *conf =
3329+
(include_dir_config *)ap_get_module_config(f->r->per_dir_config,
3330+
&include_module);
3331+
3332+
/* When our xbithack value isn't set to full or our platform isn't
3333+
* providing group-level protection bits or our group-level bits do not
3334+
* have group-execite on, we will set the no_local_copy value to 1 so
3335+
* that we will not send 304s.
3336+
*/
3337+
if ((*conf->xbithack != xbithack_full)
3338+
|| !(f->r->finfo.valid & APR_FINFO_GPROT)
3339+
|| !(f->r->finfo.protection & APR_GEXECUTE)) {
3340+
f->r->no_local_copy = 1;
3341+
}
3342+
3343+
return OK;
3344+
}
3345+
33263346
static apr_status_t includes_filter(ap_filter_t *f, apr_bucket_brigade *b)
33273347
{
33283348
request_rec *r = f->r;
@@ -3556,7 +3576,8 @@ static void register_hooks(apr_pool_t *p)
35563576
APR_REGISTER_OPTIONAL_FN(ap_register_include_handler);
35573577
ap_hook_post_config(include_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
35583578
ap_hook_fixups(include_fixup, NULL, NULL, APR_HOOK_LAST);
3559-
ap_register_output_filter("INCLUDES", includes_filter, AP_FTYPE_RESOURCE);
3579+
ap_register_output_filter("INCLUDES", includes_filter, includes_setup,
3580+
AP_FTYPE_RESOURCE);
35603581
}
35613582

35623583
module AP_MODULE_DECLARE_DATA include_module =

0 commit comments

Comments
 (0)