Generic Filter Module
To enable smart, context-sensitive filtering, we propose a revised
architecture, to be implemented in a new module mod_filter:
- A generic filter harness
- Filter modules as providers
- Dispatch based on headers
The Filter Harness is a standard filter module callback that can be
inserted into the output filter chain. Its purpose is to select
a content filter conditionally based on response headers,
and dispatch to it. If no content filter is selected, the harness
will simply uninsert itself.
Note that this (slightly unusual) usage requires us to have set up
the filter context in advance and supplied it to ap_add_output_filter.
typedef struct {
const char* name ;
apr_status_t (*func)(ap_filter_t* f, apr_bucket_brigade* bb) ;
void* fctx ;
} harness_ctx ;
static apr_status_t filter_harness(ap_filter_t* f, apr_bucket_brigade* bb) {
apr_status_t ret ;
harness_ctx* ctx = f->ctx ;
/* look up a handler function if we haven't already set it */
if ( ! ctx->func ) {
ctx->func = lookup_handler(f->r, ctx->name) ;
if ( ! ctx->func ) {
ap_remove_output_filter(f) ;
return ap_pass_brigade(f->next, bb) ;
}
}
/* call the content filter with its own context, then restore our context */
f->ctx = ctx->fctx ;
ret = ctx->func(f, bb) ;
ctx->fctx = f->ctx ;
f->ctx = ctx ;
return ret ;
}
We can see from the above that an Apache 2.0 output filter can slot
comfortably into the proposed architecure, by returning its main callback
from the lookup_handler function in the above. What remains is to
update the configuration and filter hooks. mod_filter will
implement these changes.