summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Quantum
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Quantum')
-rw-r--r--Bugzilla/Quantum/CGI.pm27
-rw-r--r--Bugzilla/Quantum/Home.pm3
-rw-r--r--Bugzilla/Quantum/Plugin/BasicAuth.pm40
-rw-r--r--Bugzilla/Quantum/Plugin/Glue.pm3
-rw-r--r--Bugzilla/Quantum/Plugin/Hostage.pm107
-rw-r--r--Bugzilla/Quantum/SES.pm364
6 files changed, 267 insertions, 277 deletions
diff --git a/Bugzilla/Quantum/CGI.pm b/Bugzilla/Quantum/CGI.pm
index 79fbcfde6..5a654111e 100644
--- a/Bugzilla/Quantum/CGI.pm
+++ b/Bugzilla/Quantum/CGI.pm
@@ -54,8 +54,7 @@ sub load_one {
open STDIN, '<', $stdin->path
or die "STDIN @{[$stdin->path]}: $!"
if -s $stdin->path;
- tie *STDOUT, 'Bugzilla::Quantum::Stdout',
- controller => $c; ## no critic (tie)
+ tie *STDOUT, 'Bugzilla::Quantum::Stdout', controller => $c; ## no critic (tie)
# the finally block calls cleanup.
$c->stash->{cleanup_guard}->dismiss;
@@ -129,19 +128,17 @@ sub _ENV {
GATEWAY_INTERFACE => 'CGI/1.1',
HTTPS => $req->is_secure ? 'on' : 'off',
%env_headers,
- QUERY_STRING => $cgi_query->to_string,
- PATH_INFO => $path_info ? "/$path_info" : '',
- REMOTE_ADDR => $tx->original_remote_address,
- REMOTE_HOST => $tx->original_remote_address,
- REMOTE_PORT => $tx->remote_port,
- REMOTE_USER => $remote_user || '',
- REQUEST_METHOD => $req->method,
- SCRIPT_NAME => "$prefix$script_name",
- SERVER_NAME => hostname,
- SERVER_PORT => $tx->local_port,
- SERVER_PROTOCOL => $req->is_secure
- ? 'HTTPS'
- : 'HTTP', # TODO: Version is missing
+ QUERY_STRING => $cgi_query->to_string,
+ PATH_INFO => $path_info ? "/$path_info" : '',
+ REMOTE_ADDR => $tx->original_remote_address,
+ REMOTE_HOST => $tx->original_remote_address,
+ REMOTE_PORT => $tx->remote_port,
+ REMOTE_USER => $remote_user || '',
+ REQUEST_METHOD => $req->method,
+ SCRIPT_NAME => "$prefix$script_name",
+ SERVER_NAME => hostname,
+ SERVER_PORT => $tx->local_port,
+ SERVER_PROTOCOL => $req->is_secure ? 'HTTPS' : 'HTTP', # TODO: Version is missing
SERVER_SOFTWARE => __PACKAGE__,
);
}
diff --git a/Bugzilla/Quantum/Home.pm b/Bugzilla/Quantum/Home.pm
index 48d5e47bd..6a3021f64 100644
--- a/Bugzilla/Quantum/Home.pm
+++ b/Bugzilla/Quantum/Home.pm
@@ -16,8 +16,7 @@ sub index {
my ($c) = @_;
$c->bugzilla->login(LOGIN_REQUIRED) or return;
try {
- ThrowUserError('invalid_username', {login => 'batman'})
- if $c->param('error');
+ ThrowUserError('invalid_username', {login => 'batman'}) if $c->param('error');
$c->render(handler => 'bugzilla', template => 'index');
}
catch {
diff --git a/Bugzilla/Quantum/Plugin/BasicAuth.pm b/Bugzilla/Quantum/Plugin/BasicAuth.pm
index e17273404..e0d4e8ecc 100644
--- a/Bugzilla/Quantum/Plugin/BasicAuth.pm
+++ b/Bugzilla/Quantum/Plugin/BasicAuth.pm
@@ -12,29 +12,29 @@ use Bugzilla::Logging;
use Carp;
sub register {
- my ( $self, $app, $conf ) = @_;
+ my ($self, $app, $conf) = @_;
- $app->renderer->add_helper(
- basic_auth => sub {
- my ( $c, $realm, $auth_user, $auth_pass ) = @_;
- my $req = $c->req;
- my ( $user, $password ) = $req->url->to_abs->userinfo =~ /^([^:]+):(.*)/;
+ $app->renderer->add_helper(
+ basic_auth => sub {
+ my ($c, $realm, $auth_user, $auth_pass) = @_;
+ my $req = $c->req;
+ my ($user, $password) = $req->url->to_abs->userinfo =~ /^([^:]+):(.*)/;
- unless ( $realm && $auth_user && $auth_pass ) {
- croak 'basic_auth() called with missing parameters.';
- }
+ unless ($realm && $auth_user && $auth_pass) {
+ croak 'basic_auth() called with missing parameters.';
+ }
- unless ( $user eq $auth_user && $password eq $auth_pass ) {
- WARN('username and password do not match');
- $c->res->headers->www_authenticate("Basic realm=\"$realm\"");
- $c->res->code(401);
- $c->rendered;
- return 0;
- }
+ unless ($user eq $auth_user && $password eq $auth_pass) {
+ WARN('username and password do not match');
+ $c->res->headers->www_authenticate("Basic realm=\"$realm\"");
+ $c->res->code(401);
+ $c->rendered;
+ return 0;
+ }
- return 1;
- }
- );
+ return 1;
+ }
+ );
}
-1; \ No newline at end of file
+1;
diff --git a/Bugzilla/Quantum/Plugin/Glue.pm b/Bugzilla/Quantum/Plugin/Glue.pm
index f04b9c025..de016356c 100644
--- a/Bugzilla/Quantum/Plugin/Glue.pm
+++ b/Bugzilla/Quantum/Plugin/Glue.pm
@@ -157,8 +157,7 @@ sub register {
);
$app->log(MojoX::Log::Log4perl::Tiny->new(
- logger => Log::Log4perl->get_logger(ref $app)
- ));
+ logger => Log::Log4perl->get_logger(ref $app)));
}
1;
diff --git a/Bugzilla/Quantum/Plugin/Hostage.pm b/Bugzilla/Quantum/Plugin/Hostage.pm
index 418b09a0c..df3e40ec1 100644
--- a/Bugzilla/Quantum/Plugin/Hostage.pm
+++ b/Bugzilla/Quantum/Plugin/Hostage.pm
@@ -3,78 +3,77 @@ use 5.10.1;
use Mojo::Base 'Mojolicious::Plugin';
sub _attachment_root {
- my ($base) = @_;
- return undef unless $base;
- return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)}
- ? $1
- : undef;
+ 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;
+ 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 register {
- my ( $self, $app, $conf ) = @_;
+ my ($self, $app, $conf) = @_;
- $app->hook(before_routes => \&_before_routes);
+ $app->hook(before_routes => \&_before_routes);
}
sub _before_routes {
- my ( $c ) = @_;
- 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 ($c) = @_;
+ 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 $stash = $c->stash;
- my $req = $c->req;
- my $url = $req->url->to_abs;
+ my $stash = $c->stash;
+ my $req = $c->req;
+ my $url = $req->url->to_abs;
- return if $stash->{'mojo.static'};
+ return if $stash->{'mojo.static'};
- my $hostname = $url->host;
- return if $hostname eq $urlbase_host;
+ my $hostname = $url->host;
+ return if $hostname eq $urlbase_host;
- my $path = $url->path;
- return if $path eq '/__lbheartbeat__';
+ my $path = $url->path;
+ return if $path eq '/__lbheartbeat__';
- if ($attachment_base && $hostname eq $attachment_root) {
- $c->redirect_to($urlbase);
- return;
- }
- elsif ($attachment_base && $hostname =~ $attachment_host_regex) {
- if ($path =~ m{^/attachment\.cgi}s) {
- return;
- } else {
- my $new_uri = $url->clone;
- $new_uri->scheme($urlbase_uri->scheme);
- $new_uri->host($urlbase_host);
- $c->redirect_to($new_uri);
- return;
- }
- }
- 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);
- $c->redirect_to($new_uri);
- return;
+ if ($attachment_base && $hostname eq $attachment_root) {
+ $c->redirect_to($urlbase);
+ return;
+ }
+ elsif ($attachment_base && $hostname =~ $attachment_host_regex) {
+ if ($path =~ m{^/attachment\.cgi}s) {
+ return;
}
else {
- $c->redirect_to($urlbase);
- return;
+ my $new_uri = $url->clone;
+ $new_uri->scheme($urlbase_uri->scheme);
+ $new_uri->host($urlbase_host);
+ $c->redirect_to($new_uri);
+ return;
}
+ }
+ 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);
+ $c->redirect_to($new_uri);
+ return;
+ }
+ else {
+ $c->redirect_to($urlbase);
+ return;
+ }
}
1;
diff --git a/Bugzilla/Quantum/SES.pm b/Bugzilla/Quantum/SES.pm
index 03916075d..9d2149978 100644
--- a/Bugzilla/Quantum/SES.pm
+++ b/Bugzilla/Quantum/SES.pm
@@ -1,4 +1,5 @@
package Bugzilla::Quantum::SES;
+
# 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/.
@@ -22,233 +23,228 @@ use Types::Standard qw( :all );
use Type::Utils;
use Type::Params qw( compile );
-my $Invocant = class_type { class => __PACKAGE__ };
+my $Invocant = class_type {class => __PACKAGE__};
sub main {
- my ($self) = @_;
- try {
- $self->_main;
- }
- catch {
- FATAL("Error in SES Handler: ", $_);
- $self->_respond( 400 => 'Bad Request' );
- };
+ my ($self) = @_;
+ try {
+ $self->_main;
+ }
+ catch {
+ FATAL("Error in SES Handler: ", $_);
+ $self->_respond(400 => 'Bad Request');
+ };
}
sub _main {
- my ($self) = @_;
- Bugzilla->error_mode(ERROR_MODE_DIE);
- my $message = $self->_decode_json_wrapper( $self->req->body ) // return;
- my $message_type = $self->req->headers->header('X-Amz-SNS-Message-Type') // '(missing)';
-
- if ( $message_type eq 'SubscriptionConfirmation' ) {
- $self->_confirm_subscription($message);
+ my ($self) = @_;
+ Bugzilla->error_mode(ERROR_MODE_DIE);
+ my $message = $self->_decode_json_wrapper($self->req->body) // return;
+ my $message_type = $self->req->headers->header('X-Amz-SNS-Message-Type')
+ // '(missing)';
+
+ if ($message_type eq 'SubscriptionConfirmation') {
+ $self->_confirm_subscription($message);
+ }
+
+ elsif ($message_type eq 'Notification') {
+ my $notification = $self->_decode_json_wrapper($message->{Message}) // return;
+ unless (
+# https://docs.aws.amazon.com/ses/latest/DeveloperGuide/event-publishing-retrieving-sns-contents.html
+ $self->_handle_notification($notification, 'eventType')
+
+ # https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html
+ || $self->_handle_notification($notification, 'notificationType')
+ )
+ {
+ WARN('Failed to find notification type');
+ $self->_respond(400 => 'Bad Request');
}
+ }
- elsif ( $message_type eq 'Notification' ) {
- my $notification = $self->_decode_json_wrapper( $message->{Message} ) // return;
- unless (
- # https://docs.aws.amazon.com/ses/latest/DeveloperGuide/event-publishing-retrieving-sns-contents.html
- $self->_handle_notification( $notification, 'eventType' )
-
- # https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html
- || $self->_handle_notification( $notification, 'notificationType' )
- )
- {
- WARN('Failed to find notification type');
- $self->_respond( 400 => 'Bad Request' );
- }
- }
-
- else {
- WARN("Unsupported message-type: $message_type");
- $self->_respond( 200 => 'OK' );
- }
+ else {
+ WARN("Unsupported message-type: $message_type");
+ $self->_respond(200 => 'OK');
+ }
}
sub _confirm_subscription {
- state $check = compile($Invocant, Dict[SubscribeURL => Str, slurpy Any]);
- my ($self, $message) = $check->(@_);
-
- my $subscribe_url = $message->{SubscribeURL};
- if ( !$subscribe_url ) {
- WARN('Bad SubscriptionConfirmation request: missing SubscribeURL');
- $self->_respond( 400 => 'Bad Request' );
- return;
- }
-
- my $ua = ua();
- my $res = $ua->get( $message->{SubscribeURL} );
- if ( !$res->is_success ) {
- WARN( 'Bad response from SubscribeURL: ' . $res->status_line );
- $self->_respond( 400 => 'Bad Request' );
- return;
- }
-
- $self->_respond( 200 => 'OK' );
+ state $check = compile($Invocant, Dict [SubscribeURL => Str, slurpy Any]);
+ my ($self, $message) = $check->(@_);
+
+ my $subscribe_url = $message->{SubscribeURL};
+ if (!$subscribe_url) {
+ WARN('Bad SubscriptionConfirmation request: missing SubscribeURL');
+ $self->_respond(400 => 'Bad Request');
+ return;
+ }
+
+ my $ua = ua();
+ my $res = $ua->get($message->{SubscribeURL});
+ if (!$res->is_success) {
+ WARN('Bad response from SubscribeURL: ' . $res->status_line);
+ $self->_respond(400 => 'Bad Request');
+ return;
+ }
+
+ $self->_respond(200 => 'OK');
}
my $NotificationType = Enum [qw( Bounce Complaint )];
my $TypeField = Enum [qw(eventType notificationType)];
-my $Notification = Dict [
- eventType => Optional [$NotificationType],
- notificationType => Optional [$NotificationType],
- slurpy Any,
+my $Notification = Dict [
+ eventType => Optional [$NotificationType],
+ notificationType => Optional [$NotificationType],
+ slurpy Any,
];
sub _handle_notification {
- state $check = compile($Invocant, $Notification, $TypeField );
- my ( $self, $notification, $type_field ) = $check->(@_);
-
- if ( !exists $notification->{$type_field} ) {
- return 0;
- }
- my $type = $notification->{$type_field};
-
- if ( $type eq 'Bounce' ) {
- $self->_process_bounce($notification);
- }
- elsif ( $type eq 'Complaint' ) {
- $self->_process_complaint($notification);
- }
- else {
- WARN("Unsupported notification-type: $type");
- $self->_respond( 200 => 'OK' );
- }
- return 1;
+ state $check = compile($Invocant, $Notification, $TypeField);
+ my ($self, $notification, $type_field) = $check->(@_);
+
+ if (!exists $notification->{$type_field}) {
+ return 0;
+ }
+ my $type = $notification->{$type_field};
+
+ if ($type eq 'Bounce') {
+ $self->_process_bounce($notification);
+ }
+ elsif ($type eq 'Complaint') {
+ $self->_process_complaint($notification);
+ }
+ else {
+ WARN("Unsupported notification-type: $type");
+ $self->_respond(200 => 'OK');
+ }
+ return 1;
}
-my $BouncedRecipients = ArrayRef[
- Dict[
- emailAddress => Str,
- action => Str,
- diagnosticCode => Str,
- slurpy Any,
- ],
+my $BouncedRecipients = ArrayRef [
+ Dict [emailAddress => Str, action => Str, diagnosticCode => Str, slurpy Any,],
];
my $BounceNotification = Dict [
- bounce => Dict [
- bouncedRecipients => $BouncedRecipients,
- reportingMTA => Str,
- bounceSubType => Str,
- bounceType => Str,
- slurpy Any,
- ],
+ bounce => Dict [
+ bouncedRecipients => $BouncedRecipients,
+ reportingMTA => Str,
+ bounceSubType => Str,
+ bounceType => Str,
slurpy Any,
+ ],
+ slurpy Any,
];
sub _process_bounce {
- state $check = compile($Invocant, $BounceNotification);
- my ($self, $notification) = $check->(@_);
-
- # disable each account that is bouncing
- foreach my $recipient ( @{ $notification->{bounce}->{bouncedRecipients} } ) {
- my $address = $recipient->{emailAddress};
- my $reason = sprintf '(%s) %s', $recipient->{action} // 'error', $recipient->{diagnosticCode} // 'unknown';
-
- my $user = Bugzilla::User->new( { name => $address, cache => 1 } );
- if ($user) {
-
- # never auto-disable admin accounts
- if ( $user->in_group('admin') ) {
- Bugzilla->audit("ignoring bounce for admin <$address>: $reason");
- }
-
- else {
- my $template = Bugzilla->template_inner();
- my $vars = {
- mta => $notification->{bounce}->{reportingMTA} // 'unknown',
- reason => $reason,
- };
- my $disable_text;
- $template->process( 'admin/users/bounce-disabled.txt.tmpl', $vars, \$disable_text )
- || die $template->error();
-
- $user->set_disabledtext($disable_text);
- $user->set_disable_mail(1);
- $user->update();
- Bugzilla->audit( "bounce for <$address> disabled userid-" . $user->id . ": $reason" );
- }
- }
-
- else {
- Bugzilla->audit("bounce for <$address> has no user: $reason");
- }
+ state $check = compile($Invocant, $BounceNotification);
+ my ($self, $notification) = $check->(@_);
+
+ # disable each account that is bouncing
+ foreach my $recipient (@{$notification->{bounce}->{bouncedRecipients}}) {
+ my $address = $recipient->{emailAddress};
+ my $reason = sprintf '(%s) %s', $recipient->{action} // 'error',
+ $recipient->{diagnosticCode} // 'unknown';
+
+ my $user = Bugzilla::User->new({name => $address, cache => 1});
+ if ($user) {
+
+ # never auto-disable admin accounts
+ if ($user->in_group('admin')) {
+ Bugzilla->audit("ignoring bounce for admin <$address>: $reason");
+ }
+
+ else {
+ my $template = Bugzilla->template_inner();
+ my $vars = {
+ mta => $notification->{bounce}->{reportingMTA} // 'unknown',
+ reason => $reason,
+ };
+ my $disable_text;
+ $template->process('admin/users/bounce-disabled.txt.tmpl',
+ $vars, \$disable_text)
+ || die $template->error();
+
+ $user->set_disabledtext($disable_text);
+ $user->set_disable_mail(1);
+ $user->update();
+ Bugzilla->audit(
+ "bounce for <$address> disabled userid-" . $user->id . ": $reason");
+ }
+ }
+
+ else {
+ Bugzilla->audit("bounce for <$address> has no user: $reason");
}
+ }
- $self->_respond( 200 => 'OK' );
+ $self->_respond(200 => 'OK');
}
-my $ComplainedRecipients = ArrayRef[Dict[ emailAddress => Str, slurpy Any ]];
-my $ComplaintNotification = Dict[
- complaint => Dict [
- complainedRecipients => $ComplainedRecipients,
- complaintFeedbackType => Str,
- slurpy Any,
- ],
+my $ComplainedRecipients = ArrayRef [Dict [emailAddress => Str, slurpy Any]];
+my $ComplaintNotification = Dict [
+ complaint => Dict [
+ complainedRecipients => $ComplainedRecipients,
+ complaintFeedbackType => Str,
slurpy Any,
+ ],
+ slurpy Any,
];
sub _process_complaint {
- state $check = compile($Invocant, $ComplaintNotification);
- my ($self, $notification) = $check->(@_);
- my $template = Bugzilla->template_inner();
- my $json = JSON::MaybeXS->new(
- pretty => 1,
- utf8 => 1,
- canonical => 1,
- );
-
- foreach my $recipient ( @{ $notification->{complaint}->{complainedRecipients} } ) {
- my $reason = $notification->{complaint}->{complaintFeedbackType} // 'unknown';
- my $address = $recipient->{emailAddress};
- Bugzilla->audit("complaint for <$address> for '$reason'");
- my $vars = {
- email => $address,
- user => Bugzilla::User->new( { name => $address, cache => 1 } ),
- reason => $reason,
- notification => $json->encode($notification),
- };
- my $message;
- $template->process( 'email/ses-complaint.txt.tmpl', $vars, \$message )
- || die $template->error();
- MessageToMTA($message);
- }
+ state $check = compile($Invocant, $ComplaintNotification);
+ my ($self, $notification) = $check->(@_);
+ my $template = Bugzilla->template_inner();
+ my $json = JSON::MaybeXS->new(pretty => 1, utf8 => 1, canonical => 1,);
+
+ foreach my $recipient (@{$notification->{complaint}->{complainedRecipients}}) {
+ my $reason = $notification->{complaint}->{complaintFeedbackType} // 'unknown';
+ my $address = $recipient->{emailAddress};
+ Bugzilla->audit("complaint for <$address> for '$reason'");
+ my $vars = {
+ email => $address,
+ user => Bugzilla::User->new({name => $address, cache => 1}),
+ reason => $reason,
+ notification => $json->encode($notification),
+ };
+ my $message;
+ $template->process('email/ses-complaint.txt.tmpl', $vars, \$message)
+ || die $template->error();
+ MessageToMTA($message);
+ }
- $self->_respond( 200 => 'OK' );
+ $self->_respond(200 => 'OK');
}
sub _respond {
- my ( $self, $code, $message ) = @_;
- $self->render(text => "$message\n", status => $code);
+ my ($self, $code, $message) = @_;
+ $self->render(text => "$message\n", status => $code);
}
sub _decode_json_wrapper {
- state $check = compile($Invocant, Str);
- my ($self, $json) = $check->(@_);
- my $result;
- my $ok = try {
- $result = decode_json($json);
- }
- catch {
- WARN( 'Malformed JSON from ' . $self->tx->remote_address );
- $self->_respond( 400 => 'Bad Request' );
- return undef;
- };
- return $ok ? $result : undef;
+ state $check = compile($Invocant, Str);
+ my ($self, $json) = $check->(@_);
+ my $result;
+ my $ok = try {
+ $result = decode_json($json);
+ }
+ catch {
+ WARN('Malformed JSON from ' . $self->tx->remote_address);
+ $self->_respond(400 => 'Bad Request');
+ return undef;
+ };
+ return $ok ? $result : undef;
}
sub ua {
- my $ua = LWP::UserAgent->new();
- $ua->timeout(10);
- $ua->protocols_allowed( [ 'http', 'https' ] );
- if ( my $proxy_url = Bugzilla->params->{'proxy_url'} ) {
- $ua->proxy( [ 'http', 'https' ], $proxy_url );
- }
- else {
- $ua->env_proxy;
- }
- return $ua;
+ my $ua = LWP::UserAgent->new();
+ $ua->timeout(10);
+ $ua->protocols_allowed(['http', 'https']);
+ if (my $proxy_url = Bugzilla->params->{'proxy_url'}) {
+ $ua->proxy(['http', 'https'], $proxy_url);
+ }
+ else {
+ $ua->env_proxy;
+ }
+ return $ua;
}
1;