Hi John,
I've written such custom container few weeks ago,
and meet the same problems as you.
First, don't use the EXEC_ON_READ option.
Indeed, it doesn't work. Unfortunately, I don't know why.
But it doesn't care, you can perform your job without using it.
I've written a small perl function to solve the as_string issue.
# Unfortunately, directive->as_string doesn't expand
# the content of all embeded sub-containers.
# Because directive->as_string seems to be buggy
# We load the content of the custom container
# by recursing into the directive tree
sub loadContent {
my ($directive, $contentRef) = @_;
my @newContent;
for (my $currentDirective = $directive->first_child;
$currentDirective; $currentDirective = $currentDirective->next) {
if ($currentDirective->first_child) {
my ($containerName) = $currentDirective->directive =~
m/<\s*(.+)$/;
die "Container directive expected instead of " . $currentDirective->directive unless ($containerName);
my $containerBegin = $currentDirective->directive . " " . $currentDirective->args;
push(@newContent, $containerBegin);
loadContent($currentDirective, suppressed);
my $containerEnd = "</" . $containerName . ">";
push(@newContent, $containerEnd);
} else {
my $line = $currentDirective->directive . " " .
$currentDirective->args;
push(@newContent, $line);
}
}
push(@$contentRef, @newContent);
}
Finally, you can write your custom container using this function :
use strict;
use warnings FATAL => 'all';
use Apache2::Const -compile => qw(NO_ARGS OR_ALL RAW_ARGS);
use Apache2::CmdParms ();
use Apache2::Module ();
use Apache2::Directive ();
use Apache2::ServerUtil ();
my @directives = (
{
name => '<StdVHost',
func => __PACKAGE__ . '::StdVHost',
req_override => Apache2::Const::OR_ALL,
args_how => Apache2::Const::RAW_ARGS,
errmsg => 'Std vhosts container',
},
{
name => '</StdVHost>',
func => __PACKAGE__ . "::StdVHost_END",
errmsg => 'end of StdVHost without beginning?',
args_how => Apache2::Const::NO_ARGS,
req_override => Apache2::Const::OR_ALL,
},
);
Apache2::Module::add(__PACKAGE__, suppressed);
sub StdVHost {
my ($self, $parms, $arg) = @_;
# Load the container configuration content
my $directive = $parms->directive;
my @content;
loadContent($directive, suppressed);
# ... Do your custom job
# For example dynamically add apache configuration directives read
inside the custom container :
Apache2::ServerUtil->server->add_config(suppressed);
}
sub StdVHost_END {
die "</StdVHost> outside a <StdVHost> container\n";
}
Hope this example can help you.
Best regards
Fred
Le 23.12.-28158 20:59, John Hallam a écrit :
I'm trying to create a custom block directive, following the documentation in the ModPerl2 book (or the on-line documentation). The minimal code for the problem I am seeing is below. I have the following block in apache2.conf for the new block <StdVHost ...> and the module is in the /root/apache2 tree as required.--- PerlSwitches -wT -Mlib=/root/apache2 PerlLoadModule MyApache::StdVHost; <StdVHost test arguments> <Directory /var/www > Order deny,allow Deny from all </Directory> </StdVHost> ---I see two behaviours: if EXEC_ON_READ is set, by removing the string ', #' in the code below, the handler is never invoked -- at least die "..." is not visibly executed; if EXEC_ON_READ is unset, the handler is invoked but $cont is just the first line <Directory /var/www> and not the whole block. Neither is what I wanted :-((.The problem seems to have been reported back in 2005, with similar code, and an implication that it was to be fixed. So what am I doing wrong?Thanks in advance, John Hallam ---# PERL module for automating a standard virtual host configuration for Apachepackage MyApache::StdVHost; use strict; use warnings FATAL => 'all'; use Apache2::Const -compile => qw(RSRC_CONF RAW_ARGS EXEC_ON_READ); use Apache2::CmdParms (); use Apache2::Module (); use Apache2::Directive (); use Apache2::ServerUtil (); my @directives = ( # Definition of a StdVHost container # # Note that EXEC_ON_READ is necessary, according to the # mod_perl2 book, but in fact breaks things if included # by stopping the handler from being called. { name => '<StdVHost', func => __PACKAGE__ . '::StdVHost', errmsg => 'StdVHost minimal test package', args_how => Apache2::Const::RAW_ARGS,req_override => Apache2::Const::RSRC_CONF, #| Apache2::Const::EXEC_ON_READ,}, ); Apache2::Module::add( __PACKAGE__, suppressed ); # Handler for the config directive. # # It is unclear how to get the content of the <StdVHost> directive # container: maybe it has not been read when this routine is called? # With RAW_ARGS, the first line of the content is available as # $parms->directive->as_string but how do you get the rest?? sub StdVHost { my ($self,$parms,$arg) = @_; my $cont = $parms->directive->as_string(); die "StdVHost arg='$arg' cont='$cont'"; } 1;
begin:vcard fn:Frederic Paillart n:Paillart;Frederic org:gemalto;WSDS adr:ZI Athelia IV;;La Vigie;La Ciotat;;13705;France email;internet:suppressed title:Development Engineer tel;work:04 42 36 43 38 tel;fax:04 42 36 32 00 x-mozilla-html:TRUE url:http://www.gemalto.com version:2.1 end:vcard
Mail converted by mhonarc 2.6.15
This archive provided courtesy of JSW4.NET, Internet Hosting Services for Small Business.