With your patch, if I have:
PerlPostConfigHandler A <VirtualHost one> PerlPostConfigHandler B </VirtualHost> <VirtualHost two> PerlPostConfigHandler C </VirtualHost>
then A gets run once, B gets run once, and C gets run once.
But if I have:
PerlPostConfigHandler A <VirtualHost one> </VirtualHost> <VirtualHost two> PerlPostConfigHandler C </VirtualHost>
then A gets run twice (once for the main server and once for the vhost) and C gets run once?
If so, that would be even more confusing, and any author of a PostConfigHandler would need to make sure that the code is safe if run for each vhost. I think that would cause more problems than it would solve.
In my case a better solution would be to write a PerlPostConfigHandler that walked the config tree and did the right thing for each vhost. In the case of Apache::PageKit, Boris Zenter has already posted a workaround. An alternative to that would be something like this:
PerlPostConfigHandler PageKitHandler::handle <VirtualHost one> PerlSetVar PKIT_ROOT onevalue PerlSetVar PKIT_SERVER serverone </VirtualHost> <VirtualHost one> PerlSetVar PKIT_ROOT twovalue PerlSetVar PKIT_SERVER servervalue </VirtualHost>
sub handle {
my $tree = Apache::Directive->conftree;
my @pkitroots = $tree->lookup('PerlSetVar', 'PKIT_ROOT');
foreach my $node (@pkitroots) {
my $rootvalue = $node->args->[1];
my $servervalue;
my $sib = $node->parent->first_child;
while ($sib) {
if (lc $sib->directive eq 'perlsetvar' && $sub->args->[0] eq 'PKIT_SERVER') {
$servervalue = $sub->args->[1];
last;
}
$sib = $sib->next;
}
Apache::PageKit->startup($rootvalue, $servervalue);
}
In other words, look for places where PKIT_ROOT is set and then look up the value of PKIT_SERVER set in the same scope, and call Apache::PageKit->startup with both args.
Actually this doesn't quite work because if PKIT_SERVER is inherited from an enclosing scope, then the code above won't find it -- it really should recurse upward on the parent if it doesn't find a value for PKIT_SERVER. Furthermore, it doesn't consider PerlAddVar. It would be nice if Apache::Directive was extended so that one could do the equivalent of $node->dir_config("value").
-P
On Sun, 21 Dec 2003 19:46:15 -0800, Stas Bekman <[EMAIL PROTECTED]> wrote:
Stas Bekman wrote:Paul G. Weiss wrote:
Rats! PerlPostConfigHandler appears to have absolutely no effect when placed inside a <VirtualHost> scope. It does indeed run when placed outside. I know this because I have something like:
open(H, ">", "/tmp/output"); print H "something\n"
in my handler and the file written to only when PerlPostConfigHandler is outside the <VirtualHost> scope. By the way, this is also true with PostOpenLogsHandler. In fact, when I set
PerlTrace all
in my configuration file, I see the line:
modperl_callback_run_handlers: no PerlPostConfigHandler handlers configured ()
You are right. I added a test and it fails :( I was pretty sure that it should have worked.
OK, we have to do it ourselves, which is easy (.e.g with the patch below). The problem is this: all vhosts inherit PerlPostConfigHandler from the main server and run it. They all inherit the PerlSetVar as well. I'm not sure this is the wanted behavior. I suppose this is why Apache doesn't do it for each vhost. Comments?
Index: src/modules/perl/mod_perl.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v
retrieving revision 1.205
diff -u -r1.205 mod_perl.c
--- src/modules/perl/mod_perl.c 15 Dec 2003 08:24:57 -0000 1.205
+++ src/modules/perl/mod_perl.c 22 Dec 2003 03:31:13 -0000
@@ -588,6 +588,17 @@
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
"mod_perl: using Perl HASH_SEED: %"UVuf, MP_init_hash_seed);
#endif
+
+ /* run PerlPostConfigHandler for each vhost (apache already does
+ * that for the main server) */
+ for (s=s->next; s; s=s->next) {
+ int rc = modperl_callback_files(MP_POST_CONFIG_HANDLER,
+ pconf, plog, ptemp, s,
+ MP_HOOK_RUN_ALL);
+ if (rc != OK) {
+ return rc;
+ }
+ }
return OK; }
Here is the test:
--- /dev/null 1969-12-31 16:00:00.000000000 -0800 +++ t/hooks/startup.t 2003-12-21 19:05:29.000000000 -0800 @@ -0,0 +1,28 @@ + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $config = Apache::Test::config(); +my $path = Apache::TestRequest::module2path('TestHooks::startup'); + +# XXX: vhosts are not run for postconfig at the moment +my @modules = qw(default TestHooks::startup); +#my @modules = qw(default TestHooks::); + +plan tests => scalar @modules; + +for my $module (sort @modules) { + + Apache::TestRequest::module($module); + my $hostport = Apache::TestRequest::hostport($config); + t_debug("connecting to $hostport"); + + ok t_cmp("ok", + GET_BODY_ASSERT("http://$hostport/$path"), + "testing PostConfig"); +} +
--- /dev/null 1969-12-31 16:00:00.000000000 -0800
+++ t/hooks/TestHooks/startup.pm 2003-12-21 01:12:31.000000000 -0800
@@ -0,0 +1,89 @@
+package TestHooks::startup;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+use Apache::TestTrace;
+
+use APR::Table;
+use Apache::Server ();
+use Apache::ServerUtil ();
+use Apache::RequestRec ();
+use Apache::RequestIO ();
+
+use File::Spec::Functions qw(catfile catdir);
+use File::Path qw(mkpath);
+
+use Apache::Const -compile => 'OK';
+
+my $dir = catdir Apache::Test::config()->{vars}->{documentroot}, 'hooks',
+ 'startup';
+
+sub post_config {
+ my($conf_pool, $log_pool, $temp_pool, $s) = @_;
+
+ my $val = $s->dir_config->{PostConfig} or die "Can't read PostConfig var";
+ debug "configuration is completed: $val";
+
+ my $file = catfile $dir, $s->port;
+
+ mkpath $dir, 0, 0755;
+ open my $fh, ">$file" or die "can't open $file: $!";
+ print $fh $val;
+ close $fh;
+
+ Apache::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ my $s = $r->server;
+ my $expected = $s->dir_config->{PostConfig}
+ or die "Can't read PostConfig var";
+ my $port = $s->port;
+
+ my $file = catfile $dir, $port;
+ open my $fh, "$file" or die "can't open $file: $!";
+ my $received = <$fh> || '';
+ close $fh;
+
+ # cleanup
+ unlink $file;
+
+ if ($expected eq $received) {
+ $r->print("ok");
+ }
+ else {
+ warn "port: $port";
+ warn "expected: $expected\n";
+ warn "received: $received\n";
+ }
+
+ Apache::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+<VirtualHost TestHooks::startup>
+ PerlSetVar PostConfig VHost
+ PerlModule TestHooks::startup
+ PerlPostConfigHandler TestHooks::startup::post_config
+ <Location /TestHooks__startup>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::startup
+ </Location>
+</VirtualHost>
+PerlSetVar PostConfig Main
+PerlModule TestHooks::startup
+PerlPostConfigHandler TestHooks::startup::post_config
+<Location /TestHooks__startup>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::startup
+</Location>
+</NoAutoConfig>
__________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
-- Reporting bugs: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html