]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 345547: shutdownhtml will not work under mod_perl
authormkanat%bugzilla.org <>
Tue, 12 Sep 2006 04:27:52 +0000 (04:27 +0000)
committermkanat%bugzilla.org <>
Tue, 12 Sep 2006 04:27:52 +0000 (04:27 +0000)
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=justdave, a=justdave

Bugzilla.pm
Bugzilla/Constants.pm
mod_perl.pl

index 24e93edc73497830bea73332144796b4b97e2afa..287e054ae7797fb158d5849b2eeb777ff5e803e0 100644 (file)
@@ -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;
index 9559dcae37012fdcb10ba6c7835abbc4a0f438ac..93d8d8d2c12272bb92dd2a6824704c0b2fca2e3f 100644 (file)
@@ -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",
index f36b219b688dc83ea70ea7b8f9c68834eb4a6071..05d781400c5160ef39f65bf99ceb466e16e9847b 100644 (file)
@@ -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;