Show Contents Previous Page Next Page
Chapter 9 - Perl API Reference Guide / The Apache Request Object mod_perl-Specific Methods There are a handful of Perl API methods for which there is no C-language
counterpart. Those who are only interested in learning the C API can skip
this section.
exit()
It is common to come across Perl CGI scripts that use the Perl built-in
exit() function to leave the script prematurely. Calling exit()
from within a CGI script, which owns its process, is harmless, but calling
exit() from within mod_perl would have the unfortunate
effect of making the entire child process exit unceremoniously, in most
cases before completing the request or logging the transaction. On Win32
systems, calling exit() will make the whole server quit. Oops!
For this reason mod_perl's version of this function call, Apache::exit(),
does not cause the process to exit. Instead, it calls Perl's croak()
function to halt script execution but does not log a message to the ErrorLog.
If you really want the child server process to exit, call Apache::exit()
with an optional status argument of DONE (available in Apache::Constants).
The child process will be shut down but only after it has had a chance to
properly finish handling the current requests. In scripts running under Apache::Registry, Perl's built-in exit()
is overridden by Apache::exit() so that legacy CGI scripts
don't inadvertently shoot themselves in the foot. In Perl Versions 5.005 and
higher, exit() is overridden everywhere, including within handlers.
In versions of mod_perl built with Perl 5.004, however, handlers
can still inadvertently invoke the built-in exit(), so you should
be on the watch for this mistake. One way to avoid it is to explicitly import
the exit symbol when you load the Apache module. Here are various examples of exit():
$r->exit;
Apache->exit;
$r->exit(0);
$r->exit(DONE);
use Apache 'exit'; #this override's Perl's builtin
exit;
If a handler needs direct access to the Perl built-in version of exit()
after it has imported Apache's version, it should call CORE::exit().
gensym()
This function creates an anonymous glob and returns a reference to it
for use as a safe file or directory handle. Ordinary bareword filehandles
are prone to namespace clashes. The IO::File class avoids this,
but some users have found that the IO::File carries too much overhead.
Apache::gensym avoids this overhead and still avoids namespace
clashes.
my $fh = Apache->gensym;
open $fh, $r->filename or die $!;
$r->send_fd($fh);
close $fh;
Because of its cleanliness, most of the examples in this book use the Apache::File
interface for reading and writing files (see "The Apache::File
Class"). If you wish to squeeze out a bit of overhead, you may wish to
use Apache::gensym() with Perl's built-in open()
function instead.
current_callback()
If a module wishes to know what handler is currently being run, it can
find out with the current_callback() method. This method is most
useful to Perl-DispatchHandlers who wish to only take action for
certain phases.
if($r->current_callback eq "PerlLogHandler") {
$r->warn("Logging request");
}
get_handlers()
The get_handlers() method will return an array reference containing
the list of all handlers that are configured to handle the current request.
This method takes a single argument specifying which handlers to return.
my $handlers = $r->get_handlers('PerlAuthenHandler');
set_handlers()
If you would like to change the list of Perl handlers configured for the
current request, you can change it with set_handlers(). This method
takes two arguments; the name of the handler you wish to change and an array
reference pointing to one or more references to the handler subroutines
you want to run for that phase. If any handlers were previously defined,
such as with a Perl*Handler directive, they are replaced by this
call. Provide a second argument of undef to remove all handlers
for that phase.
$r->set_handlers(PerlAuthenHandler => [\&auth_one, \&auth_two]);
$r->set_handlers(PerlAuthenHandler => undef);
push_handlers()
The push_handlers() method is used to add a new Perl handler
routine to the current request's handler "stack". Instead of replacing the
list of handlers, it just appends a new handler to the list. Each handler
is run in turn until one returns an error code. You'll find more information
about using stacked handlers and examples in Chapters 4,
6, and 7. This method takes two arguments: the name of the phase you want to manipulate
and a reference to the subroutine you want to handle that phase. Example:
$r->push_handlers(PerlLogHandler => \&my_logger);
module()
If you need to find out if a Perl module has already been loaded, the
module() method will tell you. Pass it the package name of the
module you're interested in. It will return a true value if the module is
loaded.
do { #something } if Apache->module('My::Module');
This method can also be used to test if a C module is loaded. In this case,
pass it the filename of the module, just as you would use with the IfModule
directive. It will return a true value if the module is loaded.
do { #something } if Apache->module('mod_proxy.c');
define()
Apache Version 1.3.1 added a -D command-line switch that can
be used to pass the server parameter names for conditional configuration
with the IfDefine directive. These names exist for the lifetime
of the server and can be accessed at any time by Perl modules using the
define() method.
if(Apache->define("SSL")) {
#the server was started with -DSSL
}
post_connection()
This method is simply an alias for the register_cleanup() method
described in the "Server Core Functions" section.
request()
The Apache->request() class method returns a reference to
the current request object, if any. Handlers that use the vanilla Perl API
will not need to call this method because the request object is passed to
them in their argument list. However, Apache::Registry scripts
and plain Perl modules do not have a subroutine entry point and therefore
need a way to gain access to the request object. For example, CGI.pm uses
this method to provide proper mod_perl support. Called with no arguments, request() returns the stored Apache
request object. It may also be called with a single argument to set the stored
request object. This is what Apache::Registry does before invoking
a script.
my $r = Apache->request; # get the request
Apache->request($r); # set the request
Actually, it's a little known fact that Apache::Registry scripts
can access the request object directly via @_ . This is slightly
faster than using Apache->request() but has the disadvantage of
being obscure. This technique is demonstrated in "Subclassing the Apache Class"
in Chapter 7.
httpd_conf()
The httpd_conf() method allows you to pass new directives to
Apache at start-up time. Pass it a multiline string containing the configuration
directives that you wish Apache to process. Using string interpolation,
you can use this method to dynamically configure Apache according to arbitrarily
complex rules.
httpd_conf() can only be called during server startup, usually
from within a Perl startup file. Because there is no request method at this
time, you must invoke httpd_conf() directly through the Apache
class.
my $ServerRoot = '/local/web';
Apache->httpd_conf(<<EOF);
Alias /perl $ServerRoot/perl
Alias /cgi-bin $ServerRoot/cgi-bin
EOF
Should a syntax error occur, Apache will log an error and the server will
exit, just as it would if the error was present in the httpd.conf
configuration file. A more sophisticated way of configuring Apache at startup
time via <Perl> sections is discussed in Chapter 8,
Customizing the Apache Configuration Process.
Footnotes 1 As of this writing, HTTP/1.1 requests that do not have
a Content-length header, such as those that use chunked encoding,
are not properly handled by this API. 2 In case you were wondering, the epoch began at 00:00:00
GMT on January 1, 1970, and is due to end in 2038. There's probably a good
explanation for this choice. 3 If you are wondering why this method has an r
prefix, it is carried over from the C API I/O methods (described in Chapter 10),
all of which have an ap_r prefix. This is the only I/O method from
the group for which there is a direct Perl interface. If you find that the
r prefix is not pleasing to the eye, this is no accident. It is intended
to discourage the use of rflush() due to the performance implications.
4 In fact, the log-level API now provides direct syslog
support. See the Apache documentation for the ErrorLog directive,
which explains how to enable logging via syslog. Show Contents Previous Page Next Page Copyright © 1999 by O'Reilly & Associates, Inc. |