mod_perl Tricks
mod_perl Tricks
If you are creating a document from a Registry script and find that certain browsers are ignoring the Content-Type header and inferring the MIME type from the script extension in the URI, you can trick the browser into submission by attaching the "correct" file extension to the end of the URI in your links.
http://www.example.com/perl-bin/rules.pl?.pdf
Use the following subroutine to check from broken client connections:
sub client_connected { my $c = Apache->request->connection; return if $c->aborted; my $s = IO::Select->new($c->fileno); return if $s->can_read(0); return 1; }
For stat() based operations, use $r->finfo and the special Perl filehandle_ instead of stat()ing $r->filename directly.
if (-f $r->finfo && -M _ < $timeout) { ... }
You can examine, set, and reset any configured ErrorDocuments using the custom_response() method.
# examine the current ErrorDocument setting my $current = $r->custom_response(NOT_FOUND); # set the ErrorDocument for 404 $r->custom_response(NOT_FOUND, \¬_found); # reset 404s to the Apache default $r->custom_response(NOT_FOUND, undef);
To subclass the Apache class, use the following basic format for your constructor.
use Apache; our @My::Apache::ISA = qw(Apache); sub new { my ($class, $r) = @_; $r ||= Apache->request; return bless { r => $r }, $class; }
Unfortunately, you cannot configure authentication in Apache completely on-the-fly. If you need to enable authentication only under specific circumstances, the proper approach is somewhat counterintuitive: you need to enable authentication everywhere, then determine where you don't need it. In places where you do not need authentication, you can turn it off by setting the authentication handler stack to OK:
$r->set_handlers(PerlAuthenHandler => [\&OK]);
To toggle Apache's default logging on and off dynamically, use this configuration combination. First, in your httpd.conf, enable conditional logging via CustomLog /usr/local/apache/logs/access_log common env=!SKIP
Then, in your mod_perl handler, turn off logging based on some condition
$r->subprocess_env->set(SKIP => 1) if $skip_me;
and watch how mod_log_config skips logging the request.
To gather the output from a subrequest, use a combination of the Apache::URI and LWP classes.
use Apache::URI; use HTTP::Request; use LWP::UserAgent; use strict; sub handler { my $r = shift; my $uri = Apache::URI->parse($r); $uri->path(´/foo.html'); my $request = HTTP::Request->new(GET => $uri->unparse); my $response = LWP::UserAgent->new->request($request); # Continue along... }
To pass data from one mod_perl handler to another, use either the notes() method (for simple string data) or the pnotes() method (for Perl scalars).
# set a note $r->notes(MyNote => "some note"); # pass around an array as a reference $r->pnotes(MyArray => \@array); # retrieve the array my $array_ref = $r->pnotes('MyArray');
If you need to add handlers to the end of a handler stack, use $r->push_handlers.
# add a PerlFixupHandler after the currently configured ones $r->push_handlers(PerlFixupHandler => 'My::FixupHandler');
However, if you need to add to the front of a stack, use a combination of get_handlers() and set_handlers().
# add a PerlFixupHandler before the currently configured ones my $handlers = $r->get_handlers('PerlFixupHandler'); $r->set_handlers(PerlFixupHandler => ['My::FixupHandler', @$handlers]);