[mp2 ] Request output filters and directories

[mp2 ] Request output filters and directories

am 22.03.2011 15:43:07 von clem.oudot

Hi all,

I am one of the developer of LemonLDAP::NG (http://lemonldap-ng.org),
a free WebSSO using mod_perl. So to begin, thanks to the mod_perl team
for this great product!

In our code, we are injecting request output filters with the
add_output_filter method. This works well, but we noticed that the
filter is never called on directories, only on files:
* http://test1.example.com/ -> filter not called
* http://test1.example.com/index.pl -> filter called

I use ModPerl 2.0.4 for my tests. My Apache configuration is the following:

---------------


ServerName test1.example.com
ServerAlias test2.example.com

# SSO protection
PerlHeaderParserHandler My::Package


# DocumentRoot
DocumentRoot /usr/local/lemonldap-ng/htdocs/test/

Order deny,allow
Allow from all
Options +ExecCGI


# Perl script (application test is written in Perl)

SetHandler perl-script
PerlResponseHandler ModPerl::Registry


# Directory index

DirectoryIndex index.pl index.html




---------------


Can this behaviour comes from the DirectoryIndex and mod_dir?


Thanks for your help,

Cl=E9ment OUDOT.

Re: [mp2 ] Request output filters and directories

am 22.03.2011 19:12:01 von torsten.foertsch

On Tuesday, March 22, 2011 15:43:07 Cl=E9ment OUDOT wrote:
> Can this behaviour comes from the DirectoryIndex and mod_dir?

I assume you call add_output_filter in My::Package?

Now, mod_dir uses subrequests for all of your DirectoryIndex documents. The=
=20
first it finds, it redirects to using ap_internal_fast_redirect(). This is =
a=20
very hackish function that tries to magically turn the subreq into the main=
=20
request. It copies a bunch of values from the subreq into the main req. One=
of=20
these values is the output filter list. So, after the operation your main r=
eq=20
looks mostly like the subreq.

Another detail that hits you here is that the HeaderParser phase is called=
=20
only for the main request.

Now put these two together, you start a request for dir/. My::Package insta=
lls=20
the output filter in its header parser phase. mod_dir jumps in and issues a=
=20
subreq for dir/index.pl. The subreq skips the header parser phase.=20
ap_internal_fast_redirect copies the output filter chain (without your filt=
er)=20
from the subreq to the main one. Your registry script index.pl is evaluated=
=20
but the output filter is gone.

What could be done? I think the cleanest way would be to either move=20
My::Package to another phase, fixup for example. If that's not possible you=
=20
can set a flag in $r->pnotes when the filter in installed. Then you need a=
=20
fixup handler that looks if the flag is set in $r->main->pnotes and reinsta=
lls=20
the filter if so.

Torsten Förtsch

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

Like fantasy? http://kabatinte.net

Re: [mp2 ] Request output filters and directories

am 22.03.2011 22:14:29 von clem.oudot

2011/3/22 Torsten Förtsch :
> On Tuesday, March 22, 2011 15:43:07 Cl=E9ment OUDOT wrote:
>> Can this behaviour comes from the DirectoryIndex and mod_dir?
>
> I assume you call add_output_filter in My::Package?

Hi,

thanks for the answer. Indeed, My::Package call a module like the
following, and the add_output_filter method is called in the run()
subroutine :
http://websvn.ow2.org/filedetails.php?repname=3Dlemonldap&pa th=3D%2Ftrunk%2=
Fmodules%2Flemonldap-ng-handler%2Flib%2FLemonldap%2FNG%2FHan dler%2FSecureTo=
ken.pm


>
> Now, mod_dir uses subrequests for all of your DirectoryIndex documents. T=
he
> first it finds, it redirects to using ap_internal_fast_redirect(). This i=
s a
> very hackish function that tries to magically turn the subreq into the ma=
in
> request. It copies a bunch of values from the subreq into the main req. O=
ne of
> these values is the output filter list. So, after the operation your main=
req
> looks mostly like the subreq.
>
> Another detail that hits you here is that the HeaderParser phase is calle=
d
> only for the main request.
>
> Now put these two together, you start a request for dir/. My::Package ins=
talls
> the output filter in its header parser phase. mod_dir jumps in and issues=
a
> subreq for dir/index.pl. The subreq skips the header parser phase.
> ap_internal_fast_redirect copies the output filter chain (without your fi=
lter)
> from the subreq to the main one. Your registry script index.pl is evaluat=
ed
> but the output filter is gone.
>
> What could be done? I think the cleanest way would be to either move
> My::Package to another phase, fixup for example. If that's not possible y=
ou
> can set a flag in $r->pnotes when the filter in installed. Then you need =
a
> fixup handler that looks if the flag is set in $r->main->pnotes and reins=
talls
> the filter if so.


I tried to use PerlFixupHandler instead of PerlHeaderParserHandler,
but this changes nothing. I will try to create a specific FixupHandler
like you suggested.

Cl=E9ment.