From: John 'Warthog9' Hawley Date: Wed, 13 Jan 2010 09:34:40 GMT Subject: [PATCH 5/7] gitweb: Convert output to using indirect file handle Message-ID: <1263375282-15508-6-git-send-email-warthog9@eaglescrag.net> In-Reply-To: <1263375282-15508-5-git-send-email-warthog9@eaglescrag.net> This converts the output handling of gitweb to using an indirect file handle. This is in preparation to add the caching layer. This is a slight modification to the way I was originally doing it by passing the output around. This should be a nop and this shouldn't change the behavior of gitweb. This does leave error reporting functions (die_error specifically) continuing to output directly as I want to garauntee those will report their errors regardless of what may be going on with respect to the rest of the output. --- gitweb/gitweb.perl | 876 ++++++++++++++++++++++++++-------------------------- 1 files changed, 442 insertions(+), 434 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index b8f2a67..3b6bc06 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -455,6 +455,13 @@ our %feature = ( 'default' => [0]}, ); +# Basic file handler for all of gitweb, there are two of them. The first +# is the basic text/html file handler which is used for everything other +# then the binary files, that uses a separate file handler though +# these are both set to STDOUT for the time being. +our $output_handler = *STDOUT; +our $output_handler_bin = *STDOUT; + sub gitweb_get_feature { my ($name) = @_; return unless exists $feature{$name}; @@ -3091,7 +3098,7 @@ sub insert_file { my $filename = shift; open my $fd, '<', $filename; - print map { to_utf8($_) } <$fd>; + print {$output_handler} map { to_utf8($_) } <$fd>; close $fd; } @@ -3208,10 +3215,10 @@ sub git_header_html { } else { $content_type = 'text/html'; } - print $cgi->header(-type=>$content_type, -charset => 'utf-8', + print {$output_handler} $cgi->header(-type=>$content_type, -charset => 'utf-8', -status=> $status, -expires => $expires); my $mod_perl_version = $ENV{'MOD_PERL'} ? " $ENV{'MOD_PERL'}" : ''; - print < @@ -3226,16 +3233,16 @@ EOF # the stylesheet, favicon etc urls won't work correctly with path_info # unless we set the appropriate base URL if ($ENV{'PATH_INFO'}) { - print "\n"; + print {$output_handler} "\n"; } # print out each stylesheet that exist, providing backwards capability # for those people who defined $stylesheet in a config file if (defined $stylesheet) { - print ''."\n"; + print {$output_handler} ''."\n"; } else { foreach my $stylesheet (@stylesheets) { next unless $stylesheet; - print ''."\n"; + print {$output_handler} ''."\n"; } } if (defined $project) { @@ -3254,7 +3261,7 @@ EOF $href_params{'action'} = $type; $link_attr{'-href'} = href(%href_params); - print "'."\n", $site_name, href(project=>undef, action=>"project_index")); - printf(''."\n", $site_name, href(project=>undef, action=>"opml")); } if (defined $favicon) { - print qq(\n); + print {$output_handler} qq(\n); } - print "\n" . + print {$output_handler} "\n" . "\n"; if (-f $site_header) { insert_file($site_header); } - print "
\n" . + print {$output_handler} "
\n" . $cgi->a({-href => esc_url($logo_url), -title => $logo_label}, qq()); - print $cgi->a({-href => esc_url($home_link)}, $home_link_str) . " / "; + print {$output_handler} $cgi->a({-href => esc_url($home_link)}, $home_link_str) . " / "; if (defined $project) { - print $cgi->a({-href => href(action=>"summary")}, esc_html($project)); + print {$output_handler} $cgi->a({-href => href(action=>"summary")}, esc_html($project)); if (defined $action) { - print " / $action"; + print {$output_handler} " / $action"; } - print "\n"; + print {$output_handler} "\n"; } - print "
\n"; + print {$output_handler} "
\n"; my $have_search = gitweb_check_feature('search'); if (defined $project && $have_search) { @@ -3323,7 +3330,7 @@ EOF if ($use_pathinfo) { $action .= "/".esc_url($project); } - print $cgi->startform(-method => "get", -action => $action) . + print {$output_handler} $cgi->startform(-method => "get", -action => $action) . "
\n" . (!$use_pathinfo && $cgi->input({-name=>"p", -value=>$project, -type=>"hidden"}) . "\n") . @@ -3346,11 +3353,11 @@ EOF sub git_footer_html { my $feed_class = 'rss_logo'; - print "
\n"; + print {$output_handler} "
\n"; if (defined $project) { my $descr = git_get_project_description($project); if (defined $descr) { - print "\n"; + print {$output_handler} "\n"; } my %href_params = get_feed_info(); @@ -3361,22 +3368,22 @@ sub git_footer_html { foreach my $format qw(RSS Atom) { $href_params{'action'} = lc($format); - print $cgi->a({-href => href(%href_params), + print {$output_handler} $cgi->a({-href => href(%href_params), -title => "$href_params{'-title'} $format feed", -class => $feed_class}, $format)."\n"; } } else { - print $cgi->a({-href => href(project=>undef, action=>"opml"), + print {$output_handler} $cgi->a({-href => href(project=>undef, action=>"opml"), -class => $feed_class}, "OPML") . " "; - print $cgi->a({-href => href(project=>undef, action=>"project_index"), + print {$output_handler} $cgi->a({-href => href(project=>undef, action=>"project_index"), -class => $feed_class}, "TXT") . "\n"; } - print "
\n"; # class="page_footer" + print {$output_handler} "
\n"; # class="page_footer" if (defined $t0 && gitweb_check_feature('timed')) { - print "
\n"; - print 'This page took '. + print {$output_handler} "
\n"; + print {$output_handler} 'This page took '. ''. Time::HiRes::tv_interval($t0, [Time::HiRes::gettimeofday()]). ' seconds '. @@ -3385,26 +3392,26 @@ sub git_footer_html { $number_of_git_cmds. ' git commands '. " to generate.\n"; - print "
\n"; # class="page_footer" + print {$output_handler} "
\n"; # class="page_footer" } if (-f $site_footer) { insert_file($site_footer); } - print qq!\n!; + print {$output_handler} qq!\n!; if ($action eq 'blame_incremental') { - print qq!\n!; } elsif (gitweb_check_feature('javascript-actions')) { - print qq!\n!; } - print "\n" . + print {$output_handler} "\n" . ""; } @@ -3488,12 +3495,12 @@ sub git_print_page_nav { $arg{$label}{'_href'} = $link; } - print "
\n" . + print {$output_handler} "
\n" . (join " | ", map { $_ eq $current ? $_ : $cgi->a({-href => ($arg{$_}{_href} ? $arg{$_}{_href} : href(%{$arg{$_}}))}, "$_") } @navs); - print "
\n$extra
\n" . + print {$output_handler} "
\n$extra
\n" . "
\n"; } @@ -3534,7 +3541,7 @@ sub git_print_header_div { $args{'hash'} = $hash if $hash; $args{'hash_base'} = $hash_base if $hash_base; - print "
\n" . + print {$output_handler} "
\n" . $cgi->a({-href => href(%args), -class => "title"}, $title ? $title : $action) . "\n
\n"; @@ -3543,10 +3550,10 @@ sub git_print_header_div { sub print_local_time { my %date = @_; if ($date{'hour_local'} < 6) { - printf(" (%02d:%02d %s)", + printf({$output_handler} " (%02d:%02d %s)", $date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'}); } else { - printf(" (%02d:%02d %s)", + printf({$output_handler} " (%02d:%02d %s)", $date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'}); } } @@ -3559,11 +3566,11 @@ sub git_print_authorship { my $author = $co->{'author_name'}; my %ad = parse_date($co->{'author_epoch'}, $co->{'author_tz'}); - print "<$tag class=\"author_date\">" . + print {$output_handler} "<$tag class=\"author_date\">" . format_search_author($author, "author", esc_html($author)) . " [$ad{'rfc2822'}"; - print_local_time(%ad) if ($opts{-localtime}); - print "]" . git_get_avatar($co->{'author_email'}, -pad_before => 1) + print {$output_handler} get_local_time(%ad) if ($opts{-localtime}); + print {$output_handler} "]" . git_get_avatar($co->{'author_email'}, -pad_before => 1) . "\n"; } @@ -3579,7 +3586,7 @@ sub git_print_authorship_rows { @people = ('author', 'committer') unless @people; foreach my $who (@people) { my %wd = parse_date($co->{"${who}_epoch"}, $co->{"${who}_tz"}); - print "$who" . + print {$output_handler} "$who" . format_search_author($co->{"${who}_name"}, $who, esc_html($co->{"${who}_name"})) . " " . format_search_author($co->{"${who}_email"}, $who, @@ -3589,8 +3596,8 @@ sub git_print_authorship_rows { "\n" . "" . " $wd{'rfc2822'}"; - print_local_time(%wd); - print "" . + print {$output_handler} get_local_time(%wd); + print {$output_handler} "" . "\n"; } } @@ -3600,11 +3607,10 @@ sub git_print_page_path { my $type = shift; my $hb = shift; - - print "
"; - print $cgi->a({-href => href(action=>"tree", hash_base=>$hb), + print {$output_handler} "
"; + print {$output_handler} $cgi->a({-href => href(action=>"tree", hash_base=>$hb), -title => 'tree root'}, to_utf8("[$project]")); - print " / "; + print {$output_handler} " / "; if (defined $name) { my @dirname = split '/', $name; my $basename = pop @dirname; @@ -3612,25 +3618,25 @@ sub git_print_page_path { foreach my $dir (@dirname) { $fullname .= ($fullname ? '/' : '') . $dir; - print $cgi->a({-href => href(action=>"tree", file_name=>$fullname, + print {$output_handler} $cgi->a({-href => href(action=>"tree", file_name=>$fullname, hash_base=>$hb), -title => $fullname}, esc_path($dir)); - print " / "; + print {$output_handler} " / "; } if (defined $type && $type eq 'blob') { - print $cgi->a({-href => href(action=>"blob_plain", file_name=>$file_name, + print {$output_handler} $cgi->a({-href => href(action=>"blob_plain", file_name=>$file_name, hash_base=>$hb), -title => $name}, esc_path($basename)); } elsif (defined $type && $type eq 'tree') { - print $cgi->a({-href => href(action=>"tree", file_name=>$file_name, + print {$output_handler} $cgi->a({-href => href(action=>"tree", file_name=>$file_name, hash_base=>$hb), -title => $name}, esc_path($basename)); - print " / "; + print {$output_handler} " / "; } else { - print esc_path($basename); + print {$output_handler} esc_path($basename); } } - print "
\n"; + print {$output_handler} "
\n"; } sub git_print_log { @@ -3654,7 +3660,7 @@ sub git_print_log { $signoff = 1; $empty = 0; if (! $opts{'-remove_signoff'}) { - print "" . esc_html($line) . "
\n"; + print {$output_handler} "" . esc_html($line) . "
\n"; next; } else { # remove signoff lines @@ -3673,12 +3679,12 @@ sub git_print_log { $empty = 0; } - print format_log_line_html($line) . "
\n"; + print {$output_handler} format_log_line_html($line) . "
\n"; } if ($opts{'-final_empty_line'}) { # end with single empty line - print "
\n" unless $empty; + print {$output_handler} "
\n" unless $empty; } } @@ -3751,12 +3757,12 @@ sub git_print_tree_entry { # the mode of the entry, list is the name of the entry, an href, # and link is the action links of the entry. - print "" . mode_str($t->{'mode'}) . "\n"; + print {$output_handler} "" . mode_str($t->{'mode'}) . "\n"; if (exists $t->{'size'}) { - print "$t->{'size'}\n"; + print {$output_handler} "$t->{'size'}\n"; } if ($t->{'type'} eq "blob") { - print "" . + print {$output_handler} "" . $cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}", %base_key), -class => "list"}, esc_path($t->{'name'})); @@ -3765,71 +3771,71 @@ sub git_print_tree_entry { if ($link_target) { my $norm_target = normalize_link_target($link_target, $basedir); if (defined $norm_target) { - print " -> " . + print {$output_handler} " -> " . $cgi->a({-href => href(action=>"object", hash_base=>$hash_base, file_name=>$norm_target), -title => $norm_target}, esc_path($link_target)); } else { - print " -> " . esc_path($link_target); + print {$output_handler} " -> " . esc_path($link_target); } } } - print "\n"; - print ""; - print $cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'}, + print {$output_handler} "\n"; + print {$output_handler} ""; + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}", %base_key)}, "blob"); if ($have_blame) { - print " | " . + print {$output_handler} " | " . $cgi->a({-href => href(action=>"blame", hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}", %base_key)}, "blame"); } if (defined $hash_base) { - print " | " . + print {$output_handler} " | " . $cgi->a({-href => href(action=>"history", hash_base=>$hash_base, hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}")}, "history"); } - print " | " . + print {$output_handler} " | " . $cgi->a({-href => href(action=>"blob_plain", hash_base=>$hash_base, file_name=>"$basedir$t->{'name'}")}, "raw"); - print "\n"; + print {$output_handler} "\n"; } elsif ($t->{'type'} eq "tree") { - print ""; - print $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'}, + print {$output_handler} ""; + print {$output_handler} $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}", %base_key)}, esc_path($t->{'name'})); - print "\n"; - print ""; - print $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'}, + print {$output_handler} "\n"; + print {$output_handler} ""; + print {$output_handler} $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}", %base_key)}, "tree"); if (defined $hash_base) { - print " | " . + print {$output_handler} " | " . $cgi->a({-href => href(action=>"history", hash_base=>$hash_base, file_name=>"$basedir$t->{'name'}")}, "history"); } - print "\n"; + print {$output_handler} "\n"; } else { # unknown object: we can only present history for it # (this includes 'commit' object, i.e. submodule support) - print "" . + print {$output_handler} "" . esc_path($t->{'name'}) . "\n"; - print ""; + print {$output_handler} ""; if (defined $hash_base) { - print $cgi->a({-href => href(action=>"history", + print {$output_handler} $cgi->a({-href => href(action=>"history", hash_base=>$hash_base, file_name=>"$basedir$t->{'name'}")}, "history"); } - print "\n"; + print {$output_handler} "\n"; } } @@ -3876,13 +3882,13 @@ sub git_difftree_body { my ($difftree, $hash, @parents) = @_; my ($parent) = $parents[0]; my $have_blame = gitweb_check_feature('blame'); - print "
\n"; + print {$output_handler} "
\n"; if ($#{$difftree} > 10) { - print(($#{$difftree} + 1) . " files changed:\n"); + print {$output_handler} (($#{$difftree} + 1) . " files changed:\n"); } - print "
\n"; + print {$output_handler} "
\n"; - print " 1 ? "combined " : "") . "diff_tree\">\n"; @@ -3890,11 +3896,11 @@ sub git_difftree_body { my $has_header = @$difftree && @parents > 1 && $action eq 'commitdiff'; if ($has_header) { # table header - print "\n" . + print {$output_handler} "\n" . "\n"; # filename, patchN link for (my $i = 0; $i < @parents; $i++) { my $par = $parents[$i]; - print "\n"; } - print "\n\n"; + print {$output_handler} "\n\n"; } my $alternate = 1; @@ -3911,9 +3917,9 @@ sub git_difftree_body { my $diff = parsed_difftree_line($line); if ($alternate) { - print "\n"; + print {$output_handler} "\n"; } else { - print "\n"; + print {$output_handler} "\n"; } $alternate ^= 1; @@ -3924,14 +3930,14 @@ sub git_difftree_body { if (!is_deleted($diff)) { # file exists in the result (child) commit - print "\n"; } else { - print "\n"; } @@ -3939,7 +3945,7 @@ sub git_difftree_body { if ($action eq 'commitdiff') { # link to patch $patchno++; - print "\n"; @@ -3957,9 +3963,9 @@ sub git_difftree_body { $not_deleted ||= ($status ne 'D'); if ($status eq 'A') { - print "\n"; + print {$output_handler} "\n"; } elsif ($status eq 'D') { - print "\n"; } else { if ($diff->{'to_id'} eq $from_hash) { - print "\n"; + print {$output_handler} "\n"; - print "\n"; + print {$output_handler} "\n"; next; # instead of 'else' clause, to avoid extra indent } # else ordinary diff @@ -4027,51 +4033,51 @@ sub git_difftree_body { my $mode_chng = "[new $to_file_type"; $mode_chng .= " with mode: $to_mode_str" if $to_mode_str; $mode_chng .= "]"; - print "\n"; - print "\n"; - print "\n"; + print {$output_handler} "\n"; + print {$output_handler} "\n"; + print {$output_handler} "\n"; } elsif ($diff->{'status'} eq "D") { # deleted my $mode_chng = "[deleted $from_file_type]"; - print "\n"; - print "\n"; - print "\n"; + print {$output_handler} "\n"; + print {$output_handler} "\n"; + print {$output_handler} "\n"; } elsif ($diff->{'status'} eq "M" || $diff->{'status'} eq "T") { # modified, or type changed my $mode_chnge = ""; @@ -4089,39 +4095,39 @@ sub git_difftree_body { } $mode_chnge .= "]\n"; } - print "\n"; - print "\n"; - print "\n"; + print {$output_handler} "\n"; + print {$output_handler} "\n"; + print {$output_handler} "\n"; } elsif ($diff->{'status'} eq "R" || $diff->{'status'} eq "C") { # renamed or copied my %status_name = ('R' => 'moved', 'C' => 'copied'); @@ -4131,7 +4137,7 @@ sub git_difftree_body { # mode also for directories, so we cannot use $to_mode_str $mode_chng = sprintf(", mode: %04o", $to_mode_oct & 0777); } - print "\n" . @@ -4144,35 +4150,35 @@ sub git_difftree_body { if ($action eq 'commitdiff') { # link to patch $patchno++; - print $cgi->a({-href => "#patch$patchno"}, "patch") . + print {$output_handler} $cgi->a({-href => "#patch$patchno"}, "patch") . " | "; } elsif ($diff->{'to_id'} ne $diff->{'from_id'}) { # "commit" view and modified file (not only pure rename or copy) - print $cgi->a({-href => href(action=>"blobdiff", + print {$output_handler} $cgi->a({-href => href(action=>"blobdiff", hash=>$diff->{'to_id'}, hash_parent=>$diff->{'from_id'}, hash_base=>$hash, hash_parent_base=>$parent, file_name=>$diff->{'to_file'}, file_parent=>$diff->{'from_file'})}, "diff") . " | "; } - print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, hash_base=>$parent, file_name=>$diff->{'to_file'})}, "blob") . " | "; if ($have_blame) { - print $cgi->a({-href => href(action=>"blame", hash_base=>$hash, + print {$output_handler} $cgi->a({-href => href(action=>"blame", hash_base=>$hash, file_name=>$diff->{'to_file'})}, "blame") . " | "; } - print $cgi->a({-href => href(action=>"history", hash_base=>$hash, + print {$output_handler} $cgi->a({-href => href(action=>"history", hash_base=>$hash, file_name=>$diff->{'to_file'})}, "history"); - print "\n"; + print {$output_handler} "\n"; } # we should not encounter Unmerged (U) or Unknown (X) status - print "\n"; + print {$output_handler} "\n"; } - print "" if $has_header; - print "
" . + print {$output_handler} "" . $cgi->a({-href => href(action=>"commitdiff", hash=>$hash, hash_parent=>$par), -title => 'commitdiff to parent number ' . @@ -3902,7 +3908,7 @@ sub git_difftree_body { $i+1) . " 
" . + print {$output_handler} "" . $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, file_name=>$diff->{'to_file'}, hash_base=>$hash), -class => "list"}, esc_path($diff->{'to_file'})) . "" . + print {$output_handler} "" . esc_path($diff->{'to_file'}) . "" . + print {$output_handler} "" . $cgi->a({-href => "#patch$patchno"}, "patch") . " | " . " | | " . + print {$output_handler} "" . $cgi->a({-href => href(action=>"blob", hash_base=>$hash, hash=>$from_hash, @@ -3968,11 +3974,11 @@ sub git_difftree_body { " | "; + print {$output_handler} ""; } - print $cgi->a({-href => href(action=>"blobdiff", + print {$output_handler} $cgi->a({-href => href(action=>"blobdiff", hash=>$diff->{'to_id'}, hash_parent=>$from_hash, hash_base=>$hash, @@ -3984,24 +3990,24 @@ sub git_difftree_body { } } - print ""; + print {$output_handler} ""; if ($not_deleted) { - print $cgi->a({-href => href(action=>"blob", + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, file_name=>$diff->{'to_file'}, hash_base=>$hash)}, "blob"); - print " | " if ($has_history); + print {$output_handler} " | " if ($has_history); } if ($has_history) { - print $cgi->a({-href => href(action=>"history", + print {$output_handler} $cgi->a({-href => href(action=>"history", file_name=>$diff->{'to_file'}, hash_base=>$hash)}, "history"); } - print "
"; - print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + print {$output_handler} ""; + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, hash_base=>$hash, file_name=>$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); - print "$mode_chng"; + print {$output_handler} "$mode_chng"; if ($action eq 'commitdiff') { # link to patch $patchno++; - print $cgi->a({-href => "#patch$patchno"}, "patch"); - print " | "; + print {$output_handler} $cgi->a({-href => "#patch$patchno"}, "patch"); + print {$output_handler} " | "; } - print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, hash_base=>$hash, file_name=>$diff->{'file'})}, "blob"); - print ""; - print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, + print {$output_handler} ""; + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, hash_base=>$parent, file_name=>$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); - print "$mode_chng"; + print {$output_handler} "$mode_chng"; if ($action eq 'commitdiff') { # link to patch $patchno++; - print $cgi->a({-href => "#patch$patchno"}, "patch"); - print " | "; + print {$output_handler} $cgi->a({-href => "#patch$patchno"}, "patch"); + print {$output_handler} " | "; } - print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, hash_base=>$parent, file_name=>$diff->{'file'})}, "blob") . " | "; if ($have_blame) { - print $cgi->a({-href => href(action=>"blame", hash_base=>$parent, + print {$output_handler} $cgi->a({-href => href(action=>"blame", hash_base=>$parent, file_name=>$diff->{'file'})}, "blame") . " | "; } - print $cgi->a({-href => href(action=>"history", hash_base=>$parent, + print {$output_handler} $cgi->a({-href => href(action=>"history", hash_base=>$parent, file_name=>$diff->{'file'})}, "history"); - print ""; - print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + print {$output_handler} ""; + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, hash_base=>$hash, file_name=>$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); - print "$mode_chnge"; + print {$output_handler} "$mode_chnge"; if ($action eq 'commitdiff') { # link to patch $patchno++; - print $cgi->a({-href => "#patch$patchno"}, "patch") . + print {$output_handler} $cgi->a({-href => "#patch$patchno"}, "patch") . " | "; } elsif ($diff->{'to_id'} ne $diff->{'from_id'}) { # "commit" view and modified file (not onlu mode changed) - print $cgi->a({-href => href(action=>"blobdiff", + print {$output_handler} $cgi->a({-href => href(action=>"blobdiff", hash=>$diff->{'to_id'}, hash_parent=>$diff->{'from_id'}, hash_base=>$hash, hash_parent_base=>$parent, file_name=>$diff->{'file'})}, "diff") . " | "; } - print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + print {$output_handler} $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, hash_base=>$hash, file_name=>$diff->{'file'})}, "blob") . " | "; if ($have_blame) { - print $cgi->a({-href => href(action=>"blame", hash_base=>$hash, + print {$output_handler} $cgi->a({-href => href(action=>"blame", hash_base=>$hash, file_name=>$diff->{'file'})}, "blame") . " | "; } - print $cgi->a({-href => href(action=>"history", hash_base=>$hash, + print {$output_handler} $cgi->a({-href => href(action=>"history", hash_base=>$hash, file_name=>$diff->{'file'})}, "history"); - print "" . + print {$output_handler} "" . $cgi->a({-href => href(action=>"blob", hash_base=>$hash, hash=>$diff->{'to_id'}, file_name=>$diff->{'to_file'}), -class => "list"}, esc_path($diff->{'to_file'})) . "
\n"; + print {$output_handler} "" if $has_header; + print {$output_handler} "\n"; } sub git_patchset_body { @@ -4187,7 +4193,7 @@ sub git_patchset_body { my $to_name; my (%from, %to); - print "
\n"; + print {$output_handler} "
\n"; # skip to first patch while ($patch_line = <$fd>) { @@ -4215,7 +4221,7 @@ sub git_patchset_body { # and parse raw git-diff line if needed if (is_patch_split($diffinfo, { 'to_file' => $to_name })) { # this is continuation of a split patch - print "
\n"; + print {$output_handler} "
\n"; } else { # advance raw git-diff output if needed $patch_idx++ if defined $diffinfo; @@ -4227,7 +4233,7 @@ sub git_patchset_body { # find which patch (using pathname of result) we are at now; if ($is_combined) { while ($to_name ne $diffinfo->{'to_file'}) { - print "
\n" . + print {$output_handler} "
\n" . format_diff_cc_simplified($diffinfo, @hash_parents) . "
\n"; # class="patch" @@ -4244,7 +4250,7 @@ sub git_patchset_body { # this is first patch for raw difftree line with $patch_idx index # we index @$difftree array from 0, but number patches from 1 - print "
\n"; + print {$output_handler} "
\n"; } # git diff header @@ -4252,25 +4258,25 @@ sub git_patchset_body { #assert($patch_line !~ m!$/$!) if DEBUG; # is chomp-ed $patch_number++; # print "git diff" header - print format_git_diff_header_line($patch_line, $diffinfo, + print {$output_handler} format_git_diff_header_line($patch_line, $diffinfo, \%from, \%to); # print extended diff header - print "
\n"; + print {$output_handler} "
\n"; EXTENDED_HEADER: while ($patch_line = <$fd>) { chomp $patch_line; last EXTENDED_HEADER if ($patch_line =~ m/^--- |^diff /); - print format_extended_diff_header_line($patch_line, $diffinfo, + print {$output_handler} format_extended_diff_header_line($patch_line, $diffinfo, \%from, \%to); } - print "
\n"; # class="diff extended_header" + print {$output_handler} "
\n"; # class="diff extended_header" # from-file/to-file diff header if (! $patch_line) { - print "
\n"; # class="patch" + print {$output_handler} "
\n"; # class="patch" last PATCH; } next PATCH if ($patch_line =~ m/^diff /); @@ -4281,7 +4287,7 @@ sub git_patchset_body { chomp $patch_line; #assert($patch_line =~ m/^\+\+\+/) if DEBUG; - print format_diff_from_to_header($last_patch_line, $patch_line, + print {$output_handler} format_diff_from_to_header($last_patch_line, $patch_line, $diffinfo, \%from, \%to, @hash_parents); @@ -4292,11 +4298,11 @@ sub git_patchset_body { next PATCH if ($patch_line =~ m/^diff /); - print format_diff_line($patch_line, \%from, \%to); + print {$output_handler} format_diff_line($patch_line, \%from, \%to); } } continue { - print "
\n"; # class="patch" + print {$output_handler} "
\n"; # class="patch" } # for compact combined (--cc) format, with chunk and patch simpliciaction @@ -4308,7 +4314,7 @@ sub git_patchset_body { $diffinfo = parsed_difftree_line($difftree->[$patch_idx]); # generate anchor for "patch" links in difftree / whatchanged part - print "
\n" . + print {$output_handler} "
\n" . format_diff_cc_simplified($diffinfo, @hash_parents) . "
\n"; # class="patch" @@ -4317,13 +4323,13 @@ sub git_patchset_body { if ($patch_number == 0) { if (@hash_parents > 1) { - print "
Trivial merge
\n"; + print {$output_handler} "
Trivial merge
\n"; } else { - print "
No differences found
\n"; + print {$output_handler} "
No differences found
\n"; } } - print "
\n"; # class="patchset" + print {$output_handler} "
\n"; # class="patchset" } # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -4376,9 +4382,9 @@ sub print_sort_th { $header ||= ucfirst($name); if ($order eq $name) { - print "$header\n"; + print {$output_handler} "$header\n"; } else { - print "" . + print {$output_handler} "" . $cgi->a({-href => href(-replay=>1, order=>$name), -class => "header"}, $header) . "\n"; @@ -4418,20 +4424,20 @@ sub git_project_list_body { } } my $cloud = git_populate_project_tagcloud(\%ctags); - print git_show_project_tagcloud($cloud, 64); + print {$output_handler} git_show_project_tagcloud($cloud, 64); } - print "\n"; + print {$output_handler} "
\n"; unless ($no_header) { - print "\n"; + print {$output_handler} "\n"; if ($check_forks) { - print "\n"; + print {$output_handler} "\n"; } - print_sort_th('project', $order, 'Project'); - print_sort_th('descr', $order, 'Description'); - print_sort_th('owner', $order, 'Owner'); - print_sort_th('age', $order, 'Last Change'); - print "\n" . # for links + print {$output_handler} get_sort_th('project', $order, 'Project'); + print {$output_handler} get_sort_th('descr', $order, 'Description'); + print {$output_handler} get_sort_th('owner', $order, 'Owner'); + print {$output_handler} get_sort_th('age', $order, 'Last Change'); + print {$output_handler} "\n" . # for links "\n"; } my $alternate = 1; @@ -4451,26 +4457,26 @@ sub git_project_list_body { } if ($alternate) { - print "\n"; + print {$output_handler} "\n"; } else { - print "\n"; + print {$output_handler} "\n"; } $alternate ^= 1; if ($check_forks) { - print "\n"; + print {$output_handler} "\n"; } - print "\n" . + print {$output_handler} "\n". "\n" . "\n"; - print "\n" . "\n"; } if (defined $extra) { - print "\n"; + print {$output_handler} "\n"; if ($check_forks) { - print "\n"; + print {$output_handler} "\n"; } - print "\n" . + print {$output_handler} "\n" . "\n"; } - print "
"; + print {$output_handler} ""; if ($pr->{'forks'}) { - print "\n"; - print $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "+"); + print {$output_handler} "\n"; + print {$output_handler} $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "+"); } - print "" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"), - -class => "list"}, esc_html($pr->{'path'})) . "" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"), + -class => "list"}, esc_html($pr->{'path'})) ."" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"), -class => "list", -title => $pr->{'descr_long'}}, esc_html($pr->{'descr'})) . "" . chop_and_escape_str($pr->{'owner'}, 15) . "{'age'}) . "\">" . + print {$output_handler} "{'age'}) . "\">" . (defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . "" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary") . " | " . @@ -4486,14 +4492,14 @@ sub git_project_list_body { "
$extra$extra
\n"; + print {$output_handler} "\n"; } sub git_log_body { @@ -4513,7 +4519,7 @@ sub git_log_body { "$co{'age_string'}" . esc_html($co{'title'}) . $ref, $commit); - print "
\n" . + print {$output_handler} "
\n" . "
\n" . $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " . @@ -4523,16 +4529,16 @@ sub git_log_body { "
\n" . "
\n"; git_print_authorship(\%co, -tag => 'span'); - print "
\n
\n"; + print {$output_handler} "
\n
\n"; - print "
\n"; + print {$output_handler} "
\n"; git_print_log($co{'comment'}, -final_empty_line=> 1); - print "
\n"; + print {$output_handler} "
\n"; } if ($extra) { - print "
\n"; - print "$extra\n"; - print "
\n"; + print {$output_handler} "
\n"; + print {$output_handler} "$extra\n"; + print {$output_handler} "
\n"; } } @@ -4543,41 +4549,41 @@ sub git_shortlog_body { $from = 0 unless defined $from; $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to); - print "\n"; + print {$output_handler} "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my %co = %{$commitlist->[$i]}; my $commit = $co{'id'}; my $ref = format_ref_marker($refs, $commit); if ($alternate) { - print "\n"; + print {$output_handler} "\n"; } else { - print "\n"; + print {$output_handler} "\n"; } $alternate ^= 1; # git_summary() used print "\n" . - print "\n" . + print {$output_handler} "\n" . format_author_html('td', \%co, 10) . "\n" . + print {$output_handler} "\n" . "\n" . + print {$output_handler} "\n" . "\n"; } if (defined $extra) { - print "\n" . + print {$output_handler} "\n" . "\n" . "\n"; } - print "
$co{'age_string'}$co{'age_string_date'}$co{'age_string_date'}"; - print format_subject_html($co{'title'}, $co{'title_short'}, + print {$output_handler} format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref); - print "" . $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " . $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") . " | " . $cgi->a({-href => href(action=>"tree", hash=>$commit, hash_base=>$commit)}, "tree"); my $snapshot_links = format_snapshot_links($commit); if (defined $snapshot_links) { - print " | " . $snapshot_links; + print {$output_handler} " | " . $snapshot_links; } - print "
$extra
\n"; + print {$output_handler} "\n"; } sub git_history_body { @@ -4588,7 +4594,7 @@ sub git_history_body { $from = 0 unless defined $from; $to = $#{$commitlist} unless (defined $to && $to <= $#{$commitlist}); - print "\n"; + print {$output_handler} "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my %co = %{$commitlist->[$i]}; @@ -4600,18 +4606,18 @@ sub git_history_body { my $ref = format_ref_marker($refs, $commit); if ($alternate) { - print "\n"; + print {$output_handler} "\n"; } else { - print "\n"; + print {$output_handler} "\n"; } $alternate ^= 1; - print "\n" . + print {$output_handler} "\n" . # shortlog: format_author_html('td', \%co, 10) format_author_html('td', \%co, 15, 3) . "\n" . + print {$output_handler} "\n" . "\n" . + print {$output_handler} "\n" . "\n"; } if (defined $extra) { - print "\n" . + print {$output_handler} "\n" . "\n" . "\n"; } - print "
$co{'age_string_date'}$co{'age_string_date'}"; # originally git_history used chop_str($co{'title'}, 50) - print format_subject_html($co{'title'}, $co{'title_short'}, + print {$output_handler} format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref); - print "" . $cgi->a({-href => href(action=>$ftype, hash_base=>$commit, file_name=>$file_name)}, $ftype) . " | " . $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff"); @@ -4621,7 +4627,7 @@ sub git_history_body { my $blob_parent = git_get_hash_by_path($commit, $file_name); if (defined $blob_current && defined $blob_parent && $blob_current ne $blob_parent) { - print " | " . + print {$output_handler} " | " . $cgi->a({-href => href(action=>"blobdiff", hash=>$blob_current, hash_parent=>$blob_parent, hash_base=>$hash_base, hash_parent_base=>$commit, @@ -4629,15 +4635,15 @@ sub git_history_body { "diff to current"); } } - print "
$extra
\n"; + print {$output_handler} "\n"; } sub git_tags_body { @@ -4646,7 +4652,7 @@ sub git_tags_body { $from = 0 unless defined $from; $to = $#{$taglist} if (!defined $to || $#{$taglist} < $to); - print "\n"; + print {$output_handler} "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my $entry = $taglist->[$i]; @@ -4657,50 +4663,50 @@ sub git_tags_body { $comment_short = chop_str($comment, 30, 5); } if ($alternate) { - print "\n"; + print {$output_handler} "\n"; } else { - print "\n"; + print {$output_handler} "\n"; } $alternate ^= 1; if (defined $tag{'age'}) { - print "\n"; + print {$output_handler} "\n"; } else { - print "\n"; + print {$output_handler} "\n"; } - print "\n" . "\n" . + print {$output_handler} "\n" . "\n" . + print {$output_handler} "\n" . "\n" . + print {$output_handler} "\n" . ""; } if (defined $extra) { - print "\n" . + print {$output_handler} "\n" . "\n" . "\n"; } - print "
$tag{'age'}$tag{'age'}" . + print {$output_handler} "" . $cgi->a({-href => href(action=>$tag{'reftype'}, hash=>$tag{'refid'}), -class => "list name"}, esc_html($tag{'name'})) . ""; if (defined $comment) { - print format_subject_html($comment, $comment_short, + print {$output_handler} format_subject_html($comment, $comment_short, href(action=>"tag", hash=>$tag{'id'})); } - print ""; if ($tag{'type'} eq "tag") { - print $cgi->a({-href => href(action=>"tag", hash=>$tag{'id'})}, "tag"); + print {$output_handler} $cgi->a({-href => href(action=>"tag", hash=>$tag{'id'})}, "tag"); } else { - print " "; + print {$output_handler} " "; } - print "" . " | " . $cgi->a({-href => href(action=>$tag{'reftype'}, hash=>$tag{'refid'})}, $tag{'reftype'}); if ($tag{'reftype'} eq "commit") { - print " | " . $cgi->a({-href => href(action=>"shortlog", hash=>$tag{'fullname'})}, "shortlog") . + print {$output_handler} " | " . $cgi->a({-href => href(action=>"shortlog", hash=>$tag{'fullname'})}, "shortlog") . " | " . $cgi->a({-href => href(action=>"log", hash=>$tag{'fullname'})}, "log"); } elsif ($tag{'reftype'} eq "blob") { - print " | " . $cgi->a({-href => href(action=>"blob_plain", hash=>$tag{'refid'})}, "raw"); + print {$output_handler} " | " . $cgi->a({-href => href(action=>"blob_plain", hash=>$tag{'refid'})}, "raw"); } - print "
$extra
\n"; + print {$output_handler} "\n"; } sub git_heads_body { @@ -4709,19 +4715,19 @@ sub git_heads_body { $from = 0 unless defined $from; $to = $#{$headlist} if (!defined $to || $#{$headlist} < $to); - print "\n"; + print {$output_handler} "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my $entry = $headlist->[$i]; my %ref = %$entry; my $curr = $ref{'id'} eq $head; if ($alternate) { - print "\n"; + print {$output_handler} "\n"; } else { - print "\n"; + print {$output_handler} "\n"; } $alternate ^= 1; - print "\n" . + print {$output_handler} "\n" . ($curr ? ""; } if (defined $extra) { - print "\n" . + print {$output_handler} "\n" . "\n" . "\n"; } - print "
$ref{'age'}$ref{'age'}" : "") . $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'fullname'}), -class => "list name"},esc_html($ref{'name'})) . @@ -4734,11 +4740,11 @@ sub git_heads_body { "
$extra
\n"; + print {$output_handler} "\n"; } sub git_search_grep_body { @@ -4746,7 +4752,7 @@ sub git_search_grep_body { $from = 0 unless defined $from; $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to); - print "\n"; + print {$output_handler} "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my %co = %{$commitlist->[$i]}; @@ -4755,12 +4761,12 @@ sub git_search_grep_body { } my $commit = $co{'id'}; if ($alternate) { - print "\n"; + print {$output_handler} "\n"; } else { - print "\n"; + print {$output_handler} "\n"; } $alternate ^= 1; - print "\n" . + print {$output_handler} "\n" . format_author_html('td', \%co, 15, 5) . "\n" . + print {$output_handler} "\n" . "\n" . + print {$output_handler} "\n" . "\n"; } if (defined $extra) { - print "\n" . + print {$output_handler} "\n" . "\n" . "\n"; } - print "
$co{'age_string_date'}$co{'age_string_date'}" . $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}), @@ -4780,25 +4786,25 @@ sub git_search_grep_body { $match = esc_html($match); $trail = esc_html($trail); - print "$lead$match$trail
"; + print {$output_handler} "$lead$match$trail
"; } } - print "
" . $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") . " | " . $cgi->a({-href => href(action=>"commitdiff", hash=>$co{'id'})}, "commitdiff") . " | " . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree"); - print "
$extra
\n"; + print {$output_handler} "\n"; } ## ====================================================================== @@ -4818,11 +4824,11 @@ sub git_project_list { git_header_html(); if (-f $home_text) { - print "
\n"; + print {$output_handler} "
\n"; insert_file($home_text); - print "
\n"; + print {$output_handler} "
\n"; } - print $cgi->startform(-method => "get") . + print {$output_handler} $cgi->startform(-method => "get") . "

Search:\n" . $cgi->textfield(-name => "s", -value => $searchtext) . "\n" . "

" . @@ -4852,7 +4858,7 @@ sub git_forks { sub git_project_index { my @projects = git_get_projects_list($project); - print $cgi->header( + print {$output_handler} $cgi->header( -type => 'text/plain', -charset => 'utf-8', -content_disposition => 'inline; filename="index.aux"'); @@ -4869,7 +4875,7 @@ sub git_project_index { $path =~ s/ /\+/g; $owner =~ s/ /\+/g; - print "$path $owner\n"; + print {$output_handler} "$path $owner\n"; } } @@ -4896,12 +4902,12 @@ sub git_summary { git_header_html(); git_print_page_nav('summary','', $head); - print "
 
\n"; - print "\n" . + print {$output_handler} "
 
\n"; + print {$output_handler} "
\n" . "\n" . "\n"; if (defined $cd{'rfc2822'}) { - print "\n"; + print {$output_handler} "\n"; } # use per project git URL list in $projectroot/$project/cloneurl @@ -4911,7 +4917,7 @@ sub git_summary { @url_list = map { "$_/$project" } @git_base_url_list unless @url_list; foreach my $git_url (@url_list) { next unless $git_url; - print "\n"; + print {$output_handler} "\n"; $url_tag = ""; } @@ -4920,23 +4926,23 @@ sub git_summary { if ($show_ctags) { my $ctags = git_get_project_ctags($project); my $cloud = git_populate_project_tagcloud($ctags); - print "\n\n"; + print {$output_handler} "\n\n"; } - print "
description" . esc_html($descr) . "
owner" . esc_html($owner) . "
last change$cd{'rfc2822'}
last change$cd{'rfc2822'}
Content tags:
"; - print "
" unless %$ctags; - print "
Add:
"; - print "
" if %$ctags; - print git_show_project_tagcloud($cloud, 48); - print "
Content tags:
"; + print {$output_handler} "
" unless %$ctags; + print {$output_handler} "
Add:
"; + print {$output_handler} "
" if %$ctags; + print {$output_handler} git_show_project_tagcloud($cloud, 48); + print {$output_handler} "
\n"; + print {$output_handler} "\n"; # If XSS prevention is on, we don't include README.html. # TODO: Allow a readme in some safe format. if (!$prevent_xss && -s "$projectroot/$project/README.html") { - print "
readme
\n" . + print {$output_handler} "
readme
\n" . "
\n"; insert_file("$projectroot/$project/README.html"); - print "\n
\n"; # class="readme" + print {$output_handler} "\n
\n"; # class="readme" } # we need to request one more than 16 (0..15) to check if @@ -4985,7 +4991,7 @@ sub git_tag { } git_print_header_div('commit', esc_html($tag{'name'}), $hash); - print "
\n" . + print {$output_handler} "
\n" . "\n" . "\n" . "\n" . @@ -4997,15 +5003,15 @@ sub git_tag { if (defined($tag{'author'})) { git_print_authorship_rows(\%tag, 'author'); } - print "
object
\n\n" . + print {$output_handler} "\n\n" . "
\n"; - print "
"; + print {$output_handler} "
"; my $comment = $tag{'comment'}; foreach my $line (@$comment) { chomp $line; - print esc_html($line, -nbsp=>1) . "
\n"; + print {$output_handler} esc_html($line, -nbsp=>1) . "
\n"; } - print "
\n"; + print {$output_handler} "
\n"; git_footer_html(); } @@ -5056,21 +5062,23 @@ sub git_blame_common { # incremental blame data returns early if ($format eq 'data') { - print $cgi->header( + print {$output_handler} $cgi->header( -type=>"text/plain", -charset => "utf-8", -status=> "200 OK"); local $| = 1; # output autoflush - print while <$fd>; + while (<$fd>) { + print {$output_handler} $_; + } close $fd - or print "ERROR $!\n"; + or die_error(500, "ERROR $!\n"); - print 'END'; + print {$output_handler} 'END'; if (defined $t0 && gitweb_check_feature('timed')) { - print ' '. + print {$output_handler} ' '. Time::HiRes::tv_interval($t0, [Time::HiRes::gettimeofday()]). ' '.$number_of_git_cmds; } - print "\n"; + print {$output_handler} "\n"; return; } @@ -5103,20 +5111,20 @@ sub git_blame_common { # page body if ($format eq 'incremental') { - print "