You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@perl.apache.org by barries <ba...@slaysys.com> on 2001/05/23 00:06:22 UTC

Re: First class PerlFilters?

On Tue, May 22, 2001 at 10:56:42AM -0700, dougm@apache.org wrote:
> as i mentioned before, there will be a Perl api that provides the
> functionality/control of the C api.

Not trying to make you repeat yourself, just seeing if I'm thinking
remotely sanely about the issues.

> will probably also support
> $r->push_handlers(Perl{Input,Output}FilterHandler, ...)
>
> glad you're looking at this stuff, things are still pretty wide open at
> this point, in terms of what can be changed/added/etc.

Cool.  After further thought, it struck me that the
Perl{Input,Output}Filter could be reduced to a PerlModule +
Set{Input,Output}Filter semantic:

<Location /blah>
    PerlModule My::AlgaeFilter::handler
    SetOutputFilter My::AlgaeFilter::handler
    ...

.  This is like the PerlFilterHandler you documented in modperl_2.0.pod,
I think.  So I guess I'm jumping the gun thinking about this functionality.

Thinking about this a bit more, though, I think I've missed something.
I thought that the filter handlers were called once per request (unlike
C filters), since there seemed to be no mechanism to differentiate EOS
buckets from 0 bytes remaining in the brigade. So that patch I sent in
is broken, D'oh.

Should Apache::Filter::read() return undef when an EOS is found,
enabling handlers like

   sub filter_handler {
       my $f = shift ;
       my $c ;
       while ($c = $f->read( my $b ) ) {
	   $f->print( "whatever" ) ;
       }
       $self->print( "footer" ) unless defined $c ;
   }

?  Hmmm, how then to insert a header?  Or is the intent of
modperl_filter_ctx_t.data to have context to pass to filter subs for
just this sort of thing?  Thinking in an event-driven fashion, it seems
like a state flag needs to be passed indicating "first", "middle",
"last"

   sub handler {
      my ( $f, $state ) = @_ ;
      $f->print( "header" ) if $state->{first} ;
      while ( $f->read( my $b ) ) {
         $state->{c} += length $b ;
	 $f->print( "body" ) ;
      }
      $f->print( ( $b || 0 ), "bytes in body" ) if $state->{last} ;
   }


or filter ctor might be needed:

   use base qw(Apache::Filter) ;

   sub new {
       my $class = shift 
       my $self = bless {}, $class ;
       $self->{FOO} = "BAR" ;
       $self->{FIRST} = 1 ;
       return $self ;
   }

   sub handler {
       my $self = shift ;

       $self->print( "header" ) if $self->{FIRST} ;
       $self->{FIRST} &&= 0 ;
       my $c ;
       while ( $c = $self->read( my $buf ) ) {
           $self->print( "body" ) ;
       }

       $self->print( "footer" ) unless defined $c ;
   }

'course you've probably already planned this out and I'm just playing
catchup with some wild & wierd guesses.

> p.s.
> please use dev@perl.apache.org in the future

Gack, thought I'd CCed it, sorry about that.  Fixed now.

Backgrounder for those not CCed on the first message: I asked Doug about
the possibility of exposing filter subs into Apache's filter registry by
registering all subs with appropriate CODE attributes using the name
__PACKAGE__ . "::sub_name", so

   package My::Filter ;
   sub handler: OutputContentFilter { # fictitious attr name
      ...
   }

would get registered as "My::Filter::handler" and then the normal httpd
directives for controlling filters could be used:

<Location /blah>
    SetOutputFilter My::Fitler::handler
    ...

or, when the inevitible filter controls accrete to mod_rewite, Perl
filters could be manipulated there, as well as the
ap_add_output_filter() call that the above push_handler() would
presumably wrap.

- Barrie

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org