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 9 - Perl API Reference Guide
Configuration Classes

In this section...

Introduction
The Apache::ModuleConfig Class
The Apache::CmdParms Class

Introduction

   Show Contents   Go to Top   Previous Page   Next Page

Two classes, Apache::ModuleConfig and Apache::CmdParms, provide access to the custom configuration directive API.

The Apache::ModuleConfig Class

   Show Contents   Go to Top   Previous Page   Next Page

Most Apache Perl API modules use the simple PerlSetVar directive to declare per-directory configuration variables. However, with a little more effort, you can create entirely new configuration directives. This process is discussed in detail in Chapter 8, Customizing the Apache Configuration Process.

Once the configuration directives have been created, they can be retrieved from within handlers using the Apache::ModuleConfig->get() class method. get() returns the current command configuration table as an Apache table blessed into the Apache::Table class. get() takes one or two arguments. The first argument can be the current request object to retrieve per-directory data or an Apache::Server object to retrieve per-server data. The second, optional, argument is the name of the module whose configuration table you are interested in. If not specified, this argument defaults to the current package, which is usually what you want.

Here's an example:

use Apache::ModuleConfig ();
...
sub handler {
 my $r = shift;
 my $cfg = Apache::ModuleConfig->get($r);
 my $printer = $cfg->{'printer-address'};
 ...
}

The Apache::CmdParms Class

   Show Contents   Go to Top   Previous Page   Next Page

The Apache::CmdParms class provides a Perl interface to the Apache cmd_parms data structure. When Apache encounters a directive, it invokes a command handler that is responsible for processing the directive's arguments. The Apache::CmdParms object is passed to the responsible handler and contains information that may be useful when processing these arguments.

An example of writing a directive handler is given in Chapter 8. In this section, we just summarize the methods that Apache::CmdParms makes available.

path()

If the configuration directive applies to a certain <Location>, <Directory>, or <Files> section, the path() method returns the path or filename pattern to which the section applies.

my $path = $parms->path;

server()

This method returns an object blessed into the Apache::Server class. This is the same Apache::Server object which is retrieved at request time via the Apache method named server(). See above.

my $s = $parms->server;

cmd()

This method returns an object blessed into the Apache::Command class. The Apache::Module package from CPAN must be installed to access Apache::Command methods.

use Apache::Module ();
...
my $name = $parms->cmd->name;

info()

If the directive handler has stashed any info in the cmd_data slot, this method will return that data. This is generally somewhat static information, normally used to reuse a common configuration function. For example, the fancy directory indexer, mod_autoindex and its family of AddIcon* directives, uses this technique quite effectively to manipulate the directive arguments.

my $info = $parms->info;

limited()

The methods present in the current Limit configuration are converted into a bit mask, which is returned by this method.

# httpd.conf
<Limit GET POST>
SomeDirective argument_1 argument_2
</Limit>
# Perl module
use Apache::Constants qw(:methods);
sub SomeDirective ($$$$) {
   my($parms, $cfg, @args) = @_;
   my $method_mask = $parms->limited;
   if($method_mask & (1 << M_POST)) {
      ...
   }
}

override()

This method converts the current value of the AllowOverride directive into a bit mask and returns it. You can then import the Apache::Constants:override tag to retrieve the values of individual bits in the mask. Modules don't generally need to check this value. The internal configuration functions take care of the required context checking.

use Apache::Constants qw(:override);
my $override_mask = $parms->override;
if($override_mask & OR_ALL) {
  #this directive is allowed anywhere in the configuration files
}

getline()

If the directive handler needs to read from the configuration file directly, it may do so with the getline() method. The first line returned in the following example is the line immediately following the line on which the directive appeared. It's up to your handler to decide when to stop reading lines; in the example below we use pattern matching.

Reading from the configuration file directly is normally done when a directive is declared with a prototype of RAW_ARGS. With this prototype, arguments are not parsed by Apache, that job is left up to the directive handler. Let's say you need to implement a configuration container, in the same format as the standard <Directory> and <Location> directives:

<Container argument>
 ....
</Container>

Here is a directive handler to parse it:

sub Container ($$$*) {
   my($parms, $cfg, $arg, $fh) = @_;
   $arg =~ s/>//;
   while($parms->getline($line)) {
       last if $line =~ m:</Container>:i;
       ...
   }
}

There is an alternative to using the getline() method. As described in Chapter 8, when the RAW_ARGS proto-type is used, a tied filehandle is passed to the directive handler as its last argument. Perl's built-in read() and getc() functions may be used on this filehandle, along with the <> readline operator:

sub Container ($$$*) {
   my($parms, $cfg, $arg, $fh) = @_;
   $arg =~ s/>//;
    while(defined(my $line = <$fh>)) {
       last if $line =~ m:</Container>:i;
       ...
   }
}
   Show Contents   Go to Top   Previous Page   Next Page
Copyright © 1999 by O'Reilly & Associates, Inc.