home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Writing Apache Modules with Perl and C
By:   Lincoln Stein and Doug MacEachern
Published:   O'Reilly & Associates, Inc.  - March 1999

Copyright © 1999 by O'Reilly & Associates, Inc.


 


   Show Contents   Previous Page   Next Page

Chapter 3 - The Apache Module Architecture and API / The Handler API
Installing Handlers

The Perl and C APIs use different techniques for installing handlers. In the C API, handlers are specified by placing pointers to the handler subroutines within a static table that is compiled directly into the module code. We discuss this in more detail in Chapter 10. In contrast, Perl API handlers are installed using a series of configuration directives that can be placed in the server's configuration files or even in per-directory .htaccess files.

Installing a Perl subroutine as a handler for one of the phases in the Apache life cycle is a matter of writing a .pm (Perl module) file to implement the handler, installing it somewhere in the Perl include path, and adding the appropriate Perl*Handler directive to one of Apache's configuration files. The term "Perl*Handler," as we use it throughout this book, corresponds to any one of the 15 or so Perl API directives named PerlTransHandler, PerlAccessHandler, PerlLogHandler, and so forth.

If there is only one handler subroutine defined in the .pm file, it is convenient to name it handler() because the Perl API looks for subroutines with this name by default. Otherwise the subroutine can be named anything you like if you refer to it explicitly in the Perl*Handler directive.

Apache Perl modules usually live in the Apache:: package namespace. This is just a convention, but a good one. It generally indicates that the module is useless outside of the Apache server. That said, the other convention to follow is keeping Apache:: modules very small, by making good use of the building blocks found on CPAN, putting together new building blocks where appropriate, and simply gluing them together with the Apache API. A typical Apache Perl module file will look like this:

package Apache::Foo;
use strict;
use Apache::constants qw(:common);
sub handler {
  my $r = shift;
  # do something
  return ;
}
1;

Its declaration in the Apache configuration file will look like this:

 Apache::Foo

Replace Perl*Handler with a legitimate handler directive listed in the next section. When Apache goes to process this directive, it automatically loads and compiles the Apache::Foo module if it is not already in memory. It then calls the module's handler() subroutine during the appropriate phase of the transaction.

If you want to register several handlers for a particular phase, you can either provide a space-separated list of handlers to install, or repeat the Perl*Handler directive on multiple lines. These two techniques can be mixed.

 Apache::Foo Apache::Bar Apache::Baz
 Apache::Wiz Apache::Waz

If the handler subroutine is not named handler(), then you must refer to it explicitly by name. For example, if the handler is named do_something(), then the directive should be changed to:

 Apache::Foo::do_something

Perl*Handler directives that explicitly name the handler subroutines do not cause the module to be automatically loaded. You must do this manually beforehand, either by placing a PerlModule directive in the configuration file or indirectly by loading the module in the Perl startup file, if you have one. Here's an example of the first method:

PerlModule Apache::Foo
 Apache::Foo::do_something

If the module is not already loaded when Apache processes the Perl*Handler directive, you will see this confusing message in your server's error log:

Undefined subroutine &Apache::Foo::do_something::handler called.

It is always a good idea to preload handler modules for better performance either by using the PerlModule directive or by pulling in modules with a PerlRequire script. The Perl*Handler directives offer a shortcut, where a leading + character will tell mod_perl to load the handler module at the same time. For example, the following configuraton:

 +Apache::Foo

is equivalent to this configuration:

PerlModule   Apache::Foo
 Apache::Foo

Anonymous subroutines can also be used as Perl*Handlers, for example:

PerlChildInitHandler "sub { warn qq(child $$ starting\n) }"

Somewhat surprisingly, although there are 11 phases in the Apache life cycle that affect modules (server initialization, child initialization, child shutdown, and the eight phases of the request loop), there are a few more Perl*Handler directives, including ones that don't correspond directly to transaction processing phases, such as PerlInitHandler, PerlDispatchHandler, and PerlRestartHandler. These phases are implemented within the "standard" phases but are given some special treatment by mod_perl.

   Show Contents   Previous Page   Next Page
Copyright © 1999 by O'Reilly & Associates, Inc.