summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/CGI.pm18
-rw-r--r--Bugzilla/Constants.pm5
-rw-r--r--Bugzilla/DB.pm9
-rw-r--r--Bugzilla/Error.pm10
-rw-r--r--Bugzilla/Install/Localconfig.pm8
-rw-r--r--Bugzilla/JobQueue.pm4
-rw-r--r--Bugzilla/JobQueue/Runner.pm10
-rw-r--r--Bugzilla/Mailer.pm9
-rw-r--r--Bugzilla/Memcached.pm26
-rw-r--r--Bugzilla/ModPerl.pm8
-rw-r--r--Bugzilla/ModPerl/BasicAuth.pm13
-rw-r--r--Bugzilla/ModPerl/Hostage.pm71
-rw-r--r--Bugzilla/WebService/Server/REST.pm3
13 files changed, 150 insertions, 44 deletions
diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
index cd947841e..b0bc15e78 100644
--- a/Bugzilla/CGI.pm
+++ b/Bugzilla/CGI.pm
@@ -600,16 +600,18 @@ sub param {
# We don't let CGI.pm warn about list context, but we do it ourselves.
local $CGI::LIST_CONTEXT_WARN = 0;
- state $has_warned = {};
-
- ## no critic (Freenode::Wantarray)
- if ( wantarray && @_ ) {
- my ( $package, $filename, $line ) = caller;
- if ( $package ne 'CGI' && ! $has_warned->{"$filename:$line"}++) {
- WARN("Bugzilla::CGI::param called in list context from $package $filename:$line");
+ if (0) {
+ state $has_warned = {};
+
+ ## no critic (Freenode::Wantarray)
+ if ( wantarray && @_ ) {
+ my ( $package, $filename, $line ) = caller;
+ if ( $package ne 'CGI' && ! $has_warned->{"$filename:$line"}++) {
+ WARN("Bugzilla::CGI::param called in list context from $package $filename:$line");
+ }
}
+ ## use critic
}
- ## use critic
# When we are just requesting the value of a parameter...
if (scalar(@_) == 1) {
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 00f0f8104..6e3a12736 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -19,7 +19,6 @@ use Memoize;
@Bugzilla::Constants::EXPORT = qw(
BUGZILLA_VERSION
- REST_DOC
REMOTE_FILE
LOCAL_FILE
@@ -209,10 +208,6 @@ sub BUGZILLA_VERSION {
eval { Bugzilla->VERSION } || $bugzilla_version;
}
-# A base link to the current REST Documentation. We place it here
-# as it will need to be updated to whatever the current release is.
-use constant REST_DOC => "https://bugzilla.readthedocs.io/en/latest/api/";
-
# Location of the remote and local XML files to track new releases.
use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml';
use constant LOCAL_FILE => 'bugzilla-update.xml'; # Relative to datadir.
diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm
index ff75aa2cf..0dfa47c23 100644
--- a/Bugzilla/DB.pm
+++ b/Bugzilla/DB.pm
@@ -111,8 +111,13 @@ sub connect_shadow {
my $connect_params = dclone(Bugzilla->localconfig);
$connect_params->{db_host} = Bugzilla->get_param_with_override('shadowdbhost');
$connect_params->{db_name} = Bugzilla->get_param_with_override('shadowdb');
- $connect_params->{db_port} = Bugzilla->get_param_with_override('shadowport');
- $connect_params->{db_sock} = Bugzilla->get_param_with_override('shadowsock');
+ $connect_params->{db_port} = Bugzilla->get_param_with_override('shadowdbport');
+ $connect_params->{db_sock} = Bugzilla->get_param_with_override('shadowdbsock');
+
+ if ( Bugzilla->localconfig->{'shadowdb_user'} && Bugzilla->localconfig->{'shadowdb_pass'} ) {
+ $connect_params->{db_user} = Bugzilla->localconfig->{'shadowdb_user'};
+ $connect_params->{db_pass} = Bugzilla->localconfig->{'shadowdb_pass'};
+ }
return _connect($connect_params);
}
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm
index e7a99dba0..d67571848 100644
--- a/Bugzilla/Error.pm
+++ b/Bugzilla/Error.pm
@@ -38,15 +38,14 @@ sub _in_eval {
sub _throw_error {
my ($name, $error, $vars) = @_;
- my $dbh = Bugzilla->dbh;
$vars ||= {};
-
$vars->{error} = $error;
# Make sure any transaction is rolled back (if supported).
# If we are within an eval(), do not roll back transactions as we are
# eval'uating some test on purpose.
- $dbh->bz_rollback_transaction() if ($dbh->bz_in_transaction() && !_in_eval());
+ my $dbh = eval { Bugzilla->dbh };
+ $dbh->bz_rollback_transaction() if ($dbh && $dbh->bz_in_transaction() && !_in_eval());
my $datadir = bz_locations()->{'datadir'};
# If a writable $datadir/errorlog exists, log error details there.
@@ -191,10 +190,9 @@ sub ThrowCodeError {
sub ThrowTemplateError {
my ($template_err) = @_;
- my $dbh = Bugzilla->dbh;
-
+ my $dbh = eval { Bugzilla->dbh };
# Make sure the transaction is rolled back (if supported).
- $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction();
+ $dbh->bz_rollback_transaction() if $dbh && $dbh->bz_in_transaction();
if (blessed($template_err) && $template_err->isa('Template::Exception')) {
my $type = $template_err->type;
diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm
index de2219f16..7a913358c 100644
--- a/Bugzilla/Install/Localconfig.pm
+++ b/Bugzilla/Install/Localconfig.pm
@@ -175,6 +175,14 @@ use constant LOCALCONFIG_VARS => (
name => 'inbound_proxies',
default => _migrate_param( 'inbound_proxies', '' ),
},
+ {
+ name => 'shadowdb_user',
+ default => '',
+ },
+ {
+ name => 'shadowdb_pass',
+ default => '',
+ }
);
diff --git a/Bugzilla/JobQueue.pm b/Bugzilla/JobQueue.pm
index 8c8d73dcd..53b088c6e 100644
--- a/Bugzilla/JobQueue.pm
+++ b/Bugzilla/JobQueue.pm
@@ -101,12 +101,12 @@ sub debug {
my $caller_pkg = caller;
local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1;
my $logger = Log::Log4perl->get_logger($caller_pkg);
- $logger->debug(@args);
+ $logger->info(@args);
}
sub work {
my ($self, $delay) = @_;
- $delay ||= 5;
+ $delay ||= 1;
my $loop = IO::Async::Loop->new;
my $timer = IO::Async::Timer::Periodic->new(
first_interval => 0,
diff --git a/Bugzilla/JobQueue/Runner.pm b/Bugzilla/JobQueue/Runner.pm
index 1c74bc28f..0177de40a 100644
--- a/Bugzilla/JobQueue/Runner.pm
+++ b/Bugzilla/JobQueue/Runner.pm
@@ -26,7 +26,7 @@ use Cwd qw(abs_path);
use English qw(-no_match_vars $PROGRAM_NAME $EXECUTABLE_NAME);
use File::Basename;
use File::Copy;
-use File::Spec::Functions qw(catfile);
+use File::Spec::Functions qw(catfile tmpdir);
use Future;
use Future::Utils qw(fmap_void);
use IO::Async::Loop;
@@ -52,7 +52,7 @@ sub gd_preconfig {
my $pidfile = $self->{gd_args}{pidfile};
if ( !$pidfile ) {
- $pidfile = bz_locations()->{datadir} . '/' . $self->{gd_progname} . '.pid';
+ $pidfile = catfile(tmpdir(), $self->{gd_progname} . '.pid');
}
return ( pidfile => $pidfile );
}
@@ -211,7 +211,7 @@ sub gd_run {
my $self = shift;
my $jobs = $self->{gd_args}{jobs} // 1;
my $signal_f = $self->{_signal_future};
- my $workers_f = fmap_void { $self->run_worker("work") }
+ my $workers_f = fmap_void { $self->run_worker() }
concurrent => $jobs,
generate => sub { !$signal_f->is_ready };
@@ -225,10 +225,10 @@ sub gd_run {
# This executes the script "jobqueue-worker.pl"
# $EXECUTABLE_NAME is the name of the perl interpreter.
sub run_worker {
- my ( $self, $fn ) = @_;
+ my ( $self ) = @_;
my $script = catfile( bz_locations->{cgi_path}, 'jobqueue-worker.pl' );
- my @command = ( $EXECUTABLE_NAME, $script, '--function' => $fn );
+ my @command = ( $EXECUTABLE_NAME, $script);
if ( $self->{gd_args}{progname} ) {
push @command, '--name' => "$self->{gd_args}{progname} [worker]";
}
diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm
index e245a05e0..1dec3d4ff 100644
--- a/Bugzilla/Mailer.pm
+++ b/Bugzilla/Mailer.pm
@@ -252,15 +252,14 @@ sub build_thread_marker {
$sitespec = "-$2$sitespec"; # Put the port number back in, before the '@'
}
- my $threadingmarker;
+ my $threadingmarker = "References: <bug-$bug_id-$user_id$sitespec>";
if ($is_new) {
- $threadingmarker = "Message-ID: <bug-$bug_id-$user_id$sitespec>";
+ $threadingmarker .= "\nMessage-ID: <bug-$bug_id-$user_id$sitespec>";
}
else {
my $rand_bits = generate_random_password(10);
- $threadingmarker = "Message-ID: <bug-$bug_id-$user_id-$rand_bits$sitespec>" .
- "\nIn-Reply-To: <bug-$bug_id-$user_id$sitespec>" .
- "\nReferences: <bug-$bug_id-$user_id$sitespec>";
+ $threadingmarker .= "\nMessage-ID: <bug-$bug_id-$user_id-$rand_bits$sitespec>" .
+ "\nIn-Reply-To: <bug-$bug_id-$user_id$sitespec>";
}
return $threadingmarker;
diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm
index 85e3505e1..d34aaa595 100644
--- a/Bugzilla/Memcached.pm
+++ b/Bugzilla/Memcached.pm
@@ -36,11 +36,25 @@ sub _new {
if (Bugzilla->feature('memcached') && $servers) {
$self->{namespace} = Bugzilla->localconfig->{memcached_namespace};
TRACE("connecting servers: $servers, namespace: $self->{namespace}");
- $self->{memcached} = Cache::Memcached::Fast->new({
- servers => [ _parse_memcached_server_list($servers) ],
- namespace => $self->{namespace},
- max_size => 1024 * 1024 * 4,
- });
+ $self->{memcached} = Cache::Memcached::Fast->new(
+ {
+ servers => [ _parse_memcached_server_list($servers) ],
+ namespace => $self->{namespace},
+ max_size => 1024 * 1024 * 4,
+ max_failures => 1,
+ failure_timeout => 60,
+ io_timeout => 0.2,
+ connect_timeout => 0.2,
+ }
+ );
+ my $versions = $self->{memcached}->server_versions;
+ if (keys %$versions) {
+ # this is needed to ensure forked processes don't start out with a connected memcached socket.
+ $self->{memcached}->disconnect_all;
+ }
+ else {
+ WARN("No memcached servers");
+ }
}
else {
TRACE("memcached feature is not enabled");
@@ -324,7 +338,7 @@ sub _get {
my $enc_key = $self->_encode_key($key)
or return;
- my $val = $self->{memcached}->get($key);
+ my $val = $self->{memcached}->get($enc_key);
TRACE("get $enc_key: " . (defined $val ? "HIT" : "MISS"));
return $val;
}
diff --git a/Bugzilla/ModPerl.pm b/Bugzilla/ModPerl.pm
index a5c840897..120dd8210 100644
--- a/Bugzilla/ModPerl.pm
+++ b/Bugzilla/ModPerl.pm
@@ -20,6 +20,7 @@ use Carp ();
use Template ();
use Bugzilla::ModPerl::BlockIP;
+use Bugzilla::ModPerl::Hostage;
sub apache_config {
my ($class, $cgi_path) = @_;
@@ -74,6 +75,7 @@ __DATA__
# 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(); }"
+PerlInitHandler Bugzilla::ModPerl::Hostage
PerlAccessHandler Bugzilla::ModPerl::BlockIP
# It is important to specify ErrorDocuments outside of all directories.
@@ -84,6 +86,12 @@ ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
+<Location /helper>
+ SetHandler perl-script
+ PerlResponseHandler Plack::Handler::Apache2
+ PerlSetVar psgi_app [% cgi_path %]/helper.psgi
+</Location>
+
<Directory "[% cgi_path %]">
AddHandler perl-script .cgi
# No need to PerlModule these because they're already defined in mod_perl.pl
diff --git a/Bugzilla/ModPerl/BasicAuth.pm b/Bugzilla/ModPerl/BasicAuth.pm
index e93680e9d..7248a19f3 100644
--- a/Bugzilla/ModPerl/BasicAuth.pm
+++ b/Bugzilla/ModPerl/BasicAuth.pm
@@ -25,18 +25,22 @@ use warnings;
# AUTH_VAR_NAME and AUTH_VAR_PASS are the names of variables defined in
# `localconfig` which hold the authentication credentials.
-use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED);
+use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED); ## no critic (Freenode::ModPerl)
+use Bugzilla::Logging;
use Bugzilla ();
sub handler {
my $r = shift;
my ($status, $password) = $r->get_basic_auth_pw;
- return $status if $status != Apache2::Const::OK;
+ if ($status != Apache2::Const::OK) {
+ WARN("Got non-OK status: $status when trying to get password");
+ return $status
+ }
my $auth_var_name = $ENV{AUTH_VAR_NAME};
my $auth_var_pass = $ENV{AUTH_VAR_PASS};
unless ($auth_var_name && $auth_var_pass) {
- warn "AUTH_VAR_NAME and AUTH_VAR_PASS environmental vars not set\n";
+ ERROR('AUTH_VAR_NAME and AUTH_VAR_PASS environmental vars not set');
$r->note_basic_auth_failure;
return Apache2::Const::HTTP_UNAUTHORIZED;
}
@@ -44,13 +48,14 @@ sub handler {
my $auth_user = Bugzilla->localconfig->{$auth_var_name};
my $auth_pass = Bugzilla->localconfig->{$auth_var_pass};
unless ($auth_user && $auth_pass) {
- warn "$auth_var_name and $auth_var_pass not configured\n";
+ ERROR("$auth_var_name and $auth_var_pass not configured");
$r->note_basic_auth_failure;
return Apache2::Const::HTTP_UNAUTHORIZED;
}
unless ($r->user eq $auth_user && $password eq $auth_pass) {
$r->note_basic_auth_failure;
+ WARN('username and password do not match');
return Apache2::Const::HTTP_UNAUTHORIZED;
}
diff --git a/Bugzilla/ModPerl/Hostage.pm b/Bugzilla/ModPerl/Hostage.pm
new file mode 100644
index 000000000..a3bdfac58
--- /dev/null
+++ b/Bugzilla/ModPerl/Hostage.pm
@@ -0,0 +1,71 @@
+package Bugzilla::ModPerl::Hostage;
+use 5.10.1;
+use strict;
+use warnings;
+
+use Apache2::Const qw(:common); ## no critic (Freenode::ModPerl)
+
+sub _attachment_root {
+ my ($base) = @_;
+ return undef unless $base;
+ return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)}
+ ? $1
+ : undef;
+}
+
+sub _attachment_host_regex {
+ my ($base) = @_;
+ return undef unless $base;
+ my $val = $base;
+ $val =~ s{^https?://}{}s;
+ $val =~ s{/$}{}s;
+ my $regex = quotemeta $val;
+ $regex =~ s/\\\%bugid\\\%/\\d+/g;
+ return qr/^$regex$/s;
+}
+
+sub handler {
+ my $r = shift;
+ state $urlbase = Bugzilla->localconfig->{urlbase};
+ state $urlbase_uri = URI->new($urlbase);
+ state $urlbase_host = $urlbase_uri->host;
+ state $urlbase_host_regex = qr/^bug(\d+)\.\Q$urlbase_host\E$/;
+ state $attachment_base = Bugzilla->localconfig->{attachment_base};
+ state $attachment_root = _attachment_root($attachment_base);
+ state $attachment_host_regex = _attachment_host_regex($attachment_base);
+
+ my $hostname = $r->hostname;
+ return OK if $hostname eq $urlbase_host;
+
+ my $path = $r->uri;
+ return OK if $path eq '/__lbheartbeat__';
+
+ if ($attachment_base && $hostname eq $attachment_root) {
+ $r->headers_out->set(Location => $urlbase);
+ return REDIRECT;
+ }
+ elsif ($attachment_base && $hostname =~ $attachment_host_regex) {
+ if ($path =~ m{^/attachment\.cgi}s) {
+ return OK;
+ } else {
+ my $new_uri = URI->new($r->unparsed_uri);
+ $new_uri->scheme($urlbase_uri->scheme);
+ $new_uri->host($urlbase_host);
+ $r->headers_out->set(Location => $new_uri);
+ return REDIRECT;
+ }
+ }
+ elsif (my ($id) = $hostname =~ $urlbase_host_regex) {
+ my $new_uri = $urlbase_uri->clone;
+ $new_uri->path('/show_bug.cgi');
+ $new_uri->query_form(id => $id);
+ $r->headers_out->set(Location => $new_uri);
+ return REDIRECT;
+ }
+ else {
+ $r->headers_out->set(Location => $urlbase);
+ return REDIRECT;
+ }
+}
+
+1; \ No newline at end of file
diff --git a/Bugzilla/WebService/Server/REST.pm b/Bugzilla/WebService/Server/REST.pm
index 6fb86fdd4..b8884b753 100644
--- a/Bugzilla/WebService/Server/REST.pm
+++ b/Bugzilla/WebService/Server/REST.pm
@@ -132,7 +132,8 @@ sub response {
if (exists $json_data->{error}) {
$result = $json_data->{error};
$result->{error} = $self->type('boolean', 1);
- $result->{documentation} = REST_DOC;
+
+ $result->{documentation} = Bugzilla->params->{docs_urlbase} . "api/";
delete $result->{'name'}; # Remove JSONRPCError
}
elsif (exists $json_data->{result}) {