On Tue 14 Oct 2008, André Warnier wrote:
> reminder of my config :
> >> <LocationMatch "/servlet.xyz$">
> >>     SetHandler jakarta-servlet
...
> >> </Location>
>
> And, in summary, what I was trying to do is :
> if the PerlAuthenHandler finds that the request is not authenticated,
> then it tries to change the response handler for this request, from
> the original "jakarta-servlet" handler, to my own response handler,
> which in fact returns a login page.
> (I need something "active" to return the login page, because I need
> to insert some data into the login page prior to returning it).
>
> And for that I used this code in the PerlAuthenHandler :
>
> # set our own response handler
> $r->handler('modperl');
> $r->set_handlers(PerlResponseHandler => \&_send_login_form);
> return OK;

The problem is the $r->handler statement. The program flow is this:

- ...
- uri translation
- map to storage
- Location container is applied
  the SetHandler directive is applied to the requests configuration
  structure. That does not mean $r->handler is set. It is simply noted
  there is a SetHandler directive active for the request.
- aaa
- ...
- fixup
  the SetHandler value is copied to $r->handler. See
  httpd-2.x.y/server/core.c:core_override_type()

    if (conf->handler && strcmp(conf->handler, "none"))
        r->handler = conf->handler;

  That means $r->handler is set only if there was a SetHandler directive
  and if it was not "SetHandler none".

So, that leads us to 4 possible solutions:

1) remove the SetHandler directive from the Location container and set 
$r->handler either to jakarta-servelet or to modperl in your aaa 
handler. It won't be touched if other modules don't kick in. mod_dir 
comes to mind but it reads (fixup handler):

    /* In case mod_mime wasn't present, and no handler was assigned. */
    if (!r->handler) {
        r->handler = DIR_MAGIC_TYPE;
    }

So, that's not a problem. But there may be other modules that don't 
check that.

2) replace $r->handler('modperl') in the aaa phase by 
$r->add_config(['SetHandler modperl']). This way you override the 
handler set in the configuration structure. In the fixup phase it is 
then automagically copied to $r->handler.

3) leave the $r->handler('modperl') and add a 
$r->add_config(['SetHandler none']);

4) set $r->handler in a fixup handler.

$r->add_config works very similar to

<Location />
your directives
</Location>

The only difference is the time when it is applied to the config struct. 
That config is reset after the translation phase. So it is useless to 
try $r->add_config before. Location containers from the httpd.conf are 
applied after MapToStorage. So anything you do in your own MapToStorage 
handler can be overridden in Location containers even if your handler 
returns OK to skip the core MapToStorage handler.

But anything applied after that, that means from the header-parser phase 
onward overrides the httpd.conf settings.

> One of the possibilities envisioned previously was :
> >> Or, a thought that just occurred to me, is the solution for me
> >> (stopping jakarta-servlet from running and running my
> >> PerlresponseHandler instead), as easy as setting the "no-jk"
> >> variable (if I can do that within my PerlAuthenHandler, and how) ?
> >
> > I was tempted to suggest that. But I don't know nothing about
> > jakarta. If you want to try use $r->subprocess_env->{'no-jk'}=1;
>
> I tried this, because it was the smallest possible change to my
> module. It works, in the sense that it sets the "no-jk" variable,
> which consequently has the effect of making the "jakarta-servlet"
> handler above not process this link.
> But it is not a solution for me, since what happens is that the
> jakarta-servlet handler is in fact still executed by Apache as the
> response handler, but it probably just returns DECLINED.

That's what I thought it would.

Torsten

--
Need professional mod_perl support?
Just hire me: [EMAIL PROTECTED]

Reply via email to