Show Contents Previous Page Next Page Chapter 8 - Customizing the Apache Configuration Process / Configuring Apache with Perl For a complete example of an Apache configuration constructed with <Perl> sections, we'll look at Doug's setup. As a freelance contractor, Doug must often configure his development server in a brand-new environment. Rather than creating a customized server configuration file each time, Doug uses a generic configuration that can be brought up anywhere, simply by running: % httpd -f $HOME/httpd.conf This one step automatically creates the server and document roots if they don't exist, as well as the log and configuration directories. It also detects the user that it is being run as, and configures the User and Group directives to match. Example 8-5 shows a slightly simplified version of Doug's httpd.conf. It contains only two hard-coded Apache directives: # file: httpd.conf PerlPassEnv HOME Port 9008 There's a PerlPassEnv directive with the value of The rest of the configuration file is written entirely in Perl: <Perl> #!perl $ServerRoot = "$ENV{HOME}/www"; The <Perl> section begins by choosing a path for the server
root. Doug likes to have his test environment set up under his home directory
in ~/www, so the variable unless (-d "$ServerRoot/logs") { for my $dir ("", qw(logs conf htdocs perl)) { mkdir "$ServerRoot/$dir", 0755; } require File::Copy; File::Copy::cp($0, "$ServerRoot/conf"); } Next, the code detects whether the server root has been properly initialized
and, if not, creates the requisite directories and subdirectories. It looks
to see whether if(-e "$ServerRoot/startup.pl") { $PerlRequire = "startup.pl"; } Next, the code checks whether there is a startup.pl present in
the configuration directory. If this is the first time the server is being
run, the file won't be present, but there may well be one there later. If
the file exists, the code sets the $User = getpwuid($>) || $>; $Group = getgrgid($)) || $); $ServerAdmin = $User; The code sets the User, Group, and ServerAdmin
directives next. The user and group are taken from the Perl magic variables
$ServerName = `hostname`; $DocumentRoot = "$ServerRoot/htdocs"; my $types = "$ServerRoot/conf/mime.types"; $TypesConfig = -e $types ? $types : "/dev/null"; The server name is set to the current host's name by setting the push @Alias, ["/perl" => "$ServerRoot/perl"], ["/icons" => "$ServerRoot/icons"]; Next, the <Perl> section declares some directory aliases.
The URI /perl is aliased to $ServerRoot/perl, and /icons
is aliased to $ServerRoot/icons. Notice how the my $servers = 3; for my $s (qw(MinSpareServers MaxSpareServers StartServers MaxClients)) { $$s = $servers; } Following this, the code sets the various parameters controlling Apache's
preforking. The server doesn't need to handle much load, since it's just Doug's
development server, so for my $l (qw(LockFile ErrorLog TransferLog PidFile ScoreBoardFile)) { $$l = "logs/$l"; #clean out the logs local *FH; open FH, ">$ServerRoot/$$l"; close FH; } We use a similar trick to configure the LockFile, ErrorLog, TransferLog, and other log file-related directives. A few additional lines of code truncate the various log files to zero length if they already exist. Doug likes to start with a clean slate every time he reconfigures and restarts a server. my @mod_perl_cfg = qw{ SetHandler perl-script Options +ExecCGI }; $Location{"/perl-status"} = { @mod_perl_cfg, PerlHandler => "Apache::Status", }; $Location{"/perl"} = { @mod_perl_cfg, PerlHandler => "Apache::Registry", }; The remainder of the configuration file sets up some directories for running
and debugging Perl API modules. We create a lexical variable named use Apache::PerlSections (); Apache::PerlSections->store("$ServerRoot/ServerConfig.pm"); The very last thing that the <Perl> section does is to write out the current configuration into the file $ServerRoot/ServerConfig.pm. This snapshots the current configuration in a form that Doug can review and edit, if necessary. Just the configuration variables set within the <Perl> section are snapshot. The PerlPass-Env and Port directives, which are outside the section, are not captured and will have to be added manually. This technique makes possible the following interesting trick: % httpd -C "PerlModule ServerConfig" The -C switch tells httpd to process the directive PerlModule,
which in turn loads the module file ServerConfig.pm. Provided that
Perl's Example 8-5. Doug's Generic httpd.conf # file: httpd.conf PerlPassEnv HOME Port 9008 <Perl> #!perl $ServerRoot = "$ENV{HOME}/www"; unless (-d "$ServerRoot/logs") { for my $dir ("", qw(logs conf htdocs perl)) { mkdir "$ServerRoot/$dir", 0755; } require File::Copy; File::Copy::cp($0, "$ServerRoot/conf"); } if(-e "$ServerRoot/startup.pl") { $PerlRequire = "startup.pl"; } $User = getpwuid($>) || $>; $Group = getgrgid($)) || $); $ServerAdmin = $User; $ServerName = `hostname`; $DocumentRoot = "$ServerRoot/htdocs"; my $types = "$ServerRoot/conf/mime.types"; $TypesConfig = -e $types ? $types : "/dev/null"; push @Alias, ["/perl" => "$ServerRoot/perl"], ["/icons" => "$ServerRoot/icons"]; my $servers = 3; for my $s (qw(MinSpareServers MaxSpareServers StartServers MaxClients)) { $$s = $servers; } for my $l (qw(LockFile ErrorLog TransferLog PidFile ScoreBoardFile)) { $$l = "logs/$l"; #clean out the logs local *FH; open FH, ">$ServerRoot/$$l"; close FH; } my @mod_perl_cfg = qw{ SetHandler perl-script Options +ExecCGI }; $Location{"/perl-status"} = { @mod_perl_cfg, PerlHandler => "Apache::Status", }; $Location{"/perl"} = { @mod_perl_cfg, PerlHandler => "Apache::Registry", }; use Apache::PerlSections (); Apache::PerlSections->store("$ServerRoot/ServerConfig.pm"); __END__ </Perl>Show Contents Previous Page Next Page Copyright © 1999 by O'Reilly & Associates, Inc. |
HIVE: All information for read only. Please respect copyright! |