As we mentioned in the beginning of this chapter, mod_perl lets you run both scripts and handlers. The previous example showed a script, which is probably the most familiar approach to web programming, but the more advanced use of mod_perl involves writing handlers. Have no fear; writing handlers is almost as easy as writing scripts and offers a level of access to Apache's internals that is simply not possible with conventional CGI scripts.

To create a mod_perl handler module, all that is necessary is to wrap the code that would have been the body of a script into a handlersubroutine, add a statement to return the status to the server when the subroutine has successfully completed, and add a package declaration at the top of the code.

Just as with scripts, the familiar CGI API may be used. Example 2-4 shows an example.

Example 2-4. ModPerl/

package ModPerl::Rules1;
use Apache::Constants qw(:common);

sub handler {
    print "Content-type: text/plain\n\n";
    print "mod_perl rules!\n";
    return OK; # We must return a status to mod_perl
1; # This is a perl module so we must return true to perl

Alternatively, the mod_perl API can be used. This API provides almost complete access to the Apache core. In the simple example used here, either approach is fine, but when lower-level access to Apache is required, the mod_perl API shown in Example 2-5 must be used.

Example 2-5. ModPerl/

package ModPerl::Rules2;
use Apache::Constants qw(:common);

sub handler {
    my $r = shift;
    $r->print("mod_perl rules!\n");
    return OK; # We must return a status to mod_perl
1; # This is a perl module so we must return true to perl

Create a directory called ModPerl under one of the directories in @INC (e.g., under /usr/lib/perl5/site_perl/5.6.1), and put and into it. (Note that you will need root access in order to do this.) The files should include the code from the above examples. To find out what the @INC directories are, execute:

panic% perl -le 'print join "\n", @INC'

On our machine it reports:


Therefore, on our machine, we might place the files in the directory /usr/lib/perl5/site_perl/5.6.1/ModPerl. By default, when you work as root, the files are created with permissions allowing everybody to read them, so here we don't have to adjust the file permissions (the server only needs to be able to read those).

Now add the following snippet to /usr/local/apache/conf/httpd.conf, to configure mod_perl to execute the ModPerl::Rules1::handler subroutine whenever a request to mod_perl_rules1 is made:

PerlModule ModPerl::Rules1
<Location /mod_perl_rules1>
   SetHandler perl-script
   PerlHandler ModPerl::Rules1
   PerlSendHeader On

Now issue a request to:


and, just as with the scripts, the following should be rendered as a response:

mod_perl rules!

Don't forget to include the port number if not using port 80 (e.g., http://localhost:8080/mod_perl_rules1); from now on, we will assume you know this.

To test the second module, ModPerl::Rules2, add a similar configuration, while replacing all 1s with 2s:

PerlModule ModPerl::Rules2
<Location /mod_perl_rules2>
   SetHandler perl-script
   PerlHandler ModPerl::Rules2

In Chapter 4 we will explain why the PerlSendHeader directive is not needed for this particular module.

To test, use the URI:


You should see the same response from the server that we saw when issuing a request for the former mod_perl handler.