summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormkanat%bugzilla.org <>2006-09-12 06:27:52 +0200
committermkanat%bugzilla.org <>2006-09-12 06:27:52 +0200
commit901ce06e6c9218b93b84fee09f9720204623dc19 (patch)
tree5ba32e48390c5331e2cf4fea701b3c592eb7fa97
parent5af900f573eec2bc561fec23092dfe8419342a50 (diff)
downloadbugzilla-901ce06e6c9218b93b84fee09f9720204623dc19.tar.gz
bugzilla-901ce06e6c9218b93b84fee09f9720204623dc19.tar.xz
Bug 345547: shutdownhtml will not work under mod_perl
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=justdave, a=justdave
-rw-r--r--Bugzilla.pm123
-rw-r--r--Bugzilla/Constants.pm3
-rw-r--r--mod_perl.pl69
3 files changed, 121 insertions, 74 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm
index 24e93edc7..287e054ae 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -77,61 +77,65 @@ use constant SHUTDOWNHTML_EXIT_SILENTLY => [
#}
#$::SIG{__DIE__} = \&Bugzilla::die_with_dignity;
-# Some environment variables are not taint safe
-delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
-
-# If Bugzilla is shut down, do not allow anything to run, just display a
-# message to the user about the downtime and log out. Scripts listed in
-# SHUTDOWNHTML_EXEMPT are exempt from this message.
-#
-# Because this is code which is run live from perl "use" commands of other
-# scripts, we're skipping this part if we get here during a perl syntax check
-# -- runtests.pl compiles scripts without running them, so we need to make sure
-# that this check doesn't apply to 'perl -c' calls.
-#
-# This code must go here. It cannot go anywhere in Bugzilla::CGI, because
-# it uses Template, and that causes various dependency loops.
-if (!$^C
- && Bugzilla->params->{"shutdownhtml"}
- && lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1)
-{
- # Allow non-cgi scripts to exit silently (without displaying any
- # message), if desired. At this point, no DBI call has been made
- # yet, and no error will be returned if the DB is inaccessible.
- if (lsearch(SHUTDOWNHTML_EXIT_SILENTLY, basename($0)) > -1
- && !i_am_cgi())
+sub init_page {
+
+ # Some environment variables are not taint safe
+ delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
+
+ # If Bugzilla is shut down, do not allow anything to run, just display a
+ # message to the user about the downtime and log out. Scripts listed in
+ # SHUTDOWNHTML_EXEMPT are exempt from this message.
+ #
+ # Because this is code which is run live from perl "use" commands of other
+ # scripts, we're skipping this part if we get here during a perl syntax
+ # check -- runtests.pl compiles scripts without running them, so we
+ # need to make sure that this check doesn't apply to 'perl -c' calls.
+ #
+ # This code must go here. It cannot go anywhere in Bugzilla::CGI, because
+ # it uses Template, and that causes various dependency loops.
+ if (!$^C && Bugzilla->params->{"shutdownhtml"}
+ && lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1)
{
- exit;
- }
+ # Allow non-cgi scripts to exit silently (without displaying any
+ # message), if desired. At this point, no DBI call has been made
+ # yet, and no error will be returned if the DB is inaccessible.
+ if (lsearch(SHUTDOWNHTML_EXIT_SILENTLY, basename($0)) > -1
+ && !i_am_cgi())
+ {
+ exit;
+ }
- # For security reasons, log out users when Bugzilla is down.
- # Bugzilla->login() is required to catch the logincookie, if any.
- my $user = Bugzilla->login(LOGIN_OPTIONAL);
- my $userid = $user->id;
- Bugzilla->logout();
-
- my $template = Bugzilla->template;
- my $vars = {};
- $vars->{'message'} = 'shutdown';
- $vars->{'userid'} = $userid;
- # Generate and return a message about the downtime, appropriately
- # for if we're a command-line script or a CGI script.
- my $extension;
- if (i_am_cgi() && (!Bugzilla->cgi->param('ctype')
- || Bugzilla->cgi->param('ctype') eq 'html')) {
- $extension = 'html';
- }
- else {
- $extension = 'txt';
+ # For security reasons, log out users when Bugzilla is down.
+ # Bugzilla->login() is required to catch the logincookie, if any.
+ my $user = Bugzilla->login(LOGIN_OPTIONAL);
+ my $userid = $user->id;
+ Bugzilla->logout();
+
+ my $template = Bugzilla->template;
+ my $vars = {};
+ $vars->{'message'} = 'shutdown';
+ $vars->{'userid'} = $userid;
+ # Generate and return a message about the downtime, appropriately
+ # for if we're a command-line script or a CGI script.
+ my $extension;
+ if (i_am_cgi() && (!Bugzilla->cgi->param('ctype')
+ || Bugzilla->cgi->param('ctype') eq 'html')) {
+ $extension = 'html';
+ }
+ else {
+ $extension = 'txt';
+ }
+ print Bugzilla->cgi->header() if i_am_cgi();
+ my $t_output;
+ $template->process("global/message.$extension.tmpl", $vars, \$t_output)
+ || ThrowTemplateError($template->error);
+ print $t_output . "\n";
+ exit;
}
- print Bugzilla->cgi->header() if i_am_cgi();
- my $t_output;
- $template->process("global/message.$extension.tmpl", $vars, \$t_output)
- || ThrowTemplateError($template->error);
- print $t_output . "\n";
- exit;
}
+init_page() if !$ENV{MOD_PERL};
+
#####################################################################
# Subroutines and Methods
#####################################################################
@@ -352,21 +356,7 @@ sub hook_args {
sub request_cache {
if ($ENV{MOD_PERL}) {
require Apache2::RequestUtil;
- my $request = Apache2::RequestUtil->request;
- my $cache = $request->pnotes();
- # Sometimes mod_perl doesn't properly call DESTROY on all
- # the objects in pnotes(), so we register a cleanup handler
- # to make sure that this happens.
- if (!$cache->{cleanup_registered}) {
- $request->push_handlers(PerlCleanupHandler => sub {
- my $r = shift;
- foreach my $key (keys %{$r->pnotes}) {
- delete $r->pnotes->{$key};
- }
- });
- $cache->{cleanup_registered} = 1;
- }
- return $cache;
+ return Apache2::RequestUtil->request->pnotes();
}
return $_request_cache;
}
@@ -385,7 +375,8 @@ sub _cleanup {
}
sub END {
- _cleanup();
+ # Bugzilla.pm cannot compile in mod_perl.pl if this runs.
+ _cleanup() unless $ENV{MOD_PERL};
}
1;
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 9559dcae3..93d8d8d2c 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -365,6 +365,9 @@ sub bz_locations {
# That means that if you modify these paths, they must be absolute paths.
return {
'libpath' => $libpath,
+ # If you put the libraries in a different location than the CGIs,
+ # make sure this still points to the CGIs.
+ 'cgi_path' => $libpath,
'templatedir' => "$libpath/template",
'project' => $project,
'localconfig' => "$libpath/$localconfig",
diff --git a/mod_perl.pl b/mod_perl.pl
index f36b219b6..05d781400 100644
--- a/mod_perl.pl
+++ b/mod_perl.pl
@@ -15,6 +15,8 @@
#
# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
+package Bugzilla::ModPerl;
+
use strict;
# If you have an Apache2::Status handler in your Apache configuration,
@@ -27,27 +29,78 @@ use strict;
# file.
use Apache::DBI ();
+use Apache2::ServerUtil;
+use ModPerl::RegistryLoader ();
+use CGI ();
+CGI->compile(qw(:cgi -no_xhtml -oldstyle_urls :private_tempfiles
+ :unique_headers SERVER_PUSH :push));
+use Template::Config ();
+Template::Config->preload();
+
use Bugzilla ();
use Bugzilla::Constants ();
use Bugzilla::CGI ();
use Bugzilla::Mailer ();
use Bugzilla::Template ();
use Bugzilla::Util ();
-use CGI ();
-CGI->compile(qw(:cgi -no_xhtml -oldstyle_urls :private_tempfiles
- :unique_headers SERVER_PUSH :push));
-use Template::Config ();
-Template::Config->preload();
-# ModPerl::RegistryLoader can pre-compile all CGI scripts.
-use ModPerl::RegistryLoader ();
+my $cgi_path = Bugzilla::Constants::bz_locations()->{'cgi_path'};
+
+# Set up the configuration for the web server
+my $server = Apache2::ServerUtil->server;
+my $conf = <<EOT;
+<Directory "$cgi_path">
+ AddHandler perl-script .cgi
+ # No need to PerlModule these because they're already defined in mod_perl.pl
+ PerlResponseHandler Bugzilla::ModPerl::ResponseHandler
+ PerlCleanupHandler Bugzilla::ModPerl::CleanupHandler
+ PerlOptions +ParseHeaders
+ Options +ExecCGI
+</Directory>
+EOT
+
+$server->add_config([split("\n", $conf)]);
+
+# Have ModPerl::RegistryLoader pre-compile all CGI scripts.
my $rl = new ModPerl::RegistryLoader();
# Note that $cgi_path will be wrong if somebody puts the libraries
# in a different place than the CGIs.
-my $cgi_path = Bugzilla::Constants::bz_locations()->{'libpath'};
foreach my $file (glob "$cgi_path/*.cgi") {
Bugzilla::Util::trick_taint($file);
$rl->handler($file, $file);
}
+
+package Bugzilla::ModPerl::ResponseHandler;
+use strict;
+use base qw(ModPerl::Registry);
+use Bugzilla;
+
+sub handler : method {
+ my $class = shift;
+
+ # $0 is broken under mod_perl before 2.0.2, so we have to set it
+ # here explicitly or init_page's shutdownhtml code won't work right.
+ $0 = $ENV{'SCRIPT_FILENAME'};
+ Bugzilla::init_page();
+ return $class->SUPER::handler(@_);
+}
+
+
+package Bugzilla::ModPerl::CleanupHandler;
+use strict;
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ # Sometimes mod_perl doesn't properly call DESTROY on all
+ # the objects in pnotes()
+ foreach my $key (keys %{$r->pnotes}) {
+ delete $r->pnotes->{$key};
+ }
+
+ return Apache2::Const::OK;
+}
+
1;