зеркало из https://github.com/mozilla/pjs.git
Bug 345547: shutdownhtml will not work under mod_perl
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=justdave, a=justdave
This commit is contained in:
Родитель
2da080f51c
Коммит
c4e039da45
|
@ -77,61 +77,65 @@ 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'};
|
|
||||||
|
|
||||||
# If Bugzilla is shut down, do not allow anything to run, just display a
|
# Some environment variables are not taint safe
|
||||||
# message to the user about the downtime and log out. Scripts listed in
|
delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
|
||||||
# SHUTDOWNHTML_EXEMPT are exempt from this message.
|
|
||||||
#
|
# If Bugzilla is shut down, do not allow anything to run, just display a
|
||||||
# Because this is code which is run live from perl "use" commands of other
|
# message to the user about the downtime and log out. Scripts listed in
|
||||||
# scripts, we're skipping this part if we get here during a perl syntax check
|
# SHUTDOWNHTML_EXEMPT are exempt from this message.
|
||||||
# -- runtests.pl compiles scripts without running them, so we need to make sure
|
#
|
||||||
# that this check doesn't apply to 'perl -c' calls.
|
# 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
|
||||||
# This code must go here. It cannot go anywhere in Bugzilla::CGI, because
|
# check -- runtests.pl compiles scripts without running them, so we
|
||||||
# it uses Template, and that causes various dependency loops.
|
# need to make sure that this check doesn't apply to 'perl -c' calls.
|
||||||
if (!$^C
|
#
|
||||||
&& Bugzilla->params->{"shutdownhtml"}
|
# This code must go here. It cannot go anywhere in Bugzilla::CGI, because
|
||||||
&& lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1)
|
# it uses Template, and that causes various dependency loops.
|
||||||
{
|
if (!$^C && Bugzilla->params->{"shutdownhtml"}
|
||||||
# Allow non-cgi scripts to exit silently (without displaying any
|
&& lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1)
|
||||||
# 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())
|
|
||||||
{
|
{
|
||||||
|
# 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';
|
||||||
|
}
|
||||||
|
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;
|
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';
|
|
||||||
}
|
|
||||||
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
|
# Subroutines and Methods
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
@ -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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
# 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 @@
|
||||||
#
|
#
|
||||||
# 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;
|
||||||
# file.
|
# file.
|
||||||
|
|
||||||
use Apache::DBI ();
|
use Apache::DBI ();
|
||||||
use Bugzilla ();
|
use Apache2::ServerUtil;
|
||||||
use Bugzilla::Constants ();
|
use ModPerl::RegistryLoader ();
|
||||||
use Bugzilla::CGI ();
|
|
||||||
use Bugzilla::Mailer ();
|
|
||||||
use Bugzilla::Template ();
|
|
||||||
use Bugzilla::Util ();
|
|
||||||
use CGI ();
|
use CGI ();
|
||||||
CGI->compile(qw(:cgi -no_xhtml -oldstyle_urls :private_tempfiles
|
CGI->compile(qw(:cgi -no_xhtml -oldstyle_urls :private_tempfiles
|
||||||
:unique_headers SERVER_PUSH :push));
|
:unique_headers SERVER_PUSH :push));
|
||||||
use Template::Config ();
|
use Template::Config ();
|
||||||
Template::Config->preload();
|
Template::Config->preload();
|
||||||
|
|
||||||
# ModPerl::RegistryLoader can pre-compile all CGI scripts.
|
use Bugzilla ();
|
||||||
use ModPerl::RegistryLoader ();
|
use Bugzilla::Constants ();
|
||||||
|
use Bugzilla::CGI ();
|
||||||
|
use Bugzilla::Mailer ();
|
||||||
|
use Bugzilla::Template ();
|
||||||
|
use Bugzilla::Util ();
|
||||||
|
|
||||||
|
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();
|
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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче