Imagine a complex server setup in which many different Perl and non-Perl handlers participate in the request processing, and one or more of these handlers misbehaves. A simple example is one where one of the handlers alters the request record, which breaks the functionality of other handlers. Or maybe a handler invoked first for any given phase of the process returns an unexpected OKstatus, thus preventing other handlers from doing their job. You can't just add debug statements to trace the offender—there are too many handlers involved.
The simplest solution is to get a trace of all registered handlers for each phase, stating whether they were invoked and what their return statuses were. Once such a trace is available, it's much easier to look only at the players that actually participated, thus narrowing the search path down a potentially misbehaving module.
The Apache::ShowRequest module shows the phases the request goes through, displaying module participation and response codes for each phase. The content response phase is not run, but possible modules are listed as defined. To configure it, just add this snippet to httpd.conf:
<Location /showrequest> SetHandler perl-script PerlHandler +Apache::ShowRequest </Location>
To see what happens when you access some URI, add the URI to /showrequest. Apache::ShowRequest uses PATH_INFO to obtain the URI that should be executed. So, to run /index.html with Apache::ShowRequest, issue a request for /showrequest/index.html. For /perl/test.pl, issue a request for /showrequest/perl/test.pl.
This module produces rather lengthy output, so we will show only one section from the report generated while requesting /showrequest/index.html:
Running request for /index.html Request phase: post_read_request [snip] Request phase: translate_handler mod_perl ....................DECLINED mod_setenvif ................undef mod_auth ....................undef mod_access ..................undef mod_alias ...................DECLINED mod_userdir .................DECLINED mod_actions .................undef mod_imap ....................undef mod_asis ....................undef mod_cgi .....................undef mod_dir .....................undef mod_autoindex ...............undef mod_include .................undef mod_info ....................undef mod_status ..................undef mod_negotiation .............undef mod_mime ....................undef mod_log_config ..............undef mod_env .....................undef http_core ...................OK Request phase: header_parser [snip] Request phase: access_checker [snip] Request phase: check_user_id [snip] Request phase: auth_checker [snip] Request phase: type_checker [snip] Request phase: fixer_upper [snip] Request phase: response handler (type: text/html) mod_actions .................defined mod_include .................defined http_core ...................defined Request phase: logger [snip]
For each stage, we get a report of what modules could participate in the processing and whether they took any action. As you can see, the content response phase is not run, but possible modules are listed as defined. If we run a mod_perl script, the response phase looks like:
Request phase: response handler (type: perl-script) mod_perl ....................defined
 
Continue to: