dougm 01/04/19 10:44:22 Modified: src/modules/perl mod_perl.c modperl_filter.c modperl_filter.h Log: register/run PerlInputFilterHandlers Revision Changes Path 1.48 +30 -2 modperl-2.0/src/modules/perl/mod_perl.c Index: mod_perl.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v retrieving revision 1.47 retrieving revision 1.48 diff -u -r1.47 -r1.48 --- mod_perl.c 2001/04/12 16:15:19 1.47 +++ mod_perl.c 2001/04/19 17:44:15 1.48 @@ -221,6 +221,11 @@ */ } +static int modperl_hook_pre_connection(conn_rec *c) +{ + return modperl_input_filter_register_connection(c); +} + static void modperl_hook_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { @@ -246,10 +251,23 @@ return OK; } +static int modperl_hook_post_read_request(request_rec *r) +{ + return modperl_input_filter_register_request(r); +} + +static int modperl_hook_header_parser(request_rec *r) +{ + return modperl_input_filter_register_request(r); +} + void modperl_register_hooks(apr_pool_t *p) { ap_hook_open_logs(modperl_hook_init, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(modperl_hook_post_config, NULL, NULL, + APR_HOOK_MIDDLE); + ap_hook_handler(modperl_response_handler, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_insert_filter(modperl_output_filter_register, @@ -259,11 +277,21 @@ modperl_output_filter_handler, AP_FTYPE_CONTENT); + ap_register_input_filter(MODPERL_INPUT_FILTER_NAME, + modperl_input_filter_handler, + AP_FTYPE_CONTENT); + + ap_hook_pre_connection(modperl_hook_pre_connection, + NULL, NULL, APR_HOOK_FIRST); + ap_hook_create_request(modperl_hook_create_request, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_post_config(modperl_hook_post_config, NULL, NULL, - APR_HOOK_MIDDLE); + ap_hook_post_read_request(modperl_hook_post_read_request, NULL, NULL, + APR_HOOK_FIRST); + + ap_hook_header_parser(modperl_hook_header_parser, NULL, NULL, + APR_HOOK_FIRST); modperl_register_handler_hooks(); } 1.12 +121 -3 modperl-2.0/src/modules/perl/modperl_filter.c Index: modperl_filter.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- modperl_filter.c 2001/04/18 04:37:46 1.11 +++ modperl_filter.c 2001/04/19 17:44:17 1.12 @@ -79,7 +79,7 @@ return filter; } -int modperl_run_filter(modperl_filter_t *filter) +int modperl_run_filter(modperl_filter_t *filter, ap_input_mode_t mode) { AV *args = Nullav; int status; @@ -88,7 +88,7 @@ request_rec *r = filter->f->r; conn_rec *c = filter->f->c; - server_rec *s = r ? r->server : NULL; + server_rec *s = r ? r->server : c->base_server; apr_pool_t *p = r ? r->pool : c->pool; MP_dINTERP_SELECT(r, c, s); @@ -98,6 +98,10 @@ "APR::Brigade", filter->bb, NULL); + if (filter->mode == MP_INPUT_FILTER_MODE) { + av_push(args, newSViv(mode)); + } + if ((status = modperl_callback(aTHX_ handler, p, s, args)) != OK) { status = modperl_errsv(aTHX_ status, r, s); } @@ -319,7 +323,7 @@ } else { filter = modperl_filter_new(f, bb, MP_OUTPUT_FILTER_MODE); - status = modperl_run_filter(filter); + status = modperl_run_filter(filter, 0); } switch (status) { @@ -332,6 +336,32 @@ } } +apr_status_t modperl_input_filter_handler(ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t mode) +{ + modperl_filter_t *filter; + int status; + + if (APR_BRIGADE_IS_EOS(bb)) { + /* XXX: see about preventing this in the first place */ + MP_TRACE_f(MP_FUNC, "first bucket is EOS, skipping callback\n"); + return APR_SUCCESS; + } + else { + filter = modperl_filter_new(f, bb, MP_INPUT_FILTER_MODE); + status = modperl_run_filter(filter, mode); + } + + switch (status) { + case OK: + case DECLINED: + return APR_SUCCESS; + default: + return status; /*XXX*/ + } +} + void modperl_output_filter_register(request_rec *r) { MP_dDCFG; @@ -348,7 +378,95 @@ ap_add_output_filter(MODPERL_OUTPUT_FILTER_NAME, (void*)ctx, r, r->connection); } + + return; + } + + MP_TRACE_h(MP_FUNC, "no OutputFilter handlers configured (%s)\n", + r->uri); +} + +int modperl_input_filter_register_connection(conn_rec *c) +{ + modperl_config_dir_t *dcfg = + modperl_config_dir_get_defaults(c->base_server); + MpAV *av; + + if ((av = dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER])) { + modperl_handler_t **handlers = (modperl_handler_t **)av->elts; + int i; + + for (i=0; i<av->nelts; i++) { + modperl_filter_ctx_t *ctx = + (modperl_filter_ctx_t *)apr_pcalloc(c->pool, sizeof(*ctx)); + ctx->handler = handlers[i]; + ap_add_input_filter(MODPERL_INPUT_FILTER_NAME, + (void*)ctx, NULL, c); + } + + return OK; } + + MP_TRACE_h(MP_FUNC, "no InputFilter handlers configured (connection)\n"); + + return DECLINED; +} + +int modperl_input_filter_register_request(request_rec *r) +{ + MP_dDCFG; + MpAV *av; + + if ((av = dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER])) { + modperl_handler_t **handlers = (modperl_handler_t **)av->elts; + int i; + + for (i=0; i<av->nelts; i++) { + modperl_filter_ctx_t *ctx; + int registered = 0; + ap_filter_t *f = r->connection->input_filters; + + while (f) { + const char *name = f->frec->name; + + if (*name == 'M' && strEQ(name, MODPERL_INPUT_FILTER_NAME)) { + modperl_handler_t *ctx_handler = + ((modperl_filter_ctx_t *)f->ctx)->handler; + + if (modperl_mgv_equal(ctx_handler->mgv_cv, + handlers[i]->mgv_cv)) { + /* skip if modperl_input_filter_register_connection + * already registered this handler + * XXX: set a flag in the modperl_handler_t instead + */ + registered = 1; + break; + } + } + + f = f->next; + } + + if (registered) { + MP_TRACE_f(MP_FUNC, + "%s InputFilter already registered\n", + handlers[i]->name); + continue; + } + + ctx = (modperl_filter_ctx_t *)apr_pcalloc(r->pool, sizeof(*ctx)); + ctx->handler = handlers[i]; + ap_add_input_filter(MODPERL_INPUT_FILTER_NAME, + (void*)ctx, r, r->connection); + } + + return OK; + } + + MP_TRACE_h(MP_FUNC, "no InputFilter handlers configured (%s)\n", + r->uri); + + return DECLINED; } void modperl_brigade_dump(apr_bucket_brigade *bb, FILE *fp) 1.3 +14 -1 modperl-2.0/src/modules/perl/modperl_filter.h Index: modperl_filter.h =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- modperl_filter.h 2001/01/20 21:19:08 1.2 +++ modperl_filter.h 2001/04/19 17:44:17 1.3 @@ -2,7 +2,11 @@ #define MODPERL_FILTER_H #define MODPERL_OUTPUT_FILTER_NAME "MODPERL_OUTPUT" +#define MODPERL_INPUT_FILTER_NAME "MODPERL_INPUT" +#define MP_INPUT_FILTER_MESSAGE 0x01 +#define MP_INPUT_FILTER_BODY 0x02 + /* simple buffer api */ MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *b, const char *buf, apr_ssize_t len); @@ -19,7 +23,7 @@ apr_bucket_brigade *bb, modperl_filter_mode_e mode); -int modperl_run_filter(modperl_filter_t *filter); +int modperl_run_filter(modperl_filter_t *filter, ap_input_mode_t mode); MP_INLINE modperl_filter_t *modperl_sv2filter(pTHX_ SV *sv); @@ -41,5 +45,14 @@ apr_ssize_t *len); void modperl_brigade_dump(apr_bucket_brigade *bb, FILE *fp); + +/* input filters */ +apr_status_t modperl_input_filter_handler(ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t mode); + +int modperl_input_filter_register_connection(conn_rec *c); + +int modperl_input_filter_register_request(request_rec *r); #endif /* MODPERL_FILTER_H */