Apache::PerlSections - Default Handler for Perl sections |
@PerlConfig
and $PerlConfig
Apache::PerlSections - Default Handler for Perl sections
<Perl > @PerlModule = qw(Mail::Send Devel::Peek);
#run the server as whoever starts it $User = getpwuid(>) || >; $Group = getgrgid()) || );
$ServerAdmin = $User;
</Perl>
With <Perl >
...</Perl>
sections, it is possible
to configure your server entirely in Perl.
<Perl >
sections can contain any and as much Perl code as
you wish. These sections are compiled into a special package whose
symbol table mod_perl can then walk and grind the names and values of
Perl variables/structures through the Apache core configuration gears.
Block sections such as <Location>
..</Location>
are represented in a %Location
hash, e.g.:
<Perl> $Location{"/~dougm/"} = { AuthUserFile => '/tmp/htpasswd', AuthType => 'Basic', AuthName => 'test', DirectoryIndex => [qw(index.html index.htm)], Limit => { METHODS => 'GET POST', require => 'user dougm', }, }; </Perl>
If an Apache directive can take two or three arguments you may push
strings (the lowest number of arguments will be shifted off the
@list
) or use an array reference to handle any number greater than
the minimum for that directive:
push @Redirect, "/foo", "http://www.foo.com/";
push @Redirect, "/imdb", "http://www.imdb.com/";
push @Redirect, [qw(temp "/here" "http://www.there.com")];
Other section counterparts include %VirtualHost
, %Directory
and
%Files
.
To pass all environment variables to the children with a single
configuration directive, rather than listing each one via PassEnv
or PerlPassEnv
, a <Perl >
section could read in a file and:
push @PerlPassEnv, [$key => $val];
or
Apache->httpd_conf("PerlPassEnv $key $val");
These are somewhat simple examples, but they should give you the basic idea. You can mix in any Perl code you desire. See eg/httpd.conf.pl and eg/perl_sections.txt in the mod_perl distribution for more examples.
Assume that you have a cluster of machines with similar configurations
and only small distinctions between them: ideally you would want to
maintain a single configuration file, but because the configurations
aren't exactly the same (e.g. the ServerName
directive) it's not
quite that simple.
<Perl >
sections come to rescue. Now you have a single
configuration file and the full power of Perl to tweak the local
configuration. For example to solve the problem of the ServerName
directive you might have this <Perl >
section:
<Perl > $ServerName = `hostname`; </Perl>
For example if you want to allow personal directories on all machines except the ones whose names start with secure:
<Perl > $ServerName = `hostname`; if ($ServerName !~ /^secure/) { $UserDir = "public.html"; } else { $UserDir = "DISABLED"; } </Perl>
@PerlConfig
and $PerlConfig
This array and scalar can be used to introduce literal configuration into the apache configuration. For example:
push @PerlConfig, 'Alias /foo /bar';
Or: $PerlConfig .= ``Alias /foo /bar\n'';
See also
$r->add_config|docs::2.0::api::Apache::RequestUtil/C_add_config_
There are a few variables that can be set to change the default
behaviour of <Perl >
sections.
$Apache::Server::SaveConfig
By default, the namespace in which <Perl >
sections are
evaluated is cleared after each block closes. By setting it to a true
value, the content of those namespaces will be preserved and will be
available for inspection by modules like
Apache::Status|docs::2.0::api::Apache::Status
.
This method will dump out all the configuration variables mod_perl
will be feeding to the apache config gears. The output is suitable to
read back in via eval
.
For example:
<Perl>
$Port = 8529;
$Location{"/perl"} = { SetHandler => "perl-script", PerlHandler => "Apache::Registry", Options => "ExecCGI", };
@DirectoryIndex = qw(index.htm index.html);
$VirtualHost{"www.foo.com"} = { DocumentRoot => "/tmp/docs", ErrorLog => "/dev/null", Location => { "/" => { Allowoverride => 'All', Order => 'deny,allow', Deny => 'from all', Allow => 'from foo.com', }, }, };
print Apache::PerlSections->dump;
</Perl>
This will print something like this:
$Port = 8529;
@DirectoryIndex = ( 'index.htm', 'index.html' );
$Location{'/perl'} = ( PerlHandler => 'Apache::Registry', SetHandler => 'perl-script', Options => 'ExecCGI' );
$VirtualHost{'www.foo.com'} = ( Location => { '/' => { Deny => 'from all', Order => 'deny,allow', Allow => 'from foo.com', Allowoverride => 'All' } }, DocumentRoot => '/tmp/docs', ErrorLog => '/dev/null' );
1; __END__
This method will call the dump
method, writing the output
to a file, suitable to be pulled in via require
or do
.
mod_perl 2.0 now introduces the same general concept of handlers to
<Perl >
sections. Apache::PerlSections simply being the
default handler for them.
To specify a different handler for a given perl section, an extra handler argument must be given to the section:
<Perl handler="My::PerlSection::Handler" somearg="test1"> $foo = 1; $bar = 2; </Perl>
And in My/PerlSection/Handler.pm:
sub My::Handler::handler : handler { my($self, $parms, $args) = @_; #do your thing! }
So, when that given <Perl >
block in encountered, the code
within will first be evaluated, then the handler routine will be
invoked with 3 arguments:
$self
$parms
( Apache::CmdParms|docs::2.0::api::Apache::CmdParms
)$parms
is specific for the current Container, for example, you
might want to call $parms->server()
to get the current server.
$args
( APR::Table object|docs::2.0::api::APR::Table
)$args->{'handler'} = 'My::PerlSection::Handler'; $args->{'package'} = 'Apache::ReadConfig';
Other name="value"
pairs given on the <Perl >
line will
also be included.
At this point, it's up to the handler routing to inspect the namespace
of the $args
->{'package'} and chooses what to do.
The most likely thing to do is to feed configuration data back into apache. To do that, use Apache::Server->add_config(``directive''), for example:
$parms->server->add_config("Alias /foo /bar");
Would create a new alias. The source code of Apache::PerlSections
is a good place to look for a practical example.
httpd-2.0.47 had a bug in the configuration parser which caused the startup failure with the following error:
Starting httpd: Syntax error on line ... of /etc/httpd/conf/httpd.conf: <Perl> directive missing closing '>' [FAILED]
This has been fixed in httpd-2.0.48. If you can't upgrade to this or a higher version, please add a space before the closing '>' of the opening tag as a workaround. So if you had:
<Perl> # some code </Perl>
change it to be:
<Perl > # some code </Perl>
On encountering a one-line <Perl> block, httpd's configuration parser will cause a startup failure with an error similar to this one:
Starting httpd: Syntax error on line ... of /etc/httpd/conf/httpd.conf: <Perl>use> was not closed.
If you have written a simple one-line <Perl> section like this one :
<Perl>use Apache::DBI;</Perl>
change it to be:
<Perl> use Apache::DBI; </Perl>
This is caused by a limitation of httpd's configuration parser and is not likely to be changed to allow one-line block like the example above. Use multi-line blocks instead.
mod_perl 2.0 and its core modules are copyrighted under The Apache Software License, Version 2.0.
The mod_perl development team and numerous contributors.
Apache::PerlSections - Default Handler for Perl sections |