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 8 - Customizing the Apache Configuration Process / Configuring Apache with Perl
Debugging <Perl> Sections

If there is a syntax error in the Perl code causing it to fail during compilation, Apache will report the problem and the server will not start.

One way to catch Perl syntax errors ahead of time is to structure your <Perl> sections like this:

<Perl>
#!perl
... code here ...
__END__
</Perl>

You can now directly syntax-check the configuration file using the Perl interpreter's -cx switches. -c makes Perl perform a syntax check, and -x tells the interpreter to ignore all junk prior to the #!perl line:

% perl -cx httpd.conf
httpd.conf syntax OK

If the Perl code is syntactically correct, but the Apache configuration generated from it contains an error, an error message will be sent to the server error log, but the server will still start. In general, it is always a good to look at the error log after starting the server to make sure startup went smoothly. If you have not picked up this good habit already, we strongly recommend you do so when working with <Perl> configuration sections.

Another helpful trick is to build mod_perl with the PERL_TRACE configuration option set to true. Then, when the environment variable MOD_PERL_TRACE is set to s, httpd will output diagnostics showing how the <Perl> section globals are converted into directive string values.

Another tool that is occasionally useful is the Apache::PerlSections module. It defines two public routines named dump() and store(). dump() dumps out the current contents of the <Perl> section as a pretty-printed string. <Perl> does the same but writes the contents to the file of your choice. Both methods are useful for making sure that the configuration you are getting is what you expect.

Apache::PerlSections requires the Perl Devel::SymDump and Data::Dumper modules, both available on CPAN. Here is a simple example of its use:

<Perl>
#!perl
use Apache::PerlSections();
$User = 'nobody';
$VirtualHost{'192.168.2.5:80'} = {
  ServerName   => 'www.fishfries.org',
  DocumentRoot => '/home/httpd/fishfries/htdocs',
  ErrorLog     => '/home/httpd/fishfries/logs/error.log',
  TransferLog  => '/home/httpd/fishfries/logs/access.log',
  ServerAdmin  => 'webmaster@fishfries.org',
};
print STDERR Apache::PerlSections->dump();
__END__
</Perl>

This will cause the following to appear on the command line at server startup time:

package Apache::ReadConfig;
#scalars:
$User = 'nobody';
#arrays:
#hashes:
%VirtualHost = (
 '192.168.2.5:80' => {
   'ServerAdmin' => 'webmaster@fishfries.org',
   'ServerName' => 'www.fishfries.org',
   'DocumentRoot' => '/home/httpd/fishfries/htdocs',
   'ErrorLog' => '/home/httpd/fishfries/logs/error.log',
   'TransferLog' => '/home/httpd/fishfries/logs/access.log'
 }
);
1;
__END__

The output from dump() and store() can be stored to a file and reloaded with a require statement. This allows you to create your configuration in a modular fashion:

<Perl>
 require "standard_configuration.pl";
 require "virtual_hosts.pl";
 require "access_control.pl";
</Perl>

More information about Apache::PerlSections can be found in Appendix A, Standard Noncore Modules.

Simple Dynamic Configuration

   Show Contents   Go to Top   Previous Page   Next Page

If the Perl configuration syntax seems a bit complex for your needs, there is a simple alternative. The special variables $PerlConfig and @PerlConfig are treated as raw Apache configuration data. Their values are fed directly to the Apache configuration engine and treated just as if they were lines of text from a conventional file:

<Perl>
$PerlConfig  = "User $ENV{USER}\n";
$PerlConfig .= "ServerAdmin $ENV{USER}\@$hostname\n";
</Perl>
<Perl>
for my $host (qw(one red two blue)) {
   $host = "$host.fish.net";
   push @PerlConfig, <<EOF;
   Listen $host
   <VirtualHost $host>
   ServerAdmin webmaster\@$host
  ServerName $host
  # ... more config here ...
 </VirtualHost>
EOF
}
</Perl>

One more utility method is available: Apache->httpd_conf, which simply pushes each argument into the @PerlConfig array and tacks a newline onto the end of each.

Apache->httpd_conf(
   "User $ENV{USER}",
   "ServerAdmin $ENV{USER}\@$hostname",
);
   Show Contents   Go to Top   Previous Page   Next Page
Copyright © 1999 by O'Reilly & Associates, Inc.