The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mod_perl_api - accessing the Apache API via mod_perl ($Date: 1998/03/19 23:08:34 $)

DESCRIPTION

This part of the mod_perl FAQ deals with the Apache Application Programmer's Interface and how to access it from perl via mod_perl.

Why can't the server find the handler I wrote?

Did you enable the required hook?

As described in the mod_perl/INSTALL document, the only callback hook enabled by default is PerlHandler. If you want to intervene at a different stage of request processing you must enable the relevant hook. So to add a special authentication handler, for instance, you would start the installation process with:

  perl Makefile.PL PERL_AUTHEN=1

Is the handler correctly referenced in the configuration?

Apache must be told to load your handler, either as a module with the PerlModule directive or as a script with PerlRequire. The handler subroutine will then be available, but you must also specify which requests it should process. This is done by naming it in one of the Perl*Handler directives (PerlInitHandler, PerlTransHandler, etc.). If this directive is put in access.conf outside of any restrictive context, your handler will be called during the given phase of each request processed by the server. You can make it more selective by restricting it to a directory (-hierarchy) in a <Directory ...> section of access.conf or by putting it in a .htaccess file.

Here is an example of the directives needed to call a handler during Apache's URI to filename translation phase:

  PerlRequire         /full/path/to/script/Trans.pl
  PerlTransHandler   Trans::handler

Trans.pl would start with the statement Package Trans; and define a subroutine called handler.

Where can I find examples to get me started?

Check out the Apache-Perl-contrib tarfile at http://perl.apache.org/src/

Here is an example from Vivek Khera. It allows you to filter files through a perl script based on their location. Rather than having to invoke a CGI script, the user just references the file with a normal URL and it is automagically processed by this code...

  #! /usr/local/bin/perl
  use strict;
  
  # filter a file before returning it to the web client
  # tell Apache to use the PerlHandler FileFilter on file which need
  # filtering in the htaccess file:
  #
  # <Files *.baz>
  #  SetHandler  perl-script
  #  PerlHandler FileFilter
  # </Files>
  
  package FileFilter;
  
  use Apache::Constants ':common';
  
  # find out the file name, then write it out with our header attached
  sub handler {
    my $r = shift;
  
    my $fileName = $r->filename;
  
    open(F,$fileName) or return NOT_FOUND; # file not found
  
    $r->content_type('text/html');
    $r->no_cache(1);              # don't be caching my dynamic documents!
  
    $r->send_http_header;
  
    $r->print("<HEAD><TITLE>This is my personal header!</TITLE></HEAD><BODY>");

    # Now copy the file to the client.  If you do not need to make any
    # changes you can copy it verbatim with the single statement
    #    $r->send_fd(\*F);
    # Otherwise, loop over each line...
    while(<F>) {
      # mangle the contents here if you want
      $r->print ($_);
    }
    close(F);
  
    $r->print("<HR>Document created: ", scalar localtime time);
    $r->print("</BODY>");
  
    OK;
  }
  
  1;

How can I check if mod_perl is available during configuration?

Ralf Engelschall writes:

When you compiled one httpd with and the other without mod_perl, then you can simply use <IfModule mod_perl.c>...</IfModule> to surround the stuff for the httpd compiled with mod_perl. The other then ignores these lines. Example:

  <IfModule mod_perl.c>
  ...stuff for httpd w/ mod_perl...
  </IfModule>
  <IfModule !mod_perl.c>
  ...stuff for httpd w/o mod_perl...
  </IfModule>