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. |