|  |  | Home / Documentation / 2.0 / API / |  |  | 
|  | ||||
|  |  | |||
|  |  | |||
|  | ||||
|  |    |  | ||
|  | Apache2::PerlSections - write Apache configuration files in Perl |  | ||
|  | ||||
|  |  |  | ||
|  | ||||
|   |  | |||
|  |  |  | 
|  | ||
|  | ||
|  |  |  | 
|  | ||
|  | ||
|  |  |  | 
|  | ||
|  | ||
|  |  |  | 
|  | ||
|  | ||
|  |  |  | 
|  | ||
|  | ||
|  |  |  | 
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
<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          => {
        "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
  Apache2->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>
 
    
    serverGet the current server's object for the <Perl> section
  <Perl>
    $s = Apache2::PerlSections->server();
  </Perl>
Apache2::PerlSections (class name)
$s
( Apache2::ServerRec object )
 
    
    @PerlConfig and $PerlConfigThis 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
 
    
    There are a few variables that can be set to change the default
behaviour of <Perl> sections.
 
    
    $Apache2::PerlSections::SaveEach <Perl> section is evaluated in its unique namespace,
by default residing in a sub-namespace of Apache2::ReadConfig::,
therefore any local variables will end up in that namespace. For
example if a <Perl> section happened to be in file
/tmp/httpd.conf starting on line 20, the namespace:
Apache2::ReadConfig::tmp::httpd_conf::line_20 will be used. Now if
it had:
  <Perl>
    $foo     = 5;
    my $bar  = 6;
    $My::tar = 7;
  </Perl>
The local global variable $foo becomes
$Apache2::ReadConfig::tmp::httpd_conf::line_20::foo, the other
variable remain where they are.
By default, the namespace in which <Perl> sections are
evaluated is cleared after each block closes. In our example nuking
$Apache2::ReadConfig::tmp::httpd_conf::line_20::foo, leaving the
rest untouched.
By setting $Apache2::PerlSections::Save to a true value, the content
of those namespaces will be preserved and will be available for
inspection by Apache2::Status and
Apache2::PerlSections->dump
In our example $Apache2::ReadConfig::tmp::httpd_conf::line_20::foo
will still be accessible from other perl code, after the
<Perl> section was parsed.
 
    
    Apache2::PerlSections->dumpThis 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.
my $dump = Apache2::PerlSections->dump;
$dump ( string / undef )
A string dump of all the Perl code encountered in <Perl> blocks,
suitable to be read back via eval
For example:
  <Perl>
  
  $Apache2::PerlSections::Save = 1;
  
  $Listen = 8529;
  
  $Location{"/perl"} = {
     SetHandler => "perl-script",
     PerlHandler => "ModPerl::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',
       },
     },
  };
  </Perl>
  
  <Perl>
  print Apache2::PerlSections->dump;
  </Perl>
This will print something like this:
  $Listen = 8529;
  
  @DirectoryIndex = (
    'index.htm',
    'index.html'
  );
  
  $Location{'/perl'} = (
      PerlHandler => 'Apache2::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__
It is important to put the call to dump in it's own <Perl>
section, otherwise the content of the current <Perl> section
will not be dumped.
 
    
    Apache2::PerlSections->storeThis method will call the dump method, writing the output
to a file, suitable to be pulled in via require or do.
Apache2::PerlSections->store($filename);
 
    
    mod_perl 2.0 now introduces the same general concept of handlers to
<Perl> sections.  Apache2::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
self-explanatory
$parms
( Apache2::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)
the table object of the section arguments. The 2 guaranteed ones will be:
  $args->{'handler'} = 'My::PerlSection::Handler';
  $args->{'package'} = 'Apache2::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 Apache2::Server->add_config("directive"), for example:
  $parms->server->add_config("Alias /foo /bar");
Would create a new alias. The source code of Apache2::PerlSections
is a good place to look for a practical example.
 
    
    <Perl> SectionsIf the <Perl> sections include no code requiring a running
mod_perl, it is possible to check those from the command line. But the
following trick should be used:
# file: httpd.conf <Perl> #!perl # ... code here ... __END__ </Perl>
Now you can run:
% perl -c httpd.conf
 
    
    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.
 
    
    | 
 |  |    |