Re: accessing environment variables set by other modules

Torsten Förtsch <[email protected]>
Newsgroups gmane.comp.apache.mod-perl
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.