cvs commit: modperl-2.0 STATUS
stas2003/01/14 21:22:53 Modified:.STATUS Log: an issue to resolve Revision ChangesPath 1.33 +8 -1 modperl-2.0/STATUS Index: STATUS === RCS file: /home/cvs/modperl-2.0/STATUS,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- STATUS11 Jan 2003 04:14:55 - 1.32 +++ STATUS15 Jan 2003 05:22:53 - 1.33 @@ -50,6 +50,13 @@ Needs Patch or Further Investigation: - +* Currently modperl_filter_add_{connection|request} check the filter + handler function attrs before accepting the filter. If the module + wasn't preloaded the check fails and filter handler is skipped. We + could have this issue documented (which is OK, but might raise too + many questions), but we could also always preload the filter + handlers. To test see TestFilter::input_msg + * we still have a problem with mod_perl starting from a vhost. consider the following config:
cvs commit: modperl-2.0/xs/tables/current/ModPerl FunctionTable.pm
stas2003/01/14 22:07:11 Modified:src/modules/perl modperl_filter.c modperl_filter.h modperl_types.h xs/tables/current/ModPerl FunctionTable.pm Log: - implementation of the input stream filtering support (1st phase) - code refactoring to be re-use for input and output filtering - proper support for mis-behaved feeding filters that send more than one EOS bucket Revision ChangesPath 1.43 +225 -66 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.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- modperl_filter.c 12 Jan 2003 02:21:37 - 1.42 +++ modperl_filter.c 15 Jan 2003 06:07:10 - 1.43 @@ -94,15 +94,23 @@ filter-mode = mode; filter-f = f; -filter-bb = bb; filter-pool = p; filter-wbucket.pool = p; filter-wbucket.filters = f-next; filter-wbucket.outcnt = 0; +if (mode == MP_INPUT_FILTER_MODE) { +filter-bb_in = NULL; +filter-bb_out = bb; +} +else { +filter-bb_in = bb; +filter-bb_out = NULL; +} + MP_TRACE_f(MP_FUNC, filter=0x%lx, mode=%s\n, - (unsigned long)filter, mode == MP_OUTPUT_FILTER_MODE ? - output : input); + (unsigned long)filter, + mode == MP_INPUT_FILTER_MODE ? input : output); return filter; } @@ -138,7 +146,10 @@ modperl_handler_make_args(aTHX_ args, Apache::Filter, filter-f, - APR::Brigade, filter-bb, + APR::Brigade, + (filter-mode == MP_INPUT_FILTER_MODE + ? filter-bb_out + : filter-bb_in), NULL); modperl_filter_mg_set(aTHX_ AvARRAY(args)[0], filter); @@ -168,26 +179,59 @@ filter-seen_eos = 0; } -if (filter-mode == MP_OUTPUT_FILTER_MODE) { +if (filter-mode == MP_INPUT_FILTER_MODE) { +if (filter-bb_in) { +/* in the streaming mode filter-bb_in is populated on the + * first modperl_input_filter_read, so it must be + * destroyed at the end of the filter invocation + */ +/* XXX: may be the filter must consume all the data? add a + * test to check */ +apr_brigade_destroy(filter-bb_in); +filter-bb_in = NULL; +} +modperl_input_filter_flush(filter); +} +else { modperl_output_filter_flush(filter); } + return status; } /* output filters */ -MP_INLINE static apr_status_t send_eos(ap_filter_t *f) +MP_INLINE static apr_status_t send_input_eos(modperl_filter_t *filter) +{ +apr_bucket_alloc_t *ba = filter-f-c-bucket_alloc; +apr_bucket *b = apr_bucket_eos_create(ba); +APR_BRIGADE_INSERT_TAIL(filter-bb_out, b); +((modperl_filter_ctx_t *)filter-f-ctx)-sent_eos = 1; +return APR_SUCCESS; + +} + +MP_INLINE static apr_status_t send_input_flush(modperl_filter_t *filter) +{ +apr_bucket_alloc_t *ba = filter-f-c-bucket_alloc; +apr_bucket *b = apr_bucket_flush_create(ba); +APR_BRIGADE_INSERT_TAIL(filter-bb_out, b); +return APR_SUCCESS; +} + +MP_INLINE static apr_status_t send_output_eos(ap_filter_t *f) { apr_bucket_alloc_t *ba = f-c-bucket_alloc; apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f), ba); apr_bucket *b = apr_bucket_eos_create(ba); APR_BRIGADE_INSERT_TAIL(bb, b); +((modperl_filter_ctx_t *)f-ctx)-sent_eos = 1; return ap_pass_brigade(f-next, bb); } -MP_INLINE static apr_status_t send_flush(ap_filter_t *f) +MP_INLINE static apr_status_t send_output_flush(ap_filter_t *f) { apr_bucket_alloc_t *ba = f-c-bucket_alloc; apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f), @@ -199,11 +243,14 @@ /* unrolled APR_BRIGADE_FOREACH loop */ +#define MP_FILTER_EMPTY(filter) \ +APR_BRIGADE_EMPTY(filter-bb_in) + #define MP_FILTER_SENTINEL(filter) \ -APR_BRIGADE_SENTINEL(filter-bb) +APR_BRIGADE_SENTINEL(filter-bb_in) #define MP_FILTER_FIRST(filter) \ -APR_BRIGADE_FIRST(filter-bb) +APR_BRIGADE_FIRST(filter-bb_in) #define MP_FILTER_NEXT(filter) \ APR_BUCKET_NEXT(filter-bucket) @@ -216,52 +263,83 @@ MP_INLINE static int get_bucket(modperl_filter_t *filter) { -if (!filter-bb) { +if (!filter-bb_in || MP_FILTER_EMPTY(filter)) { +MP_TRACE_f(MP_FUNC, %s
cvs commit: modperl-2.0/t/filter input_body.t
stas2003/01/14 22:08:16 Modified:t/filter input_body.t Log: no more need for XXX Revision ChangesPath 1.5 +0 -1 modperl-2.0/t/filter/input_body.t Index: input_body.t === RCS file: /home/cvs/modperl-2.0/t/filter/input_body.t,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- input_body.t 20 Dec 2001 03:54:41 - 1.4 +++ input_body.t 15 Jan 2003 06:08:16 - 1.5 @@ -4,7 +4,6 @@ use Apache::Test; use Apache::TestRequest; -#XXX: skip input_body filter test until filter changes dust settles plan tests = 2; my $location = '/TestFilter::input_body';
cvs commit: modperl-2.0/xs/Apache/Filter Apache__Filter.h
stas2003/01/14 22:11:09 Modified:xs/Apache/Filter Apache__Filter.h Log: input filters are now supported Revision ChangesPath 1.22 +21 -8 modperl-2.0/xs/Apache/Filter/Apache__Filter.h Index: Apache__Filter.h === RCS file: /home/cvs/modperl-2.0/xs/Apache/Filter/Apache__Filter.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- Apache__Filter.h 12 Jan 2003 02:33:27 - 1.21 +++ Apache__Filter.h 15 Jan 2003 06:11:08 - 1.22 @@ -26,7 +26,7 @@ mpxs_write_loop(modperl_output_filter_write, modperl_filter); } else { -Perl_croak(aTHX_ input filters not yet supported); +mpxs_write_loop(modperl_input_filter_write, modperl_filter); } /* XXX: ap_rflush if $| */ @@ -38,23 +38,36 @@ SV **MARK, SV **SP) { modperl_filter_t *modperl_filter; +ap_input_mode_t mode = 0; +apr_read_type_e block = 0; +apr_off_t readbytes = 0; apr_size_t wanted, len=0; SV *buffer; - -mpxs_usage_va_2(modperl_filter, buffer, $filter-read(buf, [len])); - -if (items 2) { + +if (items 4) { +mpxs_usage_va_2(modperl_filter, buffer, $filter-read(buf, [len])); +} +else { +modperl_filter = mp_xs_sv2_modperl_filter(*MARK); MARK++; +mode = (ap_input_mode_t)SvIV(*MARK); MARK++; +block = (apr_read_type_e)SvIV(*MARK); MARK++; +readbytes = (apr_off_t)SvIV(*MARK); MARK++; +buffer = *MARK++; +} + +if (items == 3 || items == 6) { wanted = SvIV(*MARK); } else { wanted = MP_IOBUFSIZE; } -if (modperl_filter-mode == MP_OUTPUT_FILTER_MODE) { -len = modperl_output_filter_read(aTHX_ modperl_filter, buffer, wanted); +if (modperl_filter-mode == MP_INPUT_FILTER_MODE) { +len = modperl_input_filter_read(aTHX_ modperl_filter, mode, +block, readbytes, buffer, wanted); } else { -Perl_croak(aTHX_ input filters not yet supported); +len = modperl_output_filter_read(aTHX_ modperl_filter, buffer, wanted); } return len;
cvs commit: modperl-2.0/t/filter/TestFilter in_bbs_body.pm in_bbs_msg.pm out_bbs_basic.pm out_bbs_ctx.pm out_str_api.pm out_str_ctx.pm out_str_lc.pm out_str_reverse.pm in_str_msg.pm api.pm buckets.pm context.pm context_stream.pm input_body.pm input_msg.pm lc.pm reverse.pm
stas2003/01/14 22:47:16 Modified:t/filter/TestFilter in_str_msg.pm Added: t/filter in_bbs_body.t in_bbs_msg.t out_bbs_basic.t out_bbs_ctx.t out_str_api.t out_str_ctx.t out_str_lc.t out_str_reverse.t t/filter/TestFilter in_bbs_body.pm in_bbs_msg.pm out_bbs_basic.pm out_bbs_ctx.pm out_str_api.pm out_str_ctx.pm out_str_lc.pm out_str_reverse.pm Removed: t/filter context.t context_stream.t input_body.t input_msg.t lc.t reverse.t t/filter/TestFilter api.pm buckets.pm context.pm context_stream.pm input_body.pm input_msg.pm lc.pm reverse.pm Log: rename filter tests so it's easy to test what kind of filter is run from its name (also to tell the streaming interface from BBs.) Revision ChangesPath 1.1 modperl-2.0/t/filter/in_bbs_body.t Index: in_bbs_body.t === use strict; use warnings FATAL = 'all'; use Apache::Test; use Apache::TestRequest; plan tests = 2; my $location = '/TestFilter::in_bbs_body'; for my $x (1,2) { my $data = scalar reverse ok $x\n; print POST_BODY $location, content = $data; } 1.1 modperl-2.0/t/filter/in_bbs_msg.t Index: in_bbs_msg.t === use Apache::TestRequest; use Apache::Test (); use Apache::TestUtil; my $module = 'TestFilter::in_bbs_msg'; Apache::TestRequest::scheme('http'); #force http for t/TEST -ssl Apache::TestRequest::module($module); my $config = Apache::Test::config(); my $hostport = Apache::TestRequest::hostport($config); t_debug(connecting to $hostport); print GET_BODY(/input_filter.html); 1.1 modperl-2.0/t/filter/out_bbs_basic.t Index: out_bbs_basic.t === # WARNING: this file is generated, do not edit # 01: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:696 # 02: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:713 # 03: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfigPerl.pm:83 # 04: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfigPerl.pm:407 # 05: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:407 # 06: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:422 # 07: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:1215 # 08: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRun.pm:398 # 09: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRunPerl.pm:32 # 10: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRun.pm:569 # 11: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRun.pm:569 # 12: t/TEST:19 use Apache::TestRequest 'GET_BODY'; print GET_BODY /TestFilter::out_bbs_basic; 1.1 modperl-2.0/t/filter/out_bbs_ctx.t Index: out_bbs_ctx.t === use strict; use warnings FATAL = 'all'; use Apache::Test; use Apache::TestRequest; use Apache::TestUtil; plan tests = 1; my $blocks = 33; my $invoked = 100; my $sig = join \n, received $blocks complete blocks, filter invoked $invoked times\n; my $data = # x $blocks . x x $blocks; my $expected = join \n, $data, $sig; { # test the filtering of the mod_perl response handler my $location = '/TestFilter::out_bbs_ctx'; my $response = GET_BODY $location; ok t_cmp($expected, $response, context filter); } 1.1 modperl-2.0/t/filter/out_str_api.t Index: out_str_api.t === # WARNING: this file is generated, do not edit # 01: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:696 # 02: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:713 # 03: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfigPerl.pm:83 # 04: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfigPerl.pm:407 # 05: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:407 # 06: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:422 # 07: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:1215 # 08: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRun.pm:398 # 09: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRunPerl.pm:32 # 10: