trying to add header field using PerlInputFilterHandler to proxy packets

This is a multi-part message in MIME format.

------_=_NextPart_001_01C9F927.7E157A1A
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

I am running an apache server 2.2.3 on CentOS 5.2. I have turned on the
proxy with the following lines from my apache.conf:

<IfModule mod_proxy.c>
ProxyRequests On
<Proxy *>
Order deny,allow
Deny from all
Allow from all
</Proxy>
</IfModule>

I would like to add a header field to all requests going through the
proxy. After doing a bunch of reading it seemed that setting up a
PerlInputFilterHandler was the right thing to do. I added the following
lines to the apache.conf

PerlModule company::AddHeader
PerlInputFilterHandler company::AddHeader

and I wrote the following example handler

package company::AddHeader;

use strict;
use warnings;

use Apache2::Filter ();
use Apache2::RequestRec ();
use APR::Table ();

use Apache2::Const -compile =3D> qw(OK DECLINED);

my $debug =3D 1;

sub handler {
my $f =3D shift;

# if we have already seen this do nothing
return Apache2::Const::DECLINED if $f->ctx;

# get headers
my $headers_in =3D $f->r->headers_in();

# add header field
$headers_in->set("Message","Hi Mom");
$f->r->headers_in($headers_in);

if($debug)
{
open FILE, ">>/tmp/out.log" or die $!;
foreach my $key (keys %{$headers_in})
{
print FILE "$key =3D $headers_in->{$key}\n";
}
close FILE;
}

$f->ctx(1);

return Apache2::Const::OK;
}
1;

As you can see, if debugging is turned on the headers are written to the
file /tmp/out.log. The contents of out.log contains the new header, but
the requests being forwarded by the proxy don't seem to be altered. Why
is the new header not being sent?

I am pretty sure I am missing something very simple, but have spent a
day trying to figure out what it is. Any ideas?

cheers,
Brandon




------_=_NextPart_001_01C9F927.7E157A1A
Content-Type: text/html;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Dus-ascii">
<META content=3D"MSHTML 6.00.6000.16809" name=3DGENERATOR></HEAD>
<BODY>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN =
class=3D910094901-30062009>I am
running an apache server 2.2.3 on CentOS 5.2.  I have turned on the =
proxy
with the following lines from my apache.conf:</SPAN></SPAN></SPAN></DIV>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN =
class=3D910094901-30062009><FONT
face=3DArial size=3D2></FONT></SPAN></SPAN></SPAN> </DIV>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN
class=3D910094901-30062009><IfModule mod_proxy.c><BR>ProxyRequests =

On</SPAN></SPAN></SPAN></DIV>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN
class=3D910094901-30062009><Proxy *><BR>    Order
deny,allow<BR>    Deny from all<BR>    =
Allow from
all<BR></Proxy></SPAN></SPAN></SPAN></DIV>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN
class=3D910094901-30062009></IfModule></SPAN></SPAN></SPAN></DIV>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN =
class=3D910094901-30062009><FONT
face=3DArial size=3D2></FONT></SPAN></SPAN></SPAN> </DIV>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN =
class=3D910094901-30062009>I would
like to add a header field to all requests =
going through the
proxy.  After doing a bunch of reading it seemed that setting
up a PerlInputFilterHandler was the right thing to do.  I =
added the
following lines to the apache.conf</SPAN></SPAN></SPAN></DIV>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN =
class=3D910094901-30062009><FONT
face=3DArial size=3D2></FONT></SPAN></SPAN></SPAN> </DIV>
<DIV><SPAN><SPAN class=3D891515216-14072008><SPAN =
class=3D910094901-30062009><FONT
face=3DArial>PerlModule company::AddHeader<BR>PerlInputFilterHandler
company::AddHeader </FONT></DIV>
<DIV><FONT face=3DArial></FONT> </DIV>
<DIV><SPAN class=3D910094901-30062009></SPAN><FONT face=3DArial><FONT =
size=3D2>a<SPAN
class=3D910094901-30062009>nd I wrote the following example
handler</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN
class=3D910094901-30062009></SPAN></FONT></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>package
company::AddHeader;</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>use
strict;<BR>use warnings;</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>use
Apache2::Filter ();<BR>use Apache2::RequestRec ();<BR>use APR::Table
();</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>use
Apache2::Const -compile =3D> qw(OK =
DECLINED);</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>my $debug =3D
1;</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>sub handler
{<BR>  my $f =3D shift;</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>  # if we
have already seen this do nothing<BR>  return =
Apache2::Const::DECLINED if
$f->ctx;</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>  # get
headers<BR>  my $headers_in =3D
$f->r->headers_in();</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>  # add
header field<BR>  $headers_in->set("Message","Hi =
Mom");<BR> 
$f->r->headers_in($headers_in);</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009> 
if($debug)<BR>  {<BR>    open FILE, =
">>/tmp/out.log"
or die $!;<BR>    foreach my $key (keys
%{$headers_in})<BR>    =
{<BR>      print
FILE "$key =3D $headers_in->{$key}\n";<BR>   
}<BR>    close FILE;<BR>  =
}</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009> 
$f->ctx(1);</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>  return
Apache2::Const::OK;<BR>}<BR>1;<BR></SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>As you can
see, if debugging is turned on the headers are written to the file
/tmp/out.log.  The contents of out.log contains the new header, but =
the
requests being forwarded by the proxy don't seem to be altered.  =
Why is the
new header not being sent?</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN
class=3D910094901-30062009></SPAN></FONT></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN =
class=3D910094901-30062009>I am pretty
sure I am missing something very simple, but have spent a day trying to =
figure
out what it is.  Any ideas?</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN
class=3D910094901-30062009></SPAN></FONT></FONT> </DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN
class=3D910094901-30062009>cheers,</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN
class=3D910094901-30062009>Brandon</SPAN></FONT></FONT></DIV>
<DIV><FONT face=3DArial><FONT size=3D2><SPAN
class=3D910094901-30062009> </DIV></SPAN></FONT>
<DIV><FONT =
size=3D2></FONT><BR></DIV></FONT></SPAN></SPAN></SPAN></BODY></HTML>

------_=_NextPart_001_01C9F927.7E157A1A--
Brandon Allgood [ Di, 30 Juni 2009 04:07 ] [ ID #2006903 ]

Re: trying to add header field using PerlInputFilterHandler to proxy packets

On Tue 30 Jun 2009, Brandon Allgood wrote:
> PerlInputFilterHandler company::AddHeader
> =A0
> and I wrote the following example handler
> =A0
> package company::AddHeader;
> =A0
> use strict;
> use warnings;
> =A0
> use Apache2::Filter ();
> use Apache2::RequestRec ();
> use APR::Table ();
> =A0
> use Apache2::Const -compile =3D> qw(OK DECLINED);
> =A0
> my $debug =3D 1;
> =A0
> sub handler {
> =A0 my $f =3D shift;
> =A0
> =A0 # if we have already seen this do nothing
> =A0 return Apache2::Const::DECLINED if $f->ctx;
> =A0
> =A0 # get headers
> =A0 my $headers_in =3D $f->r->headers_in();
> =A0
> =A0 # add header field
> =A0 $headers_in->set("Message","Hi Mom");
> =A0 $f->r->headers_in($headers_in);
> =A0
> =A0 if($debug)
> =A0 {
> =A0 =A0 open FILE, ">>/tmp/out.log" or die $!;
> =A0 =A0 foreach my $key (keys %{$headers_in})
> =A0 =A0 {
> =A0 =A0 =A0 print FILE "$key =3D $headers_in->{$key}\n";
> =A0 =A0 }
> =A0 =A0 close FILE;
> =A0 }
> =A0
> =A0 $f->ctx(1);
> =A0
> =A0 return Apache2::Const::OK;
> }
> 1;
>
> As you can see, if debugging is turned on the headers are written to
> the file /tmp/out.log. =A0The contents of out.log contains the new
> header, but the requests being forwarded by the proxy don't seem to
> be altered. =A0Why is the new header not being sent?

A request level input filter is called when the request body is read.
mod_proxy does this obviously *after* sending the request header to the
backend server. Hence, adding an input header at this time is too late.

Why do you want to do that in a filter? Why don't you add it in a
request phase prior to response. Fixup would be a good place for
example.

PerlFixupHandler "sub { \
use Apache2::RequestRec; \
use Apache2::Const -compile=3D>'DECLINED'; \
$_[0]->headers_in->{Message}=3D'Hi, Mom'; \
return Apache2::Const::DECLINED; \
}"

Another word to your filter, did you know you can remove a filter on
first invocation? This way you can avoid the useless

return Apache2::Const::DECLINED if $f->ctx;

sub filter {
my ($f)=3D [at] _;
# do something
$f->remove;
return Apache2::Const::DECLINED;
}

I haven't benchmarked it but I believe this is faster than return if
$f->ctx. But it only makes a difference of course if the filter is
called more than once.

Torsten

=2D-
Need professional mod_perl support?
Just hire me: torsten.foertsch [at] gmx.net
torsten.foertsch [ Di, 30 Juni 2009 09:59 ] [ ID #2006904 ]

Re: trying to add header field using PerlInputFilterHandler to proxy

On Mon, Jun 29, 2009 at 8:07 PM, Brandon Allgood<allgood [at] numerate.com> wrote:
> I am running an apache server 2.2.3 on CentOS 5.2. I have turned on the
> proxy with the following lines from my apache.conf:
>
> <IfModule mod_proxy.c>
> ProxyRequests On
> <Proxy *>
> Order deny,allow
> Deny from all
> Allow from all
> </Proxy>
> </IfModule>
>
> I would like to add a header field to all requests going through the proxy.

If your adding a static header you can just use the Apache directive
'Header'. Using mod_perl to add a static header is somewhat overkil.

-wjt
William T [ Di, 30 Juni 2009 18:09 ] [ ID #2006909 ]

RE: trying to add header field using PerlInputFilterHandler to proxy packets

FYI, this answered my question and everything is working.

thanks,
Brandon

-----Original Message-----
From: Torsten Foertsch [mailto:torsten.foertsch [at] gmx.net]
Sent: Tuesday, June 30, 2009 1:00 AM
To: modperl [at] perl.apache.org
Cc: Brandon Allgood
Subject: Re: trying to add header field using PerlInputFilterHandler to =
proxy packets

On Tue 30 Jun 2009, Brandon Allgood wrote:
> PerlInputFilterHandler company::AddHeader
> =A0
> and I wrote the following example handler
> =A0
> package company::AddHeader;
> =A0
> use strict;
> use warnings;
> =A0
> use Apache2::Filter ();
> use Apache2::RequestRec ();
> use APR::Table ();
> =A0
> use Apache2::Const -compile =3D> qw(OK DECLINED);
> =A0
> my $debug =3D 1;
> =A0
> sub handler {
> =A0 my $f =3D shift;
> =A0
> =A0 # if we have already seen this do nothing
> =A0 return Apache2::Const::DECLINED if $f->ctx;
> =A0
> =A0 # get headers
> =A0 my $headers_in =3D $f->r->headers_in();
> =A0
> =A0 # add header field
> =A0 $headers_in->set("Message","Hi Mom");
> =A0 $f->r->headers_in($headers_in);
> =A0
> =A0 if($debug)
> =A0 {
> =A0 =A0 open FILE, ">>/tmp/out.log" or die $!;
> =A0 =A0 foreach my $key (keys %{$headers_in})
> =A0 =A0 {
> =A0 =A0 =A0 print FILE "$key =3D $headers_in->{$key}\n";
> =A0 =A0 }
> =A0 =A0 close FILE;
> =A0 }
> =A0
> =A0 $f->ctx(1);
> =A0
> =A0 return Apache2::Const::OK;
> }
> 1;
>
> As you can see, if debugging is turned on the headers are written to
> the file /tmp/out.log. =A0The contents of out.log contains the new
> header, but the requests being forwarded by the proxy don't seem to be =

> altered. =A0Why is the new header not being sent?

A request level input filter is called when the request body is read.
mod_proxy does this obviously *after* sending the request header to the =
backend server. Hence, adding an input header at this time is too late.

Why do you want to do that in a filter? Why don't you add it in a =
request phase prior to response. Fixup would be a good place for =
example.

PerlFixupHandler "sub { \
use Apache2::RequestRec; \
use Apache2::Const -compile=3D>'DECLINED'; \
$_[0]->headers_in->{Message}=3D'Hi, Mom'; \
return Apache2::Const::DECLINED; \
}"

Another word to your filter, did you know you can remove a filter on =
first invocation? This way you can avoid the useless

return Apache2::Const::DECLINED if $f->ctx;

sub filter {
my ($f)=3D [at] _;
# do something
$f->remove;
return Apache2::Const::DECLINED;
}

I haven't benchmarked it but I believe this is faster than return if =
$f->ctx. But it only makes a difference of course if the filter is =
called more than once.

Torsten

--
Need professional mod_perl support?
Just hire me: torsten.foertsch [at] gmx.net
Brandon Allgood [ Di, 14 Juli 2009 23:35 ] [ ID #2008496 ]
Webserver » gmane.comp.apache.mod-perl » trying to add header field using PerlInputFilterHandler to proxy packets

Vorheriges Thema: graceful restarts, modperl and pre-loaded modules
Nächstes Thema: [ANNOUNCE] Apache-Bootstrap 0.07