On Thursday 15 April 2010 11:10:49 Chris Datfung wrote:
> Thanks, subprocess_env works when just using a response handler. When used
> with a filter I get the following error message:
> 
> ==================================================================
> [Thu Apr 15 11:47:34 2010] [error] [client 127.0.0.1] Can't locate object
> method "subprocess_env" via package "Apache2::Filter" at
> /opt/modperl//TE/ST.pm line 40.\n
> [Thu Apr 15 11:47:34 2010] [debug] core.c(3765): [client 127.0.0.1]
> (500)Unknown error 500: default_handler: ap_pass_brigade returned 500
> [Thu Apr 15 11:47:34 2010] [error] [client 127.0.0.1] Can't locate object
> method "subprocess_env" via package "Apache2::Filter" at
> /opt/modperl//TE/ST.pm line 40.\n
> ==================================================================
> 
> Can I test the script to use Apache2:RequestRec for the subprocess_env?

This is a RTFM question, you know?

  http://perl.apache.org/docs/2.0/api/Apache2/Filter.html#C_r_
> 
> The source of the package is as follows:
> ==================================================================
> package TE::ST;
> 
> use strict;
> use warnings;
> use Apache2::Filter ();
> use Apache2::RequestRec ();
> use Apache2::RequestIO ();
> use APR::Table ();
> 
> BEGIN { push @INC, "/opt/modperl/"; }
> 
> use Apache2::Const -compile => qw(OK);
> use constant BUFF_LEN => 1024;
> 
> sub handler
> {
>     my $f = shift;
>     $f->subprocess_env;
>     my $envar = $ENV{TE};
> 
> 
>     unless ($f->ctx)
>     {
>         while ($f->read(my $buffer, BUFF_LEN))
>         {
>             $buffer =~ s/It/Chris/g;
>             $buffer .= "[" . $envar . "]";
>             $f->print($buffer);
>         }
>         return Apache2::Const::OK;
>     }

This will probably not do what you want.

1) It will not change It into Chris at block boundaries. That means

   nth block | (n+1) block
         ...I t...

will not be changed into

   nth block | (n+1) block
         ...C hris...

2) While it may look like a pull-model (due to $f->read) Apache actually uses 
a push-model for output. A filter is passed one chunk of data (called a bucket 
brigade) at a time. $f->read reads only from the current brigade. When you are 
writing a filter think you are implementing something like the C functions 
write(2) or better writev(2). For a particular output stream your function is 
called many times. Each time it is passed a certain chunk of data. In case of 
writev it gets a list of pointers and lengths and should write all these data 
blocks to some file. In case of an Apache filter it is passed a brigade which 
is something similar to a list of pointer, length pairs. What $f->read does, 
it simplifies the reading of data from one of these lists.

Now, with that in mind reread the following chapter, especially the bottom 
half.
http://perl.apache.org/docs/2.0/user/handlers/filters.html#Stream_oriented_Output_Filters

Another useful resource may be http://www.apachetutor.org/dev/brigades

Torsten Förtsch

-- 
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net

Reply via email to