Commit 901ce06e authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 345547: shutdownhtml will not work under mod_perl

Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=justdave, a=justdave
parent 5af900f5
...@@ -77,24 +77,25 @@ use constant SHUTDOWNHTML_EXIT_SILENTLY => [ ...@@ -77,24 +77,25 @@ use constant SHUTDOWNHTML_EXIT_SILENTLY => [
#} #}
#$::SIG{__DIE__} = \&Bugzilla::die_with_dignity; #$::SIG{__DIE__} = \&Bugzilla::die_with_dignity;
# Some environment variables are not taint safe sub init_page {
delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Some environment variables are not taint safe
# If Bugzilla is shut down, do not allow anything to run, just display a delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# message to the user about the downtime and log out. Scripts listed in
# SHUTDOWNHTML_EXEMPT are exempt from this message. # 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
# Because this is code which is run live from perl "use" commands of other # SHUTDOWNHTML_EXEMPT are exempt from this message.
# 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 # Because this is code which is run live from perl "use" commands of other
# that this check doesn't apply to 'perl -c' calls. # scripts, we're skipping this part if we get here during a perl syntax
# # check -- runtests.pl compiles scripts without running them, so we
# This code must go here. It cannot go anywhere in Bugzilla::CGI, because # need to make sure that this check doesn't apply to 'perl -c' calls.
# it uses Template, and that causes various dependency loops. #
if (!$^C # This code must go here. It cannot go anywhere in Bugzilla::CGI, because
&& Bugzilla->params->{"shutdownhtml"} # it uses Template, and that causes various dependency loops.
if (!$^C && Bugzilla->params->{"shutdownhtml"}
&& lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1) && lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1)
{ {
# Allow non-cgi scripts to exit silently (without displaying any # Allow non-cgi scripts to exit silently (without displaying any
# message), if desired. At this point, no DBI call has been made # message), if desired. At this point, no DBI call has been made
# yet, and no error will be returned if the DB is inaccessible. # yet, and no error will be returned if the DB is inaccessible.
...@@ -130,8 +131,11 @@ if (!$^C ...@@ -130,8 +131,11 @@ if (!$^C
|| ThrowTemplateError($template->error); || ThrowTemplateError($template->error);
print $t_output . "\n"; print $t_output . "\n";
exit; exit;
}
} }
init_page() if !$ENV{MOD_PERL};
##################################################################### #####################################################################
# Subroutines and Methods # Subroutines and Methods
##################################################################### #####################################################################
...@@ -352,21 +356,7 @@ sub hook_args { ...@@ -352,21 +356,7 @@ sub hook_args {
sub request_cache { sub request_cache {
if ($ENV{MOD_PERL}) { if ($ENV{MOD_PERL}) {
require Apache2::RequestUtil; require Apache2::RequestUtil;
my $request = Apache2::RequestUtil->request; return Apache2::RequestUtil->request->pnotes();
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 $_request_cache; return $_request_cache;
} }
...@@ -385,7 +375,8 @@ sub _cleanup { ...@@ -385,7 +375,8 @@ sub _cleanup {
} }
sub END { sub END {
_cleanup(); # Bugzilla.pm cannot compile in mod_perl.pl if this runs.
_cleanup() unless $ENV{MOD_PERL};
} }
1; 1;
......
...@@ -365,6 +365,9 @@ sub bz_locations { ...@@ -365,6 +365,9 @@ sub bz_locations {
# That means that if you modify these paths, they must be absolute paths. # That means that if you modify these paths, they must be absolute paths.
return { return {
'libpath' => $libpath, '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", 'templatedir' => "$libpath/template",
'project' => $project, 'project' => $project,
'localconfig' => "$libpath/$localconfig", 'localconfig' => "$libpath/$localconfig",
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
# #
# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> # Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
package Bugzilla::ModPerl;
use strict; use strict;
# If you have an Apache2::Status handler in your Apache configuration, # If you have an Apache2::Status handler in your Apache configuration,
...@@ -27,27 +29,78 @@ use strict; ...@@ -27,27 +29,78 @@ use strict;
# file. # file.
use Apache::DBI (); 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 ();
use Bugzilla::Constants (); use Bugzilla::Constants ();
use Bugzilla::CGI (); use Bugzilla::CGI ();
use Bugzilla::Mailer (); use Bugzilla::Mailer ();
use Bugzilla::Template (); use Bugzilla::Template ();
use Bugzilla::Util (); 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. my $cgi_path = Bugzilla::Constants::bz_locations()->{'cgi_path'};
use ModPerl::RegistryLoader ();
# 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(); my $rl = new ModPerl::RegistryLoader();
# Note that $cgi_path will be wrong if somebody puts the libraries # Note that $cgi_path will be wrong if somebody puts the libraries
# in a different place than the CGIs. # in a different place than the CGIs.
my $cgi_path = Bugzilla::Constants::bz_locations()->{'libpath'};
foreach my $file (glob "$cgi_path/*.cgi") { foreach my $file (glob "$cgi_path/*.cgi") {
Bugzilla::Util::trick_taint($file); Bugzilla::Util::trick_taint($file);
$rl->handler($file, $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; 1;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment