diff options
Diffstat (limited to 'mod_perl.pl')
-rw-r--r-- | mod_perl.pl | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/mod_perl.pl b/mod_perl.pl new file mode 100644 index 0000000..ae15ae5 --- /dev/null +++ b/mod_perl.pl @@ -0,0 +1,151 @@ +#!/usr/bin/perl -wT +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::ModPerl; +use strict; +use warnings; + +# This sets up our libpath without having to specify it in the mod_perl +# configuration. +use File::Basename; +use lib dirname(__FILE__); +use Bugzilla::Constants (); +use lib Bugzilla::Constants::bz_locations()->{'ext_libpath'}; + +# If you have an Apache2::Status handler in your Apache configuration, +# you need to load Apache2::Status *here*, so that any later-loaded modules +# can report information to Apache2::Status. +#use Apache2::Status (); + +# We don't want to import anything into the global scope during +# startup, so we always specify () after using any module in this +# file. + +use Apache2::Log (); +use Apache2::ServerUtil; +use ModPerl::RegistryLoader (); +use File::Basename (); +use DateTime (); + +# This loads most of our modules. +use Bugzilla (); +# Loading Bugzilla.pm doesn't load this, though, and we want it preloaded. +use Bugzilla::BugMail (); +use Bugzilla::CGI (); +use Bugzilla::Extension (); +use Bugzilla::Install::Requirements (); +use Bugzilla::Util (); +use Bugzilla::RNG (); + +# Make warnings go to the virtual host's log and not the main +# server log. +BEGIN { *CORE::GLOBAL::warn = \&Apache2::ServerRec::warn; } + +# Pre-compile the CGI.pm methods that we're going to use. +Bugzilla::CGI->compile(qw(:cgi :push)); + +use Apache2::SizeLimit; +# This means that every httpd child will die after processing +# a CGI if it is taking up more than 45MB of RAM all by itself, +# not counting RAM it is sharing with the other httpd processes. +Apache2::SizeLimit->set_max_unshared_size(45_000); + +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; +# Make sure each httpd child receives a different random seed (bug 476622). +# Bugzilla::RNG has one srand that needs to be called for +# every process, and Perl has another. (Various Perl modules still use +# the built-in rand(), even though we never use it in Bugzilla itself, +# so we need to srand() both of them.) +PerlChildInitHandler "sub { Bugzilla::RNG::srand(); srand(); }" +<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 Apache2::SizeLimit Bugzilla::ModPerl::CleanupHandler + PerlOptions +ParseHeaders + Options +ExecCGI + AllowOverride Limit FileInfo Indexes Options + DirectoryIndex index.cgi index.html +</Directory> +EOT + +$server->add_config([split("\n", $conf)]); + +# Pre-load all extensions +$Bugzilla::extension_packages = Bugzilla::Extension->load_all(); + +# Have ModPerl::RegistryLoader pre-compile all CGI scripts. +my $rl = new ModPerl::RegistryLoader(); +# If we try to do this in "new" it fails because it looks for a +# Bugzilla/ModPerl/ResponseHandler.pm +$rl->{package} = 'Bugzilla::ModPerl::ResponseHandler'; +my $feature_files = Bugzilla::Install::Requirements::map_files_to_features(); + +# Prevent "use lib" from doing anything when the .cgi files are compiled. +# This is important to prevent the current directory from getting into +# @INC and messing things up. (See bug 630750.) +no warnings 'redefine'; +local *lib::import = sub {}; +use warnings; + +foreach my $file (glob "$cgi_path/*.cgi") { + my $base_filename = File::Basename::basename($file); + if (my $feature = $feature_files->{$base_filename}) { + next if !Bugzilla->feature($feature); + } + 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'}; + + # Prevent "use lib" from modifying @INC in the case where a .cgi file + # is being automatically recompiled by mod_perl when Apache is + # running. (This happens if a file changes while Apache is already + # running.) + no warnings 'redefine'; + local *lib::import = sub {}; + use warnings; + + Bugzilla::init_page(); + return $class->SUPER::handler(@_); +} + + +package Bugzilla::ModPerl::CleanupHandler; +use strict; +use Apache2::Const -compile => qw(OK); + +sub handler { + my $r = shift; + + Bugzilla::_cleanup(); + # 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; |