1111use warnings;
1212use CGI qw( :standard :escapeHTML -nosticky) ;
1313use CGI::Util qw( unescape) ;
14- use CGI::Carp qw( fatalsToBrowser) ;
14+ use CGI::Carp qw( fatalsToBrowser set_message ) ;
1515use Encode;
1616use Fcntl ' :mode' ;
1717use 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
956971if (!defined $action ) {
957972 if (defined $hash ) {
@@ -972,11 +987,16 @@ sub evaluate_path_info {
972987 die_error(400, " Project needed" );
973988}
974989$actions {$action }-> ();
975- exit ;
990+ DONE_GITWEB:
991+ 1;
976992
977993# # ======================================================================
978994# # action links
979995
996+ # possible values of extra options
997+ # -full => 0|1 - use absolute/full URL ($my_uri/$my_url as base)
998+ # -replay => 1 - start from a current view (replay with modifications)
999+ # -path_info => 0|1 - don't use/use path_info URL (if possible)
9801000sub href {
9811001 my %params = @_ ;
9821002 # default is to use -absolute url() i.e. $my_uri
@@ -993,7 +1013,8 @@ sub href {
9931013 }
9941014
9951015 my $use_pathinfo = gitweb_check_feature(' pathinfo' );
996- if ($use_pathinfo and defined $params {' project' }) {
1016+ if (defined $params {' project' } &&
1017+ (exists $params {-path_info} ? $params {-path_info} : $use_pathinfo )) {
9971018 # try to put as many parameters as possible in PATH_INFO:
9981019 # - project name
9991020 # - action
@@ -3161,23 +3182,30 @@ sub blob_contenttype {
31613182# # ======================================================================
31623183# # functions printing HTML: header, footer, error page
31633184
3185+ sub get_page_title {
3186+ my $title = to_utf8($site_name );
3187+
3188+ return $title unless (defined $project );
3189+ $title .= " - " . to_utf8($project );
3190+
3191+ return $title unless (defined $action );
3192+ $title .= " /$action " ; # $action is US-ASCII (7bit ASCII)
3193+
3194+ return $title unless (defined $file_name );
3195+ $title .= " - " . esc_path($file_name );
3196+ if ($action eq " tree" && $file_name !~ m | /$ | ) {
3197+ $title .= " /" ;
3198+ }
3199+
3200+ return $title ;
3201+ }
3202+
31643203sub git_header_html {
31653204 my $status = shift || " 200 OK" ;
31663205 my $expires = shift ;
3206+ my %opts = @_ ;
31673207
3168- my $title = " $site_name " ;
3169- if (defined $project ) {
3170- $title .= " - " . to_utf8($project );
3171- if (defined $action ) {
3172- $title .= " /$action " ;
3173- if (defined $file_name ) {
3174- $title .= " - " . esc_path($file_name );
3175- if ($action eq " tree" && $file_name !~ m | /$ | ) {
3176- $title .= " /" ;
3177- }
3178- }
3179- }
3180- }
3208+ my $title = get_page_title();
31813209 my $content_type ;
31823210 # require explicit support from the UA if we are to send the page as
31833211 # 'application/xhtml+xml', otherwise send it as plain old 'text/html'.
@@ -3191,7 +3219,8 @@ sub git_header_html {
31913219 $content_type = ' text/html' ;
31923220 }
31933221 print $cgi -> header(-type => $content_type , -charset => ' utf-8' ,
3194- -status => $status , -expires => $expires );
3222+ -status => $status , -expires => $expires )
3223+ unless ($opts {' -no_http_headers' });
31953224 my $mod_perl_version = $ENV {' MOD_PERL' } ? " $ENV {'MOD_PERL'}" : ' ' ;
31963225 print <<EOF ;
31973226<?xml version="1.0" encoding="utf-8"?>
@@ -3408,6 +3437,7 @@ sub die_error {
34083437 my $status = shift || 500;
34093438 my $error = esc_html(shift ) || " Internal Server Error" ;
34103439 my $extra = shift ;
3440+ my %opts = @_ ;
34113441
34123442 my %http_responses = (
34133443 400 => ' 400 Bad Request' ,
@@ -3416,7 +3446,7 @@ sub die_error {
34163446 500 => ' 500 Internal Server Error' ,
34173447 503 => ' 503 Service Unavailable' ,
34183448 );
3419- git_header_html($http_responses {$status });
3449+ git_header_html($http_responses {$status }, undef , %opts );
34203450 print <<EOF ;
34213451<div class="page_body">
34223452<br /><br />
@@ -3430,7 +3460,8 @@ sub die_error {
34303460 print " </div>\n " ;
34313461
34323462 git_footer_html();
3433- exit ;
3463+ goto DONE_GITWEB
3464+ unless ($opts {' -error_handler' });
34343465}
34353466
34363467# # ----------------------------------------------------------------------
0 commit comments