home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / PerlSections.pm < prev    next >
Encoding:
Perl POD Document  |  2004-09-17  |  14.2 KB  |  610 lines

  1. # Copyright 2003-2004 The Apache Software Foundation
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. #     http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. #
  15. package Apache::PerlSections;
  16.  
  17. use strict;
  18. use warnings FATAL => 'all';
  19.  
  20. our $VERSION = '0.01';
  21.  
  22. use Apache::CmdParms ();
  23. use Apache::Directive ();
  24. use APR::Table ();
  25. use Apache::ServerRec ();
  26. use Apache::ServerUtil ();
  27. use Apache::Const -compile => qw(OK);
  28.  
  29. use constant SPECIAL_NAME => 'PerlConfig';
  30. use constant SPECIAL_PACKAGE => 'Apache::ReadConfig';
  31.  
  32. sub new {
  33.     my($package, @args) = @_;
  34.     return bless { @args }, ref($package) || $package;
  35. }
  36.  
  37. sub server     { return shift->{'parms'}->server() }
  38. sub directives { return shift->{'directives'} ||= [] }
  39. sub package    { return shift->{'args'}->{'package'} }
  40.  
  41. my @saved;
  42. sub save       { return $Apache::Server::SaveConfig }
  43. sub saved      { return @saved }
  44.  
  45. sub handler : method {
  46.     my($self, $parms, $args) = @_;
  47.  
  48.     unless (ref $self) {
  49.         $self = $self->new('parms' => $parms, 'args' => $args);
  50.     }
  51.  
  52.     if ($self->save) {
  53.         push @saved, $self->package;
  54.     }
  55.  
  56.     my $special = $self->SPECIAL_NAME;
  57.  
  58.     for my $entry ($self->symdump()) {
  59.         if ($entry->[0] !~ /$special/) {
  60.             $self->dump_any(@$entry);
  61.         }
  62.     }
  63.  
  64.     {
  65.         no strict 'refs';
  66.         foreach my $package ($self->package) {
  67.             $self->dump_special(${"${package}::$special"},
  68.               @{"${package}::$special"} );
  69.         }
  70.     }
  71.  
  72.     $self->post_config();
  73.  
  74.     Apache::OK;
  75. }
  76.  
  77. sub symdump {
  78.     my($self) = @_;
  79.  
  80.     unless ($self->{symbols}) {
  81.         no strict;
  82.         
  83.         $self->{symbols} = [];
  84.         
  85.         #XXX: Here would be a good place to warn about NOT using 
  86.         #     Apache::ReadConfig:: directly in <Perl> sections
  87.         foreach my $pack ($self->package, $self->SPECIAL_PACKAGE) {
  88.             #XXX: Shamelessly borrowed from Devel::Symdump;
  89.             while (my ($key, $val) = each(%{ *{"$pack\::"} })) {
  90.                 #We don't want to pick up stashes...
  91.                 next if ($key =~ /::$/);
  92.                 local (*ENTRY) = $val;
  93.                 if (defined $val && defined *ENTRY{SCALAR}) {
  94.                     push @{$self->{symbols}}, [$key, $ENTRY];
  95.                 }
  96.                 if (defined $val && defined *ENTRY{ARRAY}) {
  97.                     push @{$self->{symbols}}, [$key, \@ENTRY];
  98.                 }
  99.                 if (defined $val && defined *ENTRY{HASH} && $key !~ /::/) {
  100.                     push @{$self->{symbols}}, [$key, \%ENTRY];
  101.                 }
  102.             }
  103.         }
  104.     }
  105.  
  106.     return @{$self->{symbols}};
  107. }
  108.  
  109. sub dump_special {
  110.     my($self, @data) = @_;
  111.     $self->add_config(@data);
  112. }
  113.  
  114. sub dump_any {
  115.     my($self, $name, $entry) = @_;
  116.     my $type = ref $entry;
  117.  
  118.     if ($type eq 'ARRAY') {
  119.         $self->dump_array($name, $entry);
  120.     }
  121.     elsif ($type eq 'HASH') {
  122.         $self->dump_hash($name, $entry);
  123.     }
  124.     else {
  125.         $self->dump_entry($name, $entry);
  126.     }
  127. }
  128.  
  129. sub dump_hash {
  130.     my($self, $name, $hash) = @_;
  131.  
  132.     for my $entry (sort keys %{ $hash || {} }) {
  133.         my $item = $hash->{$entry};
  134.         my $type = ref($item);
  135.  
  136.         if ($type eq 'HASH') {
  137.             $self->dump_section($name, $entry, $item);
  138.         }
  139.         elsif ($type eq 'ARRAY') {
  140.             for my $e (@$item) {
  141.                 $self->dump_section($name, $entry, $e);
  142.             }
  143.         }
  144.     }
  145. }
  146.  
  147. sub dump_section {
  148.     my($self, $name, $loc, $hash) = @_;
  149.  
  150.     $self->add_config("<$name $loc>\n");
  151.  
  152.     for my $entry (sort keys %{ $hash || {} }) {
  153.         $self->dump_entry($entry, $hash->{$entry});
  154.     }
  155.  
  156.     $self->add_config("</$name>\n");
  157. }
  158.  
  159. sub dump_array {
  160.     my($self, $name, $entries) = @_;
  161.  
  162.     for my $entry (@$entries) {
  163.         $self->dump_entry($name, $entry);
  164.     }
  165. }
  166.  
  167. sub dump_entry {
  168.     my($self, $name, $entry) = @_;
  169.     my $type = ref $entry;
  170.  
  171.     if ($type eq 'SCALAR') {
  172.         $self->add_config("$name $$entry\n");
  173.     }
  174.     elsif ($type eq 'ARRAY') {
  175.         if (grep {ref} @$entry) {
  176.             $self->dump_entry($name, $_) for @$entry;
  177.         }
  178.         else {
  179.             $self->add_config("$name @$entry\n");
  180.         }
  181.     }
  182.     elsif ($type eq 'HASH') {
  183.         $self->dump_hash($name, $entry);
  184.     }
  185.     elsif ($type) {
  186.         #XXX: Could do $type->can('httpd_config') here on objects ???
  187.         die "Unknown type '$type' for directive $name";
  188.     }
  189.     elsif (defined $entry) {
  190.         $self->add_config("$name $entry\n");
  191.     }
  192. }
  193.  
  194. sub add_config {
  195.     my($self, $config) = @_;
  196.     return unless defined $config;
  197.     chomp($config);
  198.     push @{ $self->directives }, $config;
  199. }
  200.  
  201. sub post_config {
  202.     my($self) = @_;
  203.     my $errmsg = $self->server->add_config($self->directives);
  204.     die $errmsg if $errmsg;
  205. }
  206.  
  207. sub dump {
  208.     my $class = shift;
  209.     require Apache::PerlSections::Dump;
  210.     return Apache::PerlSections::Dump->dump(@_);
  211. }
  212.  
  213. sub store {
  214.     my $class = shift;
  215.     require Apache::PerlSections::Dump;
  216.     return Apache::PerlSections::Dump->store(@_);
  217. }
  218.  
  219. 1;
  220. __END__
  221.  
  222. =head1 NAME
  223.  
  224. Apache::PerlSections - Default Handler for Perl sections
  225.  
  226.  
  227.  
  228.  
  229.  
  230. =head1 Synopsis
  231.  
  232.   <Perl >
  233.   @PerlModule = qw(Mail::Send Devel::Peek);
  234.   
  235.   #run the server as whoever starts it
  236.   $User  = getpwuid(>) || >;
  237.   $Group = getgrgid()) || );
  238.   
  239.   $ServerAdmin = $User;
  240.   
  241.   </Perl>
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248. =head1 Description
  249.  
  250. With C<E<lt>Perl E<gt>>...C<E<lt>/PerlE<gt>> sections, it is possible
  251. to configure your server entirely in Perl.
  252.  
  253. C<E<lt>Perl E<gt>> sections can contain I<any> and as much Perl code as
  254. you wish. These sections are compiled into a special package whose
  255. symbol table mod_perl can then walk and grind the names and values of
  256. Perl variables/structures through the Apache core configuration gears.
  257.  
  258. Block sections such as C<E<lt>LocationE<gt>>..C<E<lt>/LocationE<gt>>
  259. are represented in a C<%Location> hash, e.g.:
  260.  
  261.   <Perl>
  262.   $Location{"/~dougm/"} = {
  263.     AuthUserFile   => '/tmp/htpasswd',
  264.     AuthType       => 'Basic',
  265.     AuthName       => 'test',
  266.     DirectoryIndex => [qw(index.html index.htm)],
  267.     Limit          => {
  268.         METHODS => 'GET POST',
  269.         require => 'user dougm',
  270.     },
  271.   };
  272.   </Perl>
  273.  
  274. If an Apache directive can take two or three arguments you may push
  275. strings (the lowest number of arguments will be shifted off the
  276. C<@list>) or use an array reference to handle any number greater than
  277. the minimum for that directive:
  278.  
  279.   push @Redirect, "/foo", "http://www.foo.com/";
  280.   
  281.   push @Redirect, "/imdb", "http://www.imdb.com/";
  282.   
  283.   push @Redirect, [qw(temp "/here" "http://www.there.com")];
  284.  
  285. Other section counterparts include C<%VirtualHost>, C<%Directory> and
  286. C<%Files>.
  287.  
  288. To pass all environment variables to the children with a single
  289. configuration directive, rather than listing each one via C<PassEnv>
  290. or C<PerlPassEnv>, a C<E<lt>Perl E<gt>> section could read in a file and:
  291.  
  292.   push @PerlPassEnv, [$key => $val];
  293.  
  294. or
  295.  
  296.   Apache->httpd_conf("PerlPassEnv $key $val");
  297.  
  298. These are somewhat simple examples, but they should give you the basic
  299. idea. You can mix in any Perl code you desire. See I<eg/httpd.conf.pl>
  300. and I<eg/perl_sections.txt> in the mod_perl distribution for more
  301. examples.
  302.  
  303. Assume that you have a cluster of machines with similar configurations
  304. and only small distinctions between them: ideally you would want to
  305. maintain a single configuration file, but because the configurations
  306. aren't I<exactly> the same (e.g. the C<ServerName> directive) it's not
  307. quite that simple.
  308.  
  309. C<E<lt>Perl E<gt>> sections come to rescue. Now you have a single
  310. configuration file and the full power of Perl to tweak the local
  311. configuration. For example to solve the problem of the C<ServerName>
  312. directive you might have this C<E<lt>Perl E<gt>> section:
  313.  
  314.   <Perl >
  315.   $ServerName = `hostname`;
  316.   </Perl>
  317.  
  318. For example if you want to allow personal directories on all machines
  319. except the ones whose names start with I<secure>:
  320.  
  321.   <Perl >
  322.   $ServerName = `hostname`;
  323.   if ($ServerName !~ /^secure/) {
  324.       $UserDir = "public.html";
  325.   }
  326.   else {
  327.       $UserDir = "DISABLED";
  328.   }
  329.   </Perl>
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336. =head1 C<@PerlConfig> and C<$PerlConfig>
  337.  
  338. This array and scalar can be used to introduce literal configuration
  339. into the apache configuration. For example:
  340.  
  341.   push @PerlConfig, 'Alias /foo /bar';
  342.  
  343. Or:
  344.   $PerlConfig .= "Alias /foo /bar\n";
  345.  
  346. See also
  347. C<L<$r-E<gt>add_config|docs::2.0::api::Apache::RequestUtil/C_add_config_>>
  348.  
  349.  
  350.  
  351.  
  352.  
  353. =head1 Configuration Variables
  354.  
  355. There are a few variables that can be set to change the default
  356. behaviour of C<E<lt>Perl E<gt>> sections.
  357.  
  358.  
  359.  
  360.  
  361.  
  362. =head2 C<$Apache::Server::SaveConfig>
  363.  
  364. By default, the namespace in which C<E<lt>Perl E<gt>> sections are
  365. evaluated is cleared after each block closes. By setting it to a true
  366. value, the content of those namespaces will be preserved and will be
  367. available for inspection by modules like
  368. C<L<Apache::Status|docs::2.0::api::Apache::Status>>.
  369.  
  370.  
  371.  
  372.  
  373.  
  374. =head1 PerlSections Dumping
  375.  
  376.  
  377.  
  378. =head2 Apache::PerlSections-E<gt>dump
  379.  
  380. This method will dump out all the configuration variables mod_perl
  381. will be feeding to the apache config gears. The output is suitable to
  382. read back in via C<eval>.
  383.  
  384. For example:
  385.  
  386.   <Perl>
  387.  
  388.   $Port = 8529;
  389.  
  390.   $Location{"/perl"} = {
  391.      SetHandler => "perl-script",
  392.      PerlHandler => "Apache::Registry",
  393.      Options => "ExecCGI",
  394.   };
  395.  
  396.   @DirectoryIndex = qw(index.htm index.html);
  397.  
  398.   $VirtualHost{"www.foo.com"} = {
  399.      DocumentRoot => "/tmp/docs",
  400.      ErrorLog => "/dev/null",
  401.      Location => {
  402.        "/" => {
  403.          Allowoverride => 'All',
  404.          Order => 'deny,allow',
  405.          Deny  => 'from all',
  406.          Allow => 'from foo.com',
  407.        },
  408.      },
  409.   };
  410.  
  411.   print Apache::PerlSections->dump;
  412.  
  413.   </Perl>
  414.  
  415. This will print something like this:
  416.  
  417.   $Port = 8529;
  418.  
  419.   @DirectoryIndex = (
  420.     'index.htm',
  421.     'index.html'
  422.   );
  423.  
  424.   $Location{'/perl'} = (
  425.       PerlHandler => 'Apache::Registry',
  426.       SetHandler => 'perl-script',
  427.       Options => 'ExecCGI'
  428.   );
  429.  
  430.   $VirtualHost{'www.foo.com'} = (
  431.       Location => {
  432.         '/' => {
  433.           Deny => 'from all',
  434.           Order => 'deny,allow',
  435.           Allow => 'from foo.com',
  436.           Allowoverride => 'All'
  437.         }
  438.       },
  439.       DocumentRoot => '/tmp/docs',
  440.       ErrorLog => '/dev/null'
  441.   );
  442.  
  443.   1;
  444.   __END__
  445.  
  446.  
  447.  
  448.  
  449.  
  450. =head2 Apache::PerlSections-E<gt>store
  451.  
  452. This method will call the C<dump> method, writing the output
  453. to a file, suitable to be pulled in via C<require> or C<do>.
  454.  
  455.  
  456.  
  457.  
  458.  
  459. =head1 Advanced API
  460.  
  461. mod_perl 2.0 now introduces the same general concept of handlers to
  462. C<E<lt>Perl E<gt>> sections.  Apache::PerlSections simply being the
  463. default handler for them.
  464.  
  465. To specify a different handler for a given perl section, an extra
  466. handler argument must be given to the section:
  467.  
  468.   <Perl handler="My::PerlSection::Handler" somearg="test1">
  469.     $foo = 1;
  470.     $bar = 2;
  471.   </Perl>
  472.  
  473. And in My/PerlSection/Handler.pm:
  474.  
  475.   sub My::Handler::handler : handler {
  476.       my($self, $parms, $args) = @_;
  477.       #do your thing!
  478.   }
  479.  
  480. So, when that given C<E<lt>Perl E<gt>> block in encountered, the code
  481. within will first be evaluated, then the handler routine will be
  482. invoked with 3 arguments:
  483.  
  484. =over
  485.  
  486. =item arg1: C<$self>
  487.  
  488. self-explanatory
  489.  
  490. =item arg2: C<$parms>
  491. ( C<L<Apache::CmdParms|docs::2.0::api::Apache::CmdParms>> )
  492.  
  493. C<$parms> is specific for the current Container, for example, you
  494. might want to call C<$parms-E<gt>server()> to get the current server.
  495.  
  496. =item arg3: C<$args>
  497. ( C<L<APR::Table object|docs::2.0::api::APR::Table>>)
  498.  
  499. the table object of the section arguments. The 2 guaranteed ones will
  500. be:
  501.  
  502.   $args->{'handler'} = 'My::PerlSection::Handler';
  503.   $args->{'package'} = 'Apache::ReadConfig';
  504.  
  505. Other C<name="value"> pairs given on the C<E<lt>Perl E<gt>> line will
  506. also be included.
  507.  
  508. =back
  509.  
  510. At this point, it's up to the handler routing to inspect the namespace
  511. of the C<$args>-E<gt>{'package'} and chooses what to do.
  512.  
  513. The most likely thing to do is to feed configuration data back into
  514. apache. To do that, use Apache::Server-E<gt>add_config("directive"),
  515. for example:
  516.  
  517.   $parms->server->add_config("Alias /foo /bar");
  518.  
  519. Would create a new alias. The source code of C<Apache::PerlSections>
  520. is a good place to look for a practical example.
  521.  
  522.  
  523.  
  524.  
  525.  
  526. =head1 Bugs
  527.  
  528.  
  529.  
  530.  
  531. =head2 E<lt>PerlE<gt> directive missing closing 'E<gt>'
  532.  
  533. httpd-2.0.47 had a bug in the configuration parser which caused the
  534. startup failure with the following error:
  535.  
  536.   Starting httpd:
  537.   Syntax error on line ... of /etc/httpd/conf/httpd.conf:
  538.   <Perl> directive missing closing '>'     [FAILED]
  539.  
  540. This has been fixed in httpd-2.0.48. If you can't upgrade to this or a
  541. higher version, please add a space before the closing 'E<gt>' of the
  542. opening tag as a workaround. So if you had:
  543.  
  544.   <Perl>
  545.   # some code
  546.   </Perl>
  547.  
  548. change it to be:
  549.  
  550.   <Perl >
  551.   # some code
  552.   </Perl>
  553.  
  554.  
  555.  
  556.  
  557.  
  558. =head2 E<lt>PerlE<gt>[...]E<gt> was not closed.
  559.  
  560. On encountering a one-line E<lt>PerlE<gt> block, 
  561. httpd's configuration parser will cause a startup
  562. failure with an error similar to this one:
  563.  
  564.   Starting httpd:
  565.   Syntax error on line ... of /etc/httpd/conf/httpd.conf:
  566.   <Perl>use> was not closed.
  567.  
  568. If you have written a simple one-line E<lt>PerlE<gt>
  569. section like this one :
  570.  
  571.   <Perl>use Apache::DBI;</Perl>
  572.  
  573. change it to be:
  574.  
  575.    <Perl>
  576.    use Apache::DBI;
  577.    </Perl>
  578.  
  579. This is caused by a limitation of httpd's configuration
  580. parser and is not likely to be changed to allow one-line
  581. block like the example above. Use multi-line blocks instead.
  582.  
  583.  
  584.  
  585.  
  586. =head1 See Also
  587.  
  588. L<mod_perl 2.0 documentation|docs::2.0::index>.
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595. =head1 Copyright
  596.  
  597. mod_perl 2.0 and its core modules are copyrighted under
  598. The Apache Software License, Version 2.0.
  599.  
  600.  
  601.  
  602.  
  603. =head1 Authors
  604.  
  605. L<The mod_perl development team and numerous
  606. contributors|about::contributors::people>.
  607.  
  608. =cut
  609.  
  610.