perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ryan Gies <r...@livesite.net>
Subject Re: setHandler question
Date Sat, 15 Dec 2012 02:16:13 GMT
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 :
>
> <LocationMatch "/IIS_app/(.*)$">
>   PerlAuthenHandler SLC->authenticate
>   PerlAuthzHandler SLC->authorize
>   PerlSetVar SLC_login_page "/public/login.html"
>   ...
>   ProxyPassMatch http://localhost:8800/$1
> </LocationMatch>
>
> 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.

Mime
View raw message