diff options
-rw-r--r-- | Bugzilla.pm | 20 | ||||
-rw-r--r-- | Bugzilla/CGI.pm | 4 | ||||
-rw-r--r-- | Bugzilla/Constants.pm | 4 | ||||
-rw-r--r-- | Bugzilla/PSGI.pm | 36 | ||||
-rw-r--r-- | Bugzilla/Template.pm | 4 | ||||
-rwxr-xr-x | Makefile.PL | 7 | ||||
-rw-r--r-- | app.psgi | 114 | ||||
-rw-r--r-- | extensions/BzAPI/Extension.pm | 9 | ||||
-rw-r--r-- | extensions/Push/lib/Logger.pm | 2 | ||||
-rwxr-xr-x | heartbeat.cgi | 2 | ||||
-rw-r--r-- | mod_perl.pl | 3 |
11 files changed, 183 insertions, 22 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm index 4a3dcb114..f2191f33b 100644 --- a/Bugzilla.pm +++ b/Bugzilla.pm @@ -117,20 +117,6 @@ sub init_page { # 001compile.t test). return if $^C; - # IIS prints out warnings to the webpage, so ignore them, or log them - # to a file if the file exists. - if ($ENV{SERVER_SOFTWARE} && $ENV{SERVER_SOFTWARE} =~ /microsoft-iis/i) { - $SIG{__WARN__} = sub { - my ($msg) = @_; - my $datadir = bz_locations()->{'datadir'}; - if (-w "$datadir/errorlog") { - my $warning_log = new IO::File(">>$datadir/errorlog"); - print $warning_log $msg; - $warning_log->close(); - } - }; - } - my $script = basename($0); # BMO - init metrics collection if required @@ -369,7 +355,7 @@ sub login { return $class->user if $class->user->id; # Load all extensions here if not running under mod_perl - $class->extensions unless $ENV{MOD_PERL}; + $class->extensions unless BZ_PERSISTENT; my $authorizer = new Bugzilla::Auth(); $type = LOGIN_REQUIRED if $class->cgi->param('GoAheadAndLogIn'); @@ -902,10 +888,10 @@ sub _cleanup { sub END { # Bugzilla.pm cannot compile in mod_perl.pl if this runs. - _cleanup() unless $ENV{MOD_PERL}; + _cleanup() unless BZ_PERSISTENT; } -init_page() if !$ENV{MOD_PERL}; +init_page() unless BZ_PERSISTENT; 1; diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index 3737b97e2..05e2bd749 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -113,7 +113,7 @@ sub new { # Under mod_perl, CGI's global variables get reset on each request, # so we need to set them up again every time. - $class->_init_bz_cgi_globals() if $ENV{MOD_PERL}; + $class->_init_bz_cgi_globals() if BZ_PERSISTENT; my $self = $class->SUPER::new(@args); @@ -597,6 +597,8 @@ sub header { sub param { my $self = shift; + local $CGI::LIST_CONTEXT_WARN = 0; + # When we are just requesting the value of a parameter... if (scalar(@_) == 1) { my @result = $self->SUPER::param(@_); diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 00f0f8104..2971c7a53 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -194,6 +194,8 @@ use Memoize; EMAIL_LIMIT_EXCEPTION JOB_QUEUE_VIEW_MAX_JOBS + + BZ_PERSISTENT ); @Bugzilla::Constants::EXPORT_OK = qw(contenttypes); @@ -705,6 +707,8 @@ sub _bz_locations { }; } +use constant BZ_PERSISTENT => $main::BUGZILLA_PERSISTENT; + # This makes us not re-compute all the bz_locations data every time it's # called. BEGIN { memoize('_bz_locations') }; diff --git a/Bugzilla/PSGI.pm b/Bugzilla/PSGI.pm new file mode 100644 index 000000000..22e08540d --- /dev/null +++ b/Bugzilla/PSGI.pm @@ -0,0 +1,36 @@ +# 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::PSGI; +use 5.10.1; +use strict; +use warnings; + +use base qw(Exporter); + +our @EXPORT_OK = qw(compile_cgi); + +sub compile_cgi { + my ($script) = @_; + my $app = Plack::App::WrapCGI->new( script => $script )->to_app; + + return sub { + my ($env) = @_; + Bugzilla::init_page(); + if ($env->{'psgix.cleanup'}) { + push @{ $env->{'psgix.cleanup.handler'} }, \&Bugzilla::_cleanup; + } + + my $res = $app->($env); + Bugzilla::_cleanup() if not $env->{'psgix.cleanup'}; + return $res; + }; +} + + + +1;
\ No newline at end of file diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index d27896532..0d2a4cd86 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -570,7 +570,7 @@ sub create { # if a packager has modified bz_locations() to contain absolute # paths. ABSOLUTE => 1, - RELATIVE => $ENV{MOD_PERL} ? 0 : 1, + RELATIVE => 0, COMPILE_DIR => bz_locations()->{'template_cache'}, @@ -1037,7 +1037,7 @@ sub create { # under mod_perl, use a provider (template loader) that preloads all templates into memory my $provider_class - = $ENV{MOD_PERL} + = BZ_PERSISTENT ? 'Bugzilla::Template::PreloadProvider' : 'Template::Provider'; diff --git a/Makefile.PL b/Makefile.PL index 34e4e2487..97caea271 100755 --- a/Makefile.PL +++ b/Makefile.PL @@ -34,6 +34,8 @@ BEGIN { my %requires = ( 'Algorithm::BloomFilter' => '0.02', 'CGI' => '3.51', + 'CGI::Compile' => 0, + 'CGI::Emulate::PSGI' => 0, 'CPAN::Meta::Prereqs' => '2.132830', 'CPAN::Meta::Requirements' => '2.121', 'Class::XSAccessor' => '1.18', @@ -51,11 +53,14 @@ my %requires = ( 'HTML::Escape' => '1.10', 'IO::Async' => '0.71', 'JSON::MaybeXS' => '1.003008', + 'JSON::MaybeXS' => '1.003008', 'JSON::XS' => '2.01', 'LWP::Protocol::https' => '6.07', 'LWP::UserAgent' => '6.26', 'List::MoreUtils' => '0.418', 'Log::Dispatch' => '2.67', + 'Log::Dispatch' => '2.67', + 'Log::Log4perl' => '1.49', 'Log::Log4perl' => '1.49', 'Math::Random::ISAAC' => '1.0.1', 'Module::Metadata' => '1.000033', @@ -64,8 +69,10 @@ my %requires = ( 'MooX::StrictConstructor' => '0.008', 'Mozilla::CA' => '20160104', 'Parse::CPAN::Meta' => '1.44', + 'Plack' => '1.0031', 'Role::Tiny' => '2.000003', 'Sereal' => '4.004', + 'Sereal' => '4.004', 'Taint::Util' => '0.08', 'Template' => '2.24', 'Text::CSV_XS' => '1.26', diff --git a/app.psgi b/app.psgi new file mode 100644 index 000000000..f3ce2fb64 --- /dev/null +++ b/app.psgi @@ -0,0 +1,114 @@ +#!/usr/bin/perl +# 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. + +use 5.10.1; +use strict; +use warnings; + +BEGIN { $main::BUGZILLA_PERSISTENT = 1 } + +use File::Basename; +use File::Spec; + +BEGIN { + require lib; + my $dir = File::Spec->rel2abs( dirname(__FILE__) ); + lib->import( + $dir, + File::Spec->catdir( $dir, 'lib' ), + File::Spec->catdir( $dir, qw(local lib perl5) ) + ); + + # disable "use lib" from now on + no warnings qw(redefine); + *lib::import = sub { }; +} + +# This loads most of our modules. +use Bugzilla::Logging; +use Bugzilla (); +use Bugzilla::Constants (); +use Bugzilla::BugMail (); +use Bugzilla::CGI (); +use Bugzilla::PSGI qw(compile_cgi); +use Bugzilla::Extension (); +use Bugzilla::Install::Requirements (); +use Bugzilla::Util (); +use Bugzilla::RNG (); + +use Plack; +use Plack::Builder; +use Plack::App::URLMap; +use Plack::App::WrapCGI; +use Plack::Response; + +use constant STATIC => qw( + data/webdot + docs + extensions/[^/]+/web + graphs + images + js + skins +); + +# Pre-load all extensions +Bugzilla::Extension->load_all(); +Bugzilla->preload_features(); + +# Force instantiation of template so Bugzilla::Template::PreloadProvider can do its magic. +Bugzilla->template; + +my $bugzilla_app = builder { + my $static_paths = join( '|', STATIC ); + + enable 'Log4perl', category => 'Plack'; + + enable 'Static', + path => sub { s{^/(?:static/v\d+\.\d+/)?($static_paths)/}{$1/}gs }, + root => Bugzilla::Constants::bz_locations->{cgi_path}; + + my @scripts = glob('*.cgi'); + + my %mount; + + foreach my $script (@scripts) { + my $name = basename($script); + $mount{$name} = compile_cgi($script); + } + + Bugzilla::Hook::process('psgi_builder', { mount => \%mount }); + + foreach my $name ( keys %mount ) { + mount "/$name" => $mount{$name}; + } + + # so mount / => $app will make *all* files redirect to the index. + # instead we use an inline middleware to rewrite / to /index.cgi + enable sub { + my $app = shift; + return sub { + my $env = shift; + $env->{PATH_INFO} = '/index.cgi' if $env->{PATH_INFO} eq '/'; + return $app->($env); + }; + }; + + mount '/rest' => $mount{'rest.cgi'}; + +}; + +unless (caller) { + require Plack::Runner; + my $runner = Plack::Runner->new; + $runner->parse_options(@ARGV); + $runner->run($bugzilla_app); + exit 0; +} + +return $bugzilla_app; diff --git a/extensions/BzAPI/Extension.pm b/extensions/BzAPI/Extension.pm index bb9805134..1f7cce04a 100644 --- a/extensions/BzAPI/Extension.pm +++ b/extensions/BzAPI/Extension.pm @@ -15,6 +15,7 @@ use base qw(Bugzilla::Extension); use Bugzilla::Extension::BzAPI::Constants; use Bugzilla::Extension::BzAPI::Util qw(fix_credentials filter_wants_nocache); +use Bugzilla::PSGI qw(compile_cgi); use Bugzilla::Error; use Bugzilla::Util qw(trick_taint datetime_from); @@ -188,6 +189,14 @@ sub webservice_status_code_map { $status_code_map->{51} = STATUS_BAD_REQUEST; } +sub psgi_builder { + my ($self, $args) = @_; + my $mount = $args->{mount}; + + $mount->{'bzapi'} = compile_cgi('extensions/BzAPI/bin/rest.cgi'); +} + + ##################### # Utility Functions # ##################### diff --git a/extensions/Push/lib/Logger.pm b/extensions/Push/lib/Logger.pm index 833cb3b19..7ae96b58a 100644 --- a/extensions/Push/lib/Logger.pm +++ b/extensions/Push/lib/Logger.pm @@ -31,11 +31,11 @@ sub debugging { } sub _log_it { - require Apache2::Log; my ($self, $method, $message) = @_; return if $method eq 'DEBUG' && !$self->debugging; chomp $message; if ($ENV{MOD_PERL}) { + require Apache2::Log; Apache2::ServerRec::warn("Push $method: $message"); } elsif ($ENV{SCRIPT_FILENAME}) { print STDERR "Push $method: $message\n"; diff --git a/heartbeat.cgi b/heartbeat.cgi index 40dc8e79b..917853d2b 100755 --- a/heartbeat.cgi +++ b/heartbeat.cgi @@ -28,7 +28,7 @@ my $ok = eval { die "database not available" unless $database_ok; die "memcached server(s) not available" unless $memcached_ok; - die "mod_perl not configured?" unless $ENV{MOD_PERL}; + die "mod_perl/psgi not configured?" unless BZ_PERSISTENT; die "missing bmo feature dependencies" unless Bugzilla->has_feature('bmo'); 1; }; diff --git a/mod_perl.pl b/mod_perl.pl index 09fd80850..af60bb359 100644 --- a/mod_perl.pl +++ b/mod_perl.pl @@ -6,12 +6,15 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. + package Bugzilla::ModPerl; use 5.10.1; use strict; use warnings; +BEGIN { $main::BUGZILLA_PERSISTENT = 1 } + # This sets up our libpath without having to specify it in the mod_perl # configuration. use File::Basename; |