You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Matthew Westcott <ma...@torchbox.com> on 2003/10/02 14:47:03 UTC

[mp2] Declining from response handler bypasses other handlers

I'm using a PerlResponseHandler to control access to selected 
directories of a site, and I've encountered a similar problem to that 
described in
http://marc.theaimsgroup.com/?l=apache-modperl&m=106141216914801&w=2
where returning a 'declined' status is skipping other handlers and 
going straight to Apache's default handler.

My code is:

package MyApache::Permissions;

use strict;
use warnings;
use Apache::RequestRec ();
use Apache::Const -compile => qw(OK DECLINED);

my %protected_dirs = (
	'foo' => 1,
	'bar/baz' => 1,
);

sub handler {
        my $r = shift;

        my $requested_dir = $r->filename;
        $requested_dir =~ s|^/home/www/html/my_site/(.*)/[^\/]*$|$1|;

        return Apache::DECLINED unless exists $protected_dirs{$requested_dir};

        $r->content_type('text/plain');
        print "mod_perl has taken over the $requested_dir directory...\n";

        return Apache::OK;
}
1;

and this is active over the whole site, using these directives in 
httpd.conf:
<Location />
        SetHandler perl-script
        PerlResponseHandler MyApache::Permissions
</Location>

Blocking the named directories works fine, but for the unblocked 
directories (the ones for which I return Apache::DECLINED) the 
existing (non-Perl) response handlers aren't taking effect, so my 
ColdFusion scripts are being sent through unparsed, and directory 
indexes no longer work (/something/index.html works, /something/ 
returns a 404).

I suspect the problem is on the Apache side; the SetHandler is 
overriding all other handlers. Is there any way around this?

I'm using Apache/2.0.47 and mod_perl/1.99_10, on Linux.

- Matthew


Re: [mp2] Declining from response handler bypasses other handlers

Posted by Matthew Westcott <ma...@torchbox.com>.
On 2 Oct 2003 at 9:15, Geoffrey Young wrote:

> if you want to dynamically decide who should serve the page - mod_perl if 
> some directory is found, mod_php otherwise, then you can use your own 
> PerlTypeHandler or PerlFixupHandler to set $r->handler for the request based 
> on your own criteria.

Many thanks - a PerlFixupHandler has done the job nicely. The fixup 
handler makes the decision, turning on a custom PerlResponseHandler 
if so. For the record, here's the code I arrived at:

sub handler {
        my $r = shift;

        my $requested_dir = $r->filename;
        $requested_dir =~ s|^/home/www/html/my_site/(.*)/[^\/]*$|$1|;

        return Apache::OK unless exists $permission{$requested_dir};

        $r->handler('perl-script');
        $r->set_handlers(PerlResponseHandler => \&restricted_response);
        return Apache::OK;
}

sub restricted_response {
        my $r = shift;

        my $requested_dir = $r->filename;
        $requested_dir =~ s|^/home/www/html/my_site/(.*)/[^\/]*$|$1|;

        $r->content_type('text/plain');
        print "mod_perl has taken over the $requested_dir directory...\n";

        return Apache::OK;
}
1;

invoked with

<Location />
        PerlFixupHandler MyApache::Permissions
</Location>



- Matthew


Re: [mp2] Declining from response handler bypasses other handlers

Posted by Geoffrey Young <ge...@modperlcookbook.org>.

Matthew Westcott wrote:
> I'm using a PerlResponseHandler to control access to selected 
> directories of a site, and I've encountered a similar problem to that 
> described in
> http://marc.theaimsgroup.com/?l=apache-modperl&m=106141216914801&w=2
> where returning a 'declined' status is skipping other handlers and 
> going straight to Apache's default handler.

with SetHandler there are no other handlers to call - it's the one you 
choose (perl-script in the below case) or default-handler, that's it.

> 
> and this is active over the whole site, using these directives in 
> httpd.conf:
> <Location />
>         SetHandler perl-script
>         PerlResponseHandler MyApache::Permissions
> </Location>
> 

> I suspect the problem is on the Apache side; the SetHandler is 
> overriding all other handlers. 

yup.  both your issue and the one in the link provided are expected behaviors.

> Is there any way around this?

it really depends on what you want to do.  if you are requesting 
/foo/bar.php and want php to process the page, just alter your <Location> 
settings as appropriate.

if you want to post-process that output with mod_perl, then you need to look 
into output filters.

if you want to dynamically decide who should serve the page - mod_perl if 
some directory is found, mod_php otherwise, then you can use your own 
PerlTypeHandler or PerlFixupHandler to set $r->handler for the request based 
on your own criteria.

HTH

--Geoff