summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla.pm20
-rw-r--r--Bugzilla/CGI.pm4
-rw-r--r--Bugzilla/Constants.pm4
-rw-r--r--Bugzilla/PSGI.pm36
-rw-r--r--Bugzilla/Template.pm4
-rwxr-xr-xMakefile.PL7
-rw-r--r--app.psgi114
-rw-r--r--extensions/BzAPI/Extension.pm9
-rw-r--r--extensions/Push/lib/Logger.pm2
-rwxr-xr-xheartbeat.cgi2
-rw-r--r--mod_perl.pl3
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;