On Sun 12 Oct 2008, André Warnier wrote:
> <Location /some/url>
>
> SetHandler jakarta-servlet
> SetEnvIf REQUEST_URI "\.(htm|web|css|gif|jpg|js|html?)$" no-jk
>
> PerlXXXHandler My::Module->some_method
>
> ...
>
> </Location>
>
> ("jakarta-servlet" above means mod_jk --> Tomcat)
> (and PerlXXXHandler being any kind of Perl HTTP Handler running soon
> enough)
>
> The Question :
> Is it possible, in the PerlXXXHandler, on a request-by-request base,
> to "disable" the jakarta-servlet handler, and install the following
> instead
>
> SetHandler modperl
> PerlResponseHandler My::Module->some_other_method
>
> ?
>
> I know that I can do something like the above for regular static
> pages, and I use this already :
> $r->handler('modperl');
> $r->set_handlers(PerlAuthzHandler => []); # stop authorization
> from running
> $r->set_handlers(PerlResponseHandler => \&_send_login_form);
>
>
> However, when I try to do the same in a Location like the above, it
> seems that the jakarta-servlet handler runs anyway, and my
> PerlResponseHandler is never called.
Does that piece of code run in a /Perl(PostReadRequest|Trans|
MapToStorage)Handler/ ?
Please, have a look again at the ap_process_request_internal() function
in httpd-2.x.y/server/request.c. This function implements almost the
complete request cycle (save PostReadRequest, Response and Log).
Just after ap_run_translate_name(), that is the PerlTransHandler, you'll
see this piece:
/* Reset to the server default config prior to running
map_to_storage
*/
r->per_dir_config = r->server->lookup_defaults;
if ((access_status = ap_run_map_to_storage(r))) {
/* This request wasn't in storage (e.g. TRACE) */
return access_status;
}
/* Rerun the location walk, which overrides any map_to_storage
config.
*/
if ((access_status = ap_location_walk(r))) {
return access_status;
}
/* Only on the main request! */
if (r->main == NULL) {
if ((access_status = ap_run_header_parser(r))) {
return access_status;
}
}
...
The line "r->per_dir_config = r->server->lookup_defaults;" resets all
request specific configurations applied so far. After that line the
request is configured as if no Directory/Location or other container
were present in your httpd.conf. Next comes MapToStorage. Here
Directory, DirectoryMatch, Files and FilesMatch containers are applied
to the request. Then, and this is what I think hits you, comes an
ap_location_walk. Here Location containers are applied. So, your
SetHandler inside the Location overrides any $r->handler seen before.
After the ap_location_walk comes the PerlHeaderParserHandler. But it is
skipped for subrequests. A further examination will show you that the
next phase that is run by all requests is the PerlTypeHandler just
before Fixup. So, move your "$r->handler('modperl');" to one of those
and it will work. I prefer Fixup but that is based only on the fact
that it is documented as do-what-you-want phase. There are directives
that change the handler in the type-checker phase. In fact the
AddHandler directive works that way. Mod_mime looks at the file
extension and adjusts the handler, e.g "AddHandler cgi-script .pl". So
using Fixup your module is the last to kick in.
To carry state around use pnotes, notes or subprocess_env.
Torsten
--
Need professional mod_perl support?
Just hire me: [EMAIL PROTECTED]