-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Friday 22 October 2004 00:38, Stas Bekman wrote:
> Torsten F�rtsch wrote:
> > + � �if( f->c ) {
> > +�����for( list=f->c->input_filters; list; list=list->next ) {
> > +����� � �if( list==f ) {
> > +�������������ap_remove_input_filter(f);
> > +�������������return;
> > +����� � �}
> > +�����}
> > + � �}
>
> [ snipped other filter chains traversals ]
>
> but why do you need to traverse all these lists? is it because we don't
> know whether the given filter is an input filter or output one? May be
> it's easier to attach some flag to the filter object to say which kind of
> filter is that?
I thought about it this night and realized that I need not to traverse these
lists at all. At first ist was a try to guess what to call
ap_input_filter_remove or ap_output_filter_remove. But if the filter is not
in an appropriate chain these functions do simply nothing. Hence I can call
them both if I don't know what kind of filter it is.
> > +static MP_INLINE
> > �void mpxs_Apache__Filter_remove(pTHX_ I32 items, SV **MARK, SV **SP)
> > �{
> > � � �modperl_filter_t *modperl_filter;
> > � � �ap_filter_t *f;
> > �
> > - � �mpxs_usage_va_1(modperl_filter, "$filter->remove()");
> > + � �if (items < 1) {
> > + � � � �Perl_croak(aTHX_ "usage: $filter->remove()");
> > + � �}
> > +
> > + � �modperl_filter = mp_xs_sv2_modperl_filter(*MARK);
> > +
> > + � �if( !modperl_filter ) {��/* native filter */
> > + � � � �mpxs_Apache__Filter_remove_native_filter(aTHX_
> > (ap_filter_t*)SvIV(SvRV(*MARK))); +�����return;
> > + � �}
> > +
> > � � �f = modperl_filter->f;
> > �
> > � � �MP_TRACE_f(MP_FUNC, " � %s\n\n\tfilter removes itself\n",
>
> Also if you could add a test, that will save some time to us. e.g. take
> the t/filter/TestFilter/both_str_req_mix.pm as the base (could probably
> simplify it a bit to just test that it can be removed both on input and
> output). to make your work easier you could just start messing with this
> test and then post it or if you know A-T better you could start a new test
The attached patch contains the updated Apache__Filter.h and a test that
removes INCLUDES from the output chain and DEFLATE from input.
Torsten
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFBeQbrwicyCTir8T4RAtq3AJ9Gpdal0wooCpAST5MYY92dJmueLwCfffB8
KnDaSw1Xs7JDLBQNICt0b5Y=
=YYFu
-----END PGP SIGNATURE-----
diff -Naur mod_perl-1.99_16.orig/t/filter/TestFilter/both_str_native_remove.pm mod_perl-1.99_16/t/filter/TestFilter/both_str_native_remove.pm
--- mod_perl-1.99_16.orig/t/filter/TestFilter/both_str_native_remove.pm 1970-01-01 01:00:00.000000000 +0100
+++ mod_perl-1.99_16/t/filter/TestFilter/both_str_native_remove.pm 2004-10-22 15:03:31.740525400 +0200
@@ -0,0 +1,128 @@
+package TestFilter::both_str_native_remove;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache::RequestRec ();
+use Apache::RequestIO ();
+
+use Apache::Filter ();
+use Apache::FilterRec ();
+
+use Apache::Const -compile => qw(OK DECLINED);
+
+# this filter removes the next filter in chain and itself
+sub remove_next_filter {
+ my $f = shift;
+
+ if( $f->r->args=~/remove/ ) {
+ $f->next->remove;
+ }
+ $f->remove;
+ return Apache::DECLINED;
+}
+
+# this filter removes the next filter in chain and itself
+sub remove_deflate {
+ my $f = shift;
+
+ if( $f->r->args=~/remove/ ) {
+ for( my $ff=$f->r->input_filters; $ff; $ff=$ff->next ) {
+ if( $ff->frec->name eq 'deflate' ) {
+ $ff->remove;
+ last;
+ }
+ }
+ }
+ $f->remove;
+ return Apache::DECLINED;
+}
+
+# this filter inserts the current filter list at eos
+sub insert_filter_list {
+ my $f = shift;
+
+ unless( $f->ctx ) {
+ $f->ctx(1);
+ $f->r->headers_out->unset('Content-Length');
+ }
+
+ while ($f->read(my $buffer, 1024)) {
+ $f->print($buffer);
+ }
+
+ if ($f->seen_eos) {
+ my @flist;
+ for( my $f=$f->r->output_filters; $f; $f=$f->next ) {
+ push @flist, $f->frec->name;
+ }
+ {local $"=','; $f->print("flist2: @flist\n");}
+ }
+
+ return Apache::OK;
+}
+
+sub input_filter_list {
+ my $f = shift;
+
+ unless ($f->ctx) {
+ my @flist;
+ for( my $f=$f->r->input_filters; $f; $f=$f->next ) {
+ push @flist, $f->frec->name;
+ }
+ my $x=$f->r->pnotes('INPUT_FILTERS')||[];
+ {local $"=','; push @{$x}, "@flist";}
+ $f->r->pnotes('INPUT_FILTERS'=>$x);
+ }
+
+ return Apache::DECLINED;
+}
+
+
+sub response {
+ my $r = shift;
+
+ # just to make sure that print() won't flush, or we would get the
+ # count wrong
+ local $| = 0;
+
+ $r->content_type('text/plain');
+ if ($r->method_number == Apache::M_POST) {
+ $r->print( "content: ".ModPerl::Test::read_post($r)."\n" );
+ }
+
+ my $i=1;
+ foreach my $x (@{$r->pnotes('INPUT_FILTERS')||[]}) {
+ $r->print("fin$i: $x\n");
+ $i++;
+ }
+
+ $r->subprocess_env( SSI_TEST=>'SSI OK' );
+ my @flist;
+ for( my $f=$r->output_filters; $f; $f=$f->next ) {
+ push @flist, $f->frec->name;
+ }
+ {local $"=','; $r->print("flist1: @flist\n");}
+ $r->rflush; # this sends the data in the buffer + flush bucket
+ $r->print('x<!--#echo var=');
+ $r->rflush; # this sends the data in the buffer + flush bucket
+ $r->print('"SSI_TEST" -->x'."\n");
+
+ Apache::OK;
+}
+1;
+__DATA__
+Options +Includes
+SetHandler modperl
+PerlModule TestFilter::both_str_native_remove
+PerlResponseHandler TestFilter::both_str_native_remove::response
+PerlOutputFilterHandler TestFilter::both_str_native_remove::remove_next_filter
+PerlSetOutputFilter INCLUDES
+PerlOutputFilterHandler TestFilter::both_str_native_remove::insert_filter_list
+PerlInputFilterHandler TestFilter::both_str_native_remove::input_filter_list
+PerlInputFilterHandler TestFilter::both_str_native_remove::remove_deflate
+PerlSetInputFilter DEFLATE
+PerlInputFilterHandler TestFilter::both_str_native_remove::input_filter_list
diff -Naur mod_perl-1.99_16.orig/t/filter/both_str_native_remove.t mod_perl-1.99_16/t/filter/both_str_native_remove.t
--- mod_perl-1.99_16.orig/t/filter/both_str_native_remove.t 1970-01-01 01:00:00.000000000 +0100
+++ mod_perl-1.99_16/t/filter/both_str_native_remove.t 2004-10-22 15:02:58.332604176 +0200
@@ -0,0 +1,63 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests =>8, need 'deflate', 'include',
+ need_min_module_version("Compress::Zlib", "1.09");
+
+require Compress::Zlib;
+
+my ($location, $response, $expected, $t);
+
+
+# 1. check if DEFLATE input and INCLUDES output filter work
+
+$location = '/TestFilter__both_str_native_remove';
+$response = POST_BODY $location,
+ content=>Compress::Zlib::memGzip('gzipped text'),
+ 'Content-Encoding' => "gzip";
+
+$expected = 'xSSI OKx';
+($t)=$response=~/^(xSSI OKx)$/m;
+ok t_cmp($t, $expected, "check if INCLUDES work");
+
+$expected = 'gzipped text';
+($t)=$response=~/^content: (gzipped text)$/m;
+ok t_cmp($t, $expected, "check if DEFLATE input work");
+
+
+
+# 2. check if DEFLATE input and INCLUDES output filter can be removed
+
+$location = '/TestFilter__both_str_native_remove?remove';
+$response = POST_BODY $location, content=>'plain text';
+
+$expected = 'modperl_request_output,includes,modperl_request_output,';
+($t)=$response=~/^flist1: (modperl_request_output,includes,modperl_request_output,)/m;
+ok t_cmp($t, $expected, "check if INCLUDES is present");
+
+$expected = 'modperl_request_output,';
+($t)=$response=~/^flist2: (modperl_request_output,)(?!includes)/m;
+ok t_cmp($t, $expected, "check if INCLUDES is removed");
+
+$expected = 'x<!--#echo var="SSI_TEST" -->x';
+($t)=$response=~/^(x<!--#echo var="SSI_TEST" -->x)$/m;
+ok t_cmp($t, $expected, "check if INCLUDES does not work");
+
+$expected = 'deflate';
+($t)=$response=~/^fin1: \S+,(deflate),\S+/m;
+ok t_cmp($t, $expected, "check if DEFLATE is present");
+
+$expected = undef;
+($t)=$response=~/^fin2: \S+,(deflate),\S+/m;
+ok t_cmp($t, $expected, "check if DEFLATE is removed");
+
+$expected = 'plain text';
+($t)=$response=~/^content: (plain text)$/m;
+ok t_cmp($t, $expected, "check if DEFLATE input does not work");
+
+
+
diff -Naur mod_perl-1.99_16.orig/xs/Apache/Filter/Apache__Filter.h mod_perl-1.99_16/xs/Apache/Filter/Apache__Filter.h
--- mod_perl-1.99_16.orig/xs/Apache/Filter/Apache__Filter.h 2004-07-12 09:32:07.000000000 +0200
+++ mod_perl-1.99_16/xs/Apache/Filter/Apache__Filter.h 2004-10-22 15:04:09.586771896 +0200
@@ -282,7 +282,24 @@
modperl_filter_t *modperl_filter;
ap_filter_t *f;
- mpxs_usage_va_1(modperl_filter, "$filter->remove()");
+ if (items < 1) {
+ Perl_croak(aTHX_ "usage: $filter->remove()");
+ }
+
+ modperl_filter = mp_xs_sv2_modperl_filter(*MARK);
+
+ if( !modperl_filter ) { /* native filter */
+ f=(ap_filter_t*)SvIV(SvRV(*MARK));
+
+ /* the filter can reside in only one chain. hence we try to remove */
+ /* it first from the input chains then from the output chains. */
+ /* too bad, ap_*_remove_filter are void functions. so, there is no */
+ /* way to check if the filter is successfully removed. */
+ ap_remove_input_filter(f);
+ ap_remove_output_filter(f);
+ return;
+ }
+
f = modperl_filter->f;
MP_TRACE_f(MP_FUNC, " %s\n\n\tfilter removes itself\n",
--
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html