Skip to content

Commit 7a59745

Browse files
jnarebgitster
authored andcommitted
gitweb: Add custom error handler using die_error
Change the default message for errors (for fatalsToBrowser) to use die_error() subroutine. This way errors (and explicitely calling 'die MESSAGE') would generate 'Internal Server Error' error message. Note that call to set_message is intentionally not put in BEGIN block; we set error handler to use die_error() only after we are sure that we can use it, after all needed variables are set. Due to the fact that error handler set via set_message() subroutine from CGI::Carp (in the fatalsToBrowser case) is called after HTTP headers were already printed (with exception of MOD_PERL), gitweb cannot return 'Status: 500 Internal Server Error'. Thanks to the fact that die_error() no longer uses 'exit', errors would be logged by CGI::Carp, independent on whether default error handler is used, or handle_errors_html which uses die_error is used. Signed-off-by: Jakub Narebski <[email protected]> Acked-by: Petr Baudis <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c42b00c commit 7a59745

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

gitweb/gitweb.perl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use warnings;
1212
use CGI qw(:standard :escapeHTML -nosticky);
1313
use CGI::Util qw(unescape);
14-
use CGI::Carp qw(fatalsToBrowser);
14+
use CGI::Carp qw(fatalsToBrowser set_message);
1515
use Encode;
1616
use Fcntl ':mode';
1717
use File::Find qw();
@@ -952,6 +952,21 @@ sub evaluate_path_info {
952952
$git_avatar = '';
953953
}
954954

955+
# custom error handler: 'die <message>' is Internal Server Error
956+
sub handle_errors_html {
957+
my $msg = shift; # it is already HTML escaped
958+
959+
# to avoid infinite loop where error occurs in die_error,
960+
# change handler to default handler, disabling handle_errors_html
961+
set_message("Error occured when inside die_error:\n$msg");
962+
963+
# you cannot jump out of die_error when called as error handler;
964+
# the subroutine set via CGI::Carp::set_message is called _after_
965+
# HTTP headers are already written, so it cannot write them itself
966+
die_error(undef, undef, $msg, -error_handler => 1, -no_http_header => 1);
967+
}
968+
set_message(\&handle_errors_html);
969+
955970
# dispatch
956971
if (!defined $action) {
957972
if (defined $hash) {
@@ -3167,6 +3182,7 @@ sub blob_contenttype {
31673182
sub git_header_html {
31683183
my $status = shift || "200 OK";
31693184
my $expires = shift;
3185+
my %opts = @_;
31703186

31713187
my $title = "$site_name";
31723188
if (defined $project) {
@@ -3194,7 +3210,8 @@ sub git_header_html {
31943210
$content_type = 'text/html';
31953211
}
31963212
print $cgi->header(-type=>$content_type, -charset => 'utf-8',
3197-
-status=> $status, -expires => $expires);
3213+
-status=> $status, -expires => $expires)
3214+
unless ($opts{'-no_http_headers'});
31983215
my $mod_perl_version = $ENV{'MOD_PERL'} ? " $ENV{'MOD_PERL'}" : '';
31993216
print <<EOF;
32003217
<?xml version="1.0" encoding="utf-8"?>
@@ -3411,6 +3428,7 @@ sub die_error {
34113428
my $status = shift || 500;
34123429
my $error = esc_html(shift) || "Internal Server Error";
34133430
my $extra = shift;
3431+
my %opts = @_;
34143432

34153433
my %http_responses = (
34163434
400 => '400 Bad Request',
@@ -3419,7 +3437,7 @@ sub die_error {
34193437
500 => '500 Internal Server Error',
34203438
503 => '503 Service Unavailable',
34213439
);
3422-
git_header_html($http_responses{$status});
3440+
git_header_html($http_responses{$status}, undef, %opts);
34233441
print <<EOF;
34243442
<div class="page_body">
34253443
<br /><br />
@@ -3433,7 +3451,8 @@ sub die_error {
34333451
print "</div>\n";
34343452

34353453
git_footer_html();
3436-
goto DONE_GITWEB;
3454+
goto DONE_GITWEB
3455+
unless ($opts{'-error_handler'});
34373456
}
34383457

34393458
## ----------------------------------------------------------------------

0 commit comments

Comments
 (0)