On Tue 14 Oct 2008, André Warnier wrote:
> At this moment, I cannot see clearly how the ErrorDocument solution
> would allow me to send back a login page created dynamically, as I
> need to do. I will look it up, but as a definitive solution for the
> time being I would prefer the $r->internal_redirect method, where I
> can see more clearly how to do this.
<Location /secured>
PerlAuthenHandler "sub { \
return Apache2::Const::FORBIDDEN unless ...;
}"
ErrorDocument 403 /login
</Location>
<Location /login>
SetHandler modperl
# you still have to supply a login_form function that expects a
# $r object.
PerlResponseHandler "sub { \
my $r=shift; \
$r->content_type('text/html'); \
$r->print(login_form($r->prev));
return Apache2::Const::OK;
}"
</Location>
Your A-handler returns 403. Instead of sending the standard FORBIDDEN
page to the browser apache catches the error because of the
ErrorDocument directive. "/login" looks like an URI. Hence apache will
perform an internal redirect to it. "/login" is configured in the
normal modperl-way.
The browser will see an HTTP status of 403 (it will also be logged as
403). But the message sent along will be the output of &login_form. And
that is what the user will see. &login_form has access to the original
request. So, it can pass the original URI in a hidden field.
See also http://httpd.apache.org/docs/2.2/mod/core.html#errordocument
Instead of 403 you can also use 401 if you want to use
http-authentication. That is the user will see a browser generated
password box. But I doubt that is what you want.
> But I still have some (hopefully) last questions, if you would be so
> kind :
>
> As I understand this, the internal_redirect() basically stops the
> current request, and replaces it in-place by a totally new request,
> except that in that new request, $r->prev will be set to the
> (original) request that did the redirect, right ?
Yes. Best if you return OK from the current handler right after the
$r->internal_redirect line.
> (So in the new request, I can still access the pnotes set by the
> original request, via $r->prev->pnotes()).
Yes.
> For this new request, the cycle restarts right at the beginning, and
> runs through all the steps just as if this was a main request. Right
> ?
AAA are possibly skipped as I mentioned before.
> Are there any other significant differences between this new request
> and the previous one that I should be very aware of (in a
> mod_perl/AAA context) ?
You'll find some, ;-)
> One thing I do not really understand, is what happens to the original
> request, when it issues a call to $r->internal_redirect().
> Does the original request still run to completion, or does it "abort"
> right there ?
I think you'll see the original request again in the logging phase.
> Does Apache still return something to the browser for the original
> request, or is that completely replaced by whatever the new
> (redirected) request produces ?
No, not unless you have sent something prior to the internal_redirect.
> After the call to $r->internal_redirect(), should the original
> request still do something ? (like return Apache2::Const::?????) ?
OK, see
http://perl.apache.org/docs/2.0/api/Apache2/SubRequest.html#C_internal_redirect_
> P.S.
> I have downloaded the Apache source, and looked at the code within
> httpd-2.x.y/server/request.c, but it is still a bit obscure to me,
> except in a very general sense. I kind of approximately follow the
> steps, but do not always understand aspects like why it re-does
> directory walks at several stages, nor can I see at all where
> mod_perl plugs in to that code.
great! Many treasures are hidden there.
Torsten
--
Need professional mod_perl support?
Just hire me: [EMAIL PROTECTED]