From modperl-return-63091-apmail-perl-modperl-archive=perl.apache.org@perl.apache.org Sat Dec 15 02:17:06 2012 Return-Path: X-Original-To: apmail-perl-modperl-archive@www.apache.org Delivered-To: apmail-perl-modperl-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 71A0ED791 for ; Sat, 15 Dec 2012 02:17:06 +0000 (UTC) Received: (qmail 25585 invoked by uid 500); 15 Dec 2012 02:17:05 -0000 Delivered-To: apmail-perl-modperl-archive@perl.apache.org Received: (qmail 25555 invoked by uid 500); 15 Dec 2012 02:17:05 -0000 Mailing-List: contact modperl-help@perl.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list modperl@perl.apache.org Received: (qmail 25547 invoked by uid 99); 15 Dec 2012 02:17:05 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 15 Dec 2012 02:17:05 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=5.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of ryan@livesite.net designates 206.63.25.114 as permitted sender) Received: from [206.63.25.114] (HELO mail.livesite.net) (206.63.25.114) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 15 Dec 2012 02:16:55 +0000 Received: from localhost (unknown [127.0.0.1]) by mail.livesite.net (Postfix) with ESMTP id ED37C748114; Sat, 15 Dec 2012 02:16:33 +0000 (UTC) X-Virus-Scanned: amavisd-new at example.com Received: from mail.livesite.net ([127.0.0.1]) by localhost (msrv.livesite.net [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gRO5vL4RGoEf; Fri, 14 Dec 2012 18:16:20 -0800 (PST) Received: from [192.168.0.7] (unknown [74.78.90.48]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.livesite.net (Postfix) with ESMTP id 82F9774810B; Sat, 15 Dec 2012 02:16:19 +0000 (UTC) Message-ID: <50CBDD6D.8070208@livesite.net> Date: Fri, 14 Dec 2012 21:16:13 -0500 From: Ryan Gies User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: mod_perl list CC: =?UTF-8?B?QW5kcsOpIFdhcm5pZXI=?= Subject: Re: setHandler question References: <50CB2F1C.8020901@ice-sa.com> <50CB65BF.8000908@livesite.net> <50CB8C11.1040809@ice-sa.com> In-Reply-To: <50CB8C11.1040809@ice-sa.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Virus-Checked: Checked by ClamAV on apache.org On 12/14/2012 3:29 PM, André Warnier wrote: > Ryan Gies wrote: >> On 12/14/2012 8:52 AM, André Warnier wrote: >>> I suppose that in the end I will want to do something like this : >>> >>> my $finfo = $r->finfo(); >>> # do something to $finfo to set the flag >>> $r->finfo($finfo); >>> $r->handler('modperl'); >>> $r->set_handlers(PerlResponseHandler => \&_my_response_handler); >>> >>> but how do I "do something to $finfo" ? >>> >>> Or am I totally off-track here ? >>> >>> TIA >> For what it's worth, I have consistent success in using $r->finfo to >> tell Apache the final destination. In the case that $you_want_to_hook >> (below) is false, Apache will also serve the intended file. The >> timing used is: >> >> PerlMapToStorageHandler >> >> $r->filename($path); # where $path is an absolute file-system path >> $r->finfo(APR::Finfo::stat($path, APR::Const::FINFO_NORM, $r->pool)); >> return Apache2::Const::OK; >> >> PerlFixupHandler >> >> if ($you_want_to_hook) { >> $r->push_handlers(PerlResponseHandler => \&_response_handler); >> $r->handler('modperl'); >> return Apache2::Const::OK; >> } >> > > Let me explain better what I am looking for : > > > PerlAuthenHandler SLC->authenticate > PerlAuthzHandler SLC->authorize > PerlSetVar SLC_login_page "/public/login.html" > ... > ProxyPassMatch http://localhost:8800/$1 > > > In other words, > - Apache+mod_perl is acting as a reverse proxy for an application > running under IIS on the same server > - but this IIS application requires a special HTTP header to > authenticate the user > - In the Location above, the PerlAuthenHandler checks if the user is > authenticated. > - If yes, it adds the required HTTP header to the request, and > then a few steps later the proxying happens to IIS, and that's fine. > - If not, it sends back a login page. > > What I want to do refers to the "sends back a login page". > In case the user is not authenticated, I do /not/ want Apache to proxy > the call to IIS. > I want to reset the response handler so that it is no longer > mod_proxy, but mod_perl, and my own PerlResponseHandler (which sends > back the login page "/public/login.html", after munching on it). > But what happens is that the proxying runs anyway, and the request > ends up in IIS, but without the authentication header. > That's what I want to avoid. > > In the PerlAuthenHandler, I already do this : > > if ($not_authenticated) > { > $r->handler('modperl'); # (1) > $r->set_handlers(PerlResponseHandler => \&_my_send_login_handler); > # (2) > $r->set_handlers(PerlFixupHandler => sub { > $_[0]->handler('modperl') } ); # (3) > return Apache2::Const::OK; > } > > But that is apparently not enough. It is still (later) proxying the > request to IIS. > So it is apparently ignoring the line > $r->handler('modperl'); # (1) > > What am I missing ? (as another way of phrasing the initial question) > > I am led to believe that it has to do with the "map-to-storage" phase, > which has already happened by the time the PerlAuthenHandler runs, and > that in order to completely override the mod_proxy response handler, I > need to set/reset some flag(s). > I'd like (if possible) to do that "dynamically" in the > PerlAuthenHandler, without having to configure an extra > PerlMapToStorageHandler in my configuration for that Location. > > (In the above, (1) and (3) are probably the same thing, with (3) > happening later and having maybe a better chance. But it's still not > working. > > Would these 2 lines : > > > $r->filename($path); # where $path is an absolute file-system path > > $r->finfo(APR::Finfo::stat($path, APR::Const::FINFO_NORM, $r->pool)); > > added to the above current code, do the trick ? I would need to duplicate your scenario, setting up a ProxyPass situation such as you've described, to help answer that. I do however suspect that if you change the approach to do something like this: my $login_page = '/public/login.html'; $r->add_config(["ErrorDocument 401 $login_page"]); $r->err_headers_out->add('WWW-Authenticate' => 'Web'); # Required header return Apache2::Const::AUTH_REQUIRED; That the ProxyPass will not happen. You would then munch on /public/login.html separately, as a sub-request.