[PATCH 5/7] gitweb: Convert output to using indirect file handle

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <<EOF;
+	print {$output_handler} <<EOF;
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
 <html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en-US" lang="en-US">
@@ -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 "<base href=\"".esc_url($base_url)."\" />\n";
+		print {$output_handler} "<base href=\"".esc_url($base_url)."\" />\n";
 	}
 	# print out each stylesheet that exist, providing backwards capability
 	# for those people who defined $stylesheet in a config file
 	if (defined $stylesheet) {
-		print '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'"/>'."\n";
+		print {$output_handler} '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'"/>'."\n";
 	} else {
 		foreach my $stylesheet (@stylesheets) {
 			next unless $stylesheet;
-			print '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'"/>'."\n";
+			print {$output_handler} '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'"/>'."\n";
 		}
 	}
 	if (defined $project) {
@@ -3254,7 +3261,7 @@ EOF
 
 			$href_params{'action'} = $type;
 			$link_attr{'-href'} = href(%href_params);
-			print "<link ".
+			print {$output_handler} "<link ".
 			      "rel=\"$link_attr{'-rel'}\" ".
 			      "title=\"$link_attr{'-title'}\" ".
 			      "href=\"$link_attr{'-href'}\" ".
@@ -3264,7 +3271,7 @@ EOF
 			$href_params{'extra_options'} = '--no-merges';
 			$link_attr{'-href'} = href(%href_params);
 			$link_attr{'-title'} .= ' (no merges)';
-			print "<link ".
+			print {$output_handler} "<link ".
 			      "rel=\"$link_attr{'-rel'}\" ".
 			      "title=\"$link_attr{'-title'}\" ".
 			      "href=\"$link_attr{'-href'}\" ".
@@ -3273,37 +3280,37 @@ EOF
 		}
 
 	} else {
-		printf('<link rel="alternate" title="%s projects list" '.
+		printf( {$output_handler} '<link rel="alternate" title="%s projects list" '.
 		       'href="%s" type="text/plain; charset=utf-8" />'."\n",
 		       $site_name, href(project=>undef, action=>"project_index"));
-		printf('<link rel="alternate" title="%s projects feeds" '.
+		printf( {$output_handler} '<link rel="alternate" title="%s projects feeds" '.
 		       'href="%s" type="text/x-opml" />'."\n",
 		       $site_name, href(project=>undef, action=>"opml"));
 	}
 	if (defined $favicon) {
-		print qq(<link rel="shortcut icon" href="$favicon" type="image/png" />\n);
+		print {$output_handler} qq(<link rel="shortcut icon" href="$favicon" type="image/png" />\n);
 	}
 
-	print "</head>\n" .
+	print {$output_handler} "</head>\n" .
 	      "<body>\n";
 
 	if (-f $site_header) {
 		insert_file($site_header);
 	}
 
-	print "<div class=\"page_header\">\n" .
+	print {$output_handler} "<div class=\"page_header\">\n" .
 	      $cgi->a({-href => esc_url($logo_url),
 	               -title => $logo_label},
 	              qq(<img src="$logo" width="72" height="27" alt="git" class="logo"/>));
-	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 "</div>\n";
+	print {$output_handler} "</div>\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) .
 		      "<div class=\"search\">\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 "<div class=\"page_footer\">\n";
+	print {$output_handler} "<div class=\"page_footer\">\n";
 	if (defined $project) {
 		my $descr = git_get_project_description($project);
 		if (defined $descr) {
-			print "<div class=\"page_footer_text\">" . esc_html($descr) . "</div>\n";
+			print {$output_handler} "<div class=\"page_footer_text\">" . esc_html($descr) . "</div>\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 "</div>\n"; # class="page_footer"
+	print {$output_handler} "</div>\n"; # class="page_footer"
 
 	if (defined $t0 && gitweb_check_feature('timed')) {
-		print "<div id=\"generating_info\">\n";
-		print 'This page took '.
+		print {$output_handler} "<div id=\"generating_info\">\n";
+		print {$output_handler} 'This page took '.
 		      '<span id="generating_time" class="time_span">'.
 		      Time::HiRes::tv_interval($t0, [Time::HiRes::gettimeofday()]).
 		      ' seconds </span>'.
@@ -3385,26 +3392,26 @@ sub git_footer_html {
 		      $number_of_git_cmds.
 		      '</span> git commands '.
 		      " to generate.\n";
-		print "</div>\n"; # class="page_footer"
+		print {$output_handler} "</div>\n"; # class="page_footer"
 	}
 
 	if (-f $site_footer) {
 		insert_file($site_footer);
 	}
 
-	print qq!<script type="text/javascript" src="$javascript"></script>\n!;
+	print {$output_handler} qq!<script type="text/javascript" src="$javascript"></script>\n!;
 	if ($action eq 'blame_incremental') {
-		print qq!<script type="text/javascript">\n!.
+		print {$output_handler} qq!<script type="text/javascript">\n!.
 		      qq!startBlame("!. href(action=>"blame_data", -replay=>1) .qq!",\n!.
 		      qq!           "!. href() .qq!");\n!.
 		      qq!</script>\n!;
 	} elsif (gitweb_check_feature('javascript-actions')) {
-		print qq!<script type="text/javascript">\n!.
+		print {$output_handler} qq!<script type="text/javascript">\n!.
 		      qq!window.onload = fixLinks;\n!.
 		      qq!</script>\n!;
 	}
 
-	print "</body>\n" .
+	print {$output_handler} "</body>\n" .
 	      "</html>";
 }
 
@@ -3488,12 +3495,12 @@ sub git_print_page_nav {
 		$arg{$label}{'_href'} = $link;
 	}
 
-	print "<div class=\"page_nav\">\n" .
+	print {$output_handler} "<div class=\"page_nav\">\n" .
 		(join " | ",
 		 map { $_ eq $current ?
 		       $_ : $cgi->a({-href => ($arg{$_}{_href} ? $arg{$_}{_href} : href(%{$arg{$_}}))}, "$_")
 		 } @navs);
-	print "<br/>\n$extra<br/>\n" .
+	print {$output_handler} "<br/>\n$extra<br/>\n" .
 	      "</div>\n";
 }
 
@@ -3534,7 +3541,7 @@ sub git_print_header_div {
 	$args{'hash'} = $hash if $hash;
 	$args{'hash_base'} = $hash_base if $hash_base;
 
-	print "<div class=\"header\">\n" .
+	print {$output_handler} "<div class=\"header\">\n" .
 	      $cgi->a({-href => href(%args), -class => "title"},
 	      $title ? $title : $action) .
 	      "\n</div>\n";
@@ -3543,10 +3550,10 @@ sub git_print_header_div {
 sub print_local_time {
 	my %date = @_;
 	if ($date{'hour_local'} < 6) {
-		printf(" (<span class=\"atnight\">%02d:%02d</span> %s)",
+		printf({$output_handler} " (<span class=\"atnight\">%02d:%02d</span> %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)
 		  . "</$tag>\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 "<tr><td>$who</td><td>" .
+		print {$output_handler} "<tr><td>$who</td><td>" .
 		      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 {
 		      "</td></tr>\n" .
 		      "<tr>" .
 		      "<td></td><td> $wd{'rfc2822'}";
-		print_local_time(%wd);
-		print "</td>" .
+		print {$output_handler} get_local_time(%wd);
+		print {$output_handler} "</td>" .
 		      "</tr>\n";
 	}
 }
@@ -3600,11 +3607,10 @@ sub git_print_page_path {
 	my $type = shift;
 	my $hb = shift;
 
-
-	print "<div class=\"page_path\">";
-	print $cgi->a({-href => href(action=>"tree", hash_base=>$hb),
+	print {$output_handler} "<div class=\"page_path\">";
+	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 "<br/></div>\n";
+	print {$output_handler} "<br/></div>\n";
 }
 
 sub git_print_log {
@@ -3654,7 +3660,7 @@ sub git_print_log {
 			$signoff = 1;
 			$empty = 0;
 			if (! $opts{'-remove_signoff'}) {
-				print "<span class=\"signoff\">" . esc_html($line) . "</span><br/>\n";
+				print {$output_handler} "<span class=\"signoff\">" . esc_html($line) . "</span><br/>\n";
 				next;
 			} else {
 				# remove signoff lines
@@ -3673,12 +3679,12 @@ sub git_print_log {
 			$empty = 0;
 		}
 
-		print format_log_line_html($line) . "<br/>\n";
+		print {$output_handler} format_log_line_html($line) . "<br/>\n";
 	}
 
 	if ($opts{'-final_empty_line'}) {
 		# end with single empty line
-		print "<br/>\n" unless $empty;
+		print {$output_handler} "<br/>\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 "<td class=\"mode\">" . mode_str($t->{'mode'}) . "</td>\n";
+	print {$output_handler} "<td class=\"mode\">" . mode_str($t->{'mode'}) . "</td>\n";
 	if (exists $t->{'size'}) {
-		print "<td class=\"size\">$t->{'size'}</td>\n";
+		print {$output_handler} "<td class=\"size\">$t->{'size'}</td>\n";
 	}
 	if ($t->{'type'} eq "blob") {
-		print "<td class=\"list\">" .
+		print {$output_handler} "<td class=\"list\">" .
 			$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 "</td>\n";
-		print "<td class=\"link\">";
-		print $cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'},
+		print {$output_handler} "</td>\n";
+		print {$output_handler} "<td class=\"link\">";
+		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 "</td>\n";
+		print {$output_handler} "</td>\n";
 
 	} elsif ($t->{'type'} eq "tree") {
-		print "<td class=\"list\">";
-		print $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'},
+		print {$output_handler} "<td class=\"list\">";
+		print {$output_handler} $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'},
 		                             file_name=>"$basedir$t->{'name'}",
 		                             %base_key)},
 		              esc_path($t->{'name'}));
-		print "</td>\n";
-		print "<td class=\"link\">";
-		print $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'},
+		print {$output_handler} "</td>\n";
+		print {$output_handler} "<td class=\"link\">";
+		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 "</td>\n";
+		print {$output_handler} "</td>\n";
 	} else {
 		# unknown object: we can only present history for it
 		# (this includes 'commit' object, i.e. submodule support)
-		print "<td class=\"list\">" .
+		print {$output_handler} "<td class=\"list\">" .
 		      esc_path($t->{'name'}) .
 		      "</td>\n";
-		print "<td class=\"link\">";
+		print {$output_handler} "<td class=\"link\">";
 		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 "</td>\n";
+		print {$output_handler} "</td>\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 "<div class=\"list_head\">\n";
+	print {$output_handler} "<div class=\"list_head\">\n";
 	if ($#{$difftree} > 10) {
-		print(($#{$difftree} + 1) . " files changed:\n");
+		print {$output_handler} (($#{$difftree} + 1) . " files changed:\n");
 	}
-	print "</div>\n";
+	print {$output_handler} "</div>\n";
 
-	print "<table class=\"" .
+	print {$output_handler} "<table class=\"" .
 	      (@parents > 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 "<thead><tr>\n" .
+		print {$output_handler} "<thead><tr>\n" .
 		       "<th></th><th></th>\n"; # filename, patchN link
 		for (my $i = 0; $i < @parents; $i++) {
 			my $par = $parents[$i];
-			print "<th>" .
+			print {$output_handler} "<th>" .
 			      $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) .
 			      "&nbsp;</th>\n";
 		}
-		print "</tr></thead>\n<tbody>\n";
+		print {$output_handler} "</tr></thead>\n<tbody>\n";
 	}
 
 	my $alternate = 1;
@@ -3911,9 +3917,9 @@ sub git_difftree_body {
 		my $diff = parsed_difftree_line($line);
 
 		if ($alternate) {
-			print "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
 
@@ -3924,14 +3930,14 @@ sub git_difftree_body {
 
 			if (!is_deleted($diff)) {
 				# file exists in the result (child) commit
-				print "<td>" .
+				print {$output_handler} "<td>" .
 				      $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'})) .
 				      "</td>\n";
 			} else {
-				print "<td>" .
+				print {$output_handler} "<td>" .
 				      esc_path($diff->{'to_file'}) .
 				      "</td>\n";
 			}
@@ -3939,7 +3945,7 @@ sub git_difftree_body {
 			if ($action eq 'commitdiff') {
 				# link to patch
 				$patchno++;
-				print "<td class=\"link\">" .
+				print {$output_handler} "<td class=\"link\">" .
 				      $cgi->a({-href => "#patch$patchno"}, "patch") .
 				      " | " .
 				      "</td>\n";
@@ -3957,9 +3963,9 @@ sub git_difftree_body {
 				$not_deleted ||= ($status ne 'D');
 
 				if ($status eq 'A') {
-					print "<td  class=\"link\" align=\"right\"> | </td>\n";
+					print {$output_handler} "<td  class=\"link\" align=\"right\"> | </td>\n";
 				} elsif ($status eq 'D') {
-					print "<td class=\"link\">" .
+					print {$output_handler} "<td class=\"link\">" .
 					      $cgi->a({-href => href(action=>"blob",
 					                             hash_base=>$hash,
 					                             hash=>$from_hash,
@@ -3968,11 +3974,11 @@ sub git_difftree_body {
 					      " | </td>\n";
 				} else {
 					if ($diff->{'to_id'} eq $from_hash) {
-						print "<td class=\"link nochange\">";
+						print {$output_handler} "<td class=\"link nochange\">";
 					} else {
-						print "<td class=\"link\">";
+						print {$output_handler} "<td class=\"link\">";
 					}
-					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 "<td class=\"link\">";
+			print {$output_handler} "<td class=\"link\">";
 			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 "</td>\n";
+			print {$output_handler} "</td>\n";
 
-			print "</tr>\n";
+			print {$output_handler} "</tr>\n";
 			next; # instead of 'else' clause, to avoid extra indent
 		}
 		# else ordinary diff
@@ -4027,51 +4033,51 @@ sub git_difftree_body {
 			my $mode_chng = "<span class=\"file_status new\">[new $to_file_type";
 			$mode_chng   .= " with mode: $to_mode_str" if $to_mode_str;
 			$mode_chng   .= "]</span>";
-			print "<td>";
-			print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'},
+			print {$output_handler} "<td>";
+			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 "</td>\n";
-			print "<td>$mode_chng</td>\n";
-			print "<td class=\"link\">";
+			print {$output_handler} "</td>\n";
+			print {$output_handler} "<td>$mode_chng</td>\n";
+			print {$output_handler} "<td class=\"link\">";
 			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 "</td>\n";
+			print {$output_handler} "</td>\n";
 
 		} elsif ($diff->{'status'} eq "D") { # deleted
 			my $mode_chng = "<span class=\"file_status deleted\">[deleted $from_file_type]</span>";
-			print "<td>";
-			print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'},
+			print {$output_handler} "<td>";
+			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 "</td>\n";
-			print "<td>$mode_chng</td>\n";
-			print "<td class=\"link\">";
+			print {$output_handler} "</td>\n";
+			print {$output_handler} "<td>$mode_chng</td>\n";
+			print {$output_handler} "<td class=\"link\">";
 			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 "</td>\n";
+			print {$output_handler} "</td>\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 .= "]</span>\n";
 			}
-			print "<td>";
-			print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'},
+			print {$output_handler} "<td>";
+			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 "</td>\n";
-			print "<td>$mode_chnge</td>\n";
-			print "<td class=\"link\">";
+			print {$output_handler} "</td>\n";
+			print {$output_handler} "<td>$mode_chnge</td>\n";
+			print {$output_handler} "<td class=\"link\">";
 			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 "</td>\n";
+			print {$output_handler} "</td>\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 "<td>" .
+			print {$output_handler} "<td>" .
 			      $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'})) . "</td>\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 "</td>\n";
+			print {$output_handler} "</td>\n";
 
 		} # we should not encounter Unmerged (U) or Unknown (X) status
-		print "</tr>\n";
+		print {$output_handler} "</tr>\n";
 	}
-	print "</tbody>" if $has_header;
-	print "</table>\n";
+	print {$output_handler} "</tbody>" if $has_header;
+	print {$output_handler} "</table>\n";
 }
 
 sub git_patchset_body {
@@ -4187,7 +4193,7 @@ sub git_patchset_body {
 	my $to_name;
 	my (%from, %to);
 
-	print "<div class=\"patchset\">\n";
+	print {$output_handler} "<div class=\"patchset\">\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 "<div class=\"patch cont\">\n";
+			print {$output_handler} "<div class=\"patch cont\">\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 "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n" .
+					print {$output_handler} "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n" .
 					      format_diff_cc_simplified($diffinfo, @hash_parents) .
 					      "</div>\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 "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n";
+			print {$output_handler} "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\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 "<div class=\"diff extended_header\">\n";
+		print {$output_handler} "<div class=\"diff extended_header\">\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 "</div>\n"; # class="diff extended_header"
+		print {$output_handler} "</div>\n"; # class="diff extended_header"
 
 		# from-file/to-file diff header
 		if (! $patch_line) {
-			print "</div>\n"; # class="patch"
+			print {$output_handler} "</div>\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 "</div>\n"; # class="patch"
+		print {$output_handler} "</div>\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 "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n" .
+		print {$output_handler} "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n" .
 		      format_diff_cc_simplified($diffinfo, @hash_parents) .
 		      "</div>\n";  # class="patch"
 
@@ -4317,13 +4323,13 @@ sub git_patchset_body {
 
 	if ($patch_number == 0) {
 		if (@hash_parents > 1) {
-			print "<div class=\"diff nodifferences\">Trivial merge</div>\n";
+			print {$output_handler} "<div class=\"diff nodifferences\">Trivial merge</div>\n";
 		} else {
-			print "<div class=\"diff nodifferences\">No differences found</div>\n";
+			print {$output_handler} "<div class=\"diff nodifferences\">No differences found</div>\n";
 		}
 	}
 
-	print "</div>\n"; # class="patchset"
+	print {$output_handler} "</div>\n"; # class="patchset"
 }
 
 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@@ -4376,9 +4382,9 @@ sub print_sort_th {
 	$header ||= ucfirst($name);
 
 	if ($order eq $name) {
-		print "<th>$header</th>\n";
+		print {$output_handler} "<th>$header</th>\n";
 	} else {
-		print "<th>" .
+		print {$output_handler} "<th>" .
 		      $cgi->a({-href => href(-replay=>1, order=>$name),
 		               -class => "header"}, $header) .
 		      "</th>\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 "<table class=\"project_list\">\n";
+	print {$output_handler} "<table class=\"project_list\">\n";
 	unless ($no_header) {
-		print "<tr>\n";
+		print {$output_handler} "<tr>\n";
 		if ($check_forks) {
-			print "<th></th>\n";
+			print {$output_handler} "<th></th>\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 "<th></th>\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} "<th></th>\n" . # for links
 		      "</tr>\n";
 	}
 	my $alternate = 1;
@@ -4451,26 +4457,26 @@ sub git_project_list_body {
 		}
 
 		if ($alternate) {
-			print "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
 		if ($check_forks) {
-			print "<td>";
+			print {$output_handler} "<td>";
 			if ($pr->{'forks'}) {
-				print "<!-- $pr->{'forks'} -->\n";
-				print $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "+");
+				print {$output_handler} "<!-- $pr->{'forks'} -->\n";
+				print {$output_handler} $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "+");
 			}
-			print "</td>\n";
+			print {$output_handler} "</td>\n";
 		}
-		print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
-		                        -class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
+		print {$output_handler} "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
+		                        -class => "list"}, esc_html($pr->{'path'})) ."</td>\n".
 		      "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
 		                        -class => "list", -title => $pr->{'descr_long'}},
 		                        esc_html($pr->{'descr'})) . "</td>\n" .
 		      "<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";
-		print "<td class=\"". age_class($pr->{'age'}) . "\">" .
+		print {$output_handler} "<td class=\"". age_class($pr->{'age'}) . "\">" .
 		      (defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . "</td>\n" .
 		      "<td class=\"link\">" .
 		      $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary")   . " | " .
@@ -4486,14 +4492,14 @@ sub git_project_list_body {
 		      "</tr>\n";
 	}
 	if (defined $extra) {
-		print "<tr>\n";
+		print {$output_handler} "<tr>\n";
 		if ($check_forks) {
-			print "<td></td>\n";
+			print {$output_handler} "<td></td>\n";
 		}
-		print "<td colspan=\"5\">$extra</td>\n" .
+		print {$output_handler} "<td colspan=\"5\">$extra</td>\n" .
 		      "</tr>\n";
 	}
-	print "</table>\n";
+	print {$output_handler} "</table>\n";
 }
 
 sub git_log_body {
@@ -4513,7 +4519,7 @@ sub git_log_body {
 		               "<span class=\"age\">$co{'age_string'}</span>" .
 		               esc_html($co{'title'}) . $ref,
 		               $commit);
-		print "<div class=\"title_text\">\n" .
+		print {$output_handler} "<div class=\"title_text\">\n" .
 		      "<div class=\"log_link\">\n" .
 		      $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") .
 		      " | " .
@@ -4523,16 +4529,16 @@ sub git_log_body {
 		      "<br/>\n" .
 		      "</div>\n";
 		      git_print_authorship(\%co, -tag => 'span');
-		      print "<br/>\n</div>\n";
+		      print {$output_handler} "<br/>\n</div>\n";
 
-		print "<div class=\"log_body\">\n";
+		print {$output_handler} "<div class=\"log_body\">\n";
 		git_print_log($co{'comment'}, -final_empty_line=> 1);
-		print "</div>\n";
+		print {$output_handler} "</div>\n";
 	}
 	if ($extra) {
-		print "<div class=\"page_nav\">\n";
-		print "$extra\n";
-		print "</div>\n";
+		print {$output_handler} "<div class=\"page_nav\">\n";
+		print {$output_handler} "$extra\n";
+		print {$output_handler} "</div>\n";
 	}
 }
 
@@ -4543,41 +4549,41 @@ sub git_shortlog_body {
 	$from = 0 unless defined $from;
 	$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
 
-	print "<table class=\"shortlog\">\n";
+	print {$output_handler} "<table class=\"shortlog\">\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 "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
 		# git_summary() used print "<td><i>$co{'age_string'}</i></td>\n" .
-		print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+		print {$output_handler} "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
 		      format_author_html('td', \%co, 10) . "<td>";
-		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 "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "<td class=\"link\">" .
 		      $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 "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "</tr>\n";
 	}
 	if (defined $extra) {
-		print "<tr>\n" .
+		print {$output_handler} "<tr>\n" .
 		      "<td colspan=\"4\">$extra</td>\n" .
 		      "</tr>\n";
 	}
-	print "</table>\n";
+	print {$output_handler} "</table>\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 "<table class=\"history\">\n";
+	print {$output_handler} "<table class=\"history\">\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 "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
-		print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+		print {$output_handler} "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
 	# shortlog:   format_author_html('td', \%co, 10)
 		      format_author_html('td', \%co, 15, 3) . "<td>";
 		# 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 "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "<td class=\"link\">" .
 		      $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 "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "</tr>\n";
 	}
 	if (defined $extra) {
-		print "<tr>\n" .
+		print {$output_handler} "<tr>\n" .
 		      "<td colspan=\"4\">$extra</td>\n" .
 		      "</tr>\n";
 	}
-	print "</table>\n";
+	print {$output_handler} "</table>\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 "<table class=\"tags\">\n";
+	print {$output_handler} "<table class=\"tags\">\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 "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
 		if (defined $tag{'age'}) {
-			print "<td><i>$tag{'age'}</i></td>\n";
+			print {$output_handler} "<td><i>$tag{'age'}</i></td>\n";
 		} else {
-			print "<td></td>\n";
+			print {$output_handler} "<td></td>\n";
 		}
-		print "<td>" .
+		print {$output_handler} "<td>" .
 		      $cgi->a({-href => href(action=>$tag{'reftype'}, hash=>$tag{'refid'}),
 		               -class => "list name"}, esc_html($tag{'name'})) .
 		      "</td>\n" .
 		      "<td>";
 		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 "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "<td class=\"selflink\">";
 		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 "&nbsp;";
+			print {$output_handler} "&nbsp;";
 		}
-		print "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "<td class=\"link\">" . " | " .
 		      $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 "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "</tr>";
 	}
 	if (defined $extra) {
-		print "<tr>\n" .
+		print {$output_handler} "<tr>\n" .
 		      "<td colspan=\"5\">$extra</td>\n" .
 		      "</tr>\n";
 	}
-	print "</table>\n";
+	print {$output_handler} "</table>\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 "<table class=\"heads\">\n";
+	print {$output_handler} "<table class=\"heads\">\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 "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
-		print "<td><i>$ref{'age'}</i></td>\n" .
+		print {$output_handler} "<td><i>$ref{'age'}</i></td>\n" .
 		      ($curr ? "<td class=\"current_head\">" : "<td>") .
 		      $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'fullname'}),
 		               -class => "list name"},esc_html($ref{'name'})) .
@@ -4734,11 +4740,11 @@ sub git_heads_body {
 		      "</tr>";
 	}
 	if (defined $extra) {
-		print "<tr>\n" .
+		print {$output_handler} "<tr>\n" .
 		      "<td colspan=\"3\">$extra</td>\n" .
 		      "</tr>\n";
 	}
-	print "</table>\n";
+	print {$output_handler} "</table>\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 "<table class=\"commit_search\">\n";
+	print {$output_handler} "<table class=\"commit_search\">\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 "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
-		print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+		print {$output_handler} "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
 		      format_author_html('td', \%co, 15, 5) .
 		      "<td>" .
 		      $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<span class=\"match\">$match</span>$trail<br />";
+				print {$output_handler} "$lead<span class=\"match\">$match</span>$trail<br />";
 			}
 		}
-		print "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "<td class=\"link\">" .
 		      $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 "</td>\n" .
+		print {$output_handler} "</td>\n" .
 		      "</tr>\n";
 	}
 	if (defined $extra) {
-		print "<tr>\n" .
+		print {$output_handler} "<tr>\n" .
 		      "<td colspan=\"3\">$extra</td>\n" .
 		      "</tr>\n";
 	}
-	print "</table>\n";
+	print {$output_handler} "</table>\n";
 }
 
 ## ======================================================================
@@ -4818,11 +4824,11 @@ sub git_project_list {
 
 	git_header_html();
 	if (-f $home_text) {
-		print "<div class=\"index_include\">\n";
+		print {$output_handler} "<div class=\"index_include\">\n";
 		insert_file($home_text);
-		print "</div>\n";
+		print {$output_handler} "</div>\n";
 	}
-	print $cgi->startform(-method => "get") .
+	print {$output_handler} $cgi->startform(-method => "get") .
 	      "<p class=\"projsearch\">Search:\n" .
 	      $cgi->textfield(-name => "s", -value => $searchtext) . "\n" .
 	      "</p>" .
@@ -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 "<div class=\"title\">&nbsp;</div>\n";
-	print "<table class=\"projects_list\">\n" .
+	print {$output_handler} "<div class=\"title\">&nbsp;</div>\n";
+	print {$output_handler} "<table class=\"projects_list\">\n" .
 	      "<tr id=\"metadata_desc\"><td>description</td><td>" . esc_html($descr) . "</td></tr>\n" .
 	      "<tr id=\"metadata_owner\"><td>owner</td><td>" . esc_html($owner) . "</td></tr>\n";
 	if (defined $cd{'rfc2822'}) {
-		print "<tr id=\"metadata_lchange\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\n";
+		print {$output_handler} "<tr id=\"metadata_lchange\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\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 "<tr class=\"metadata_url\"><td>$url_tag</td><td>$git_url</td></tr>\n";
+		print {$output_handler} "<tr class=\"metadata_url\"><td>$url_tag</td><td>$git_url</td></tr>\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 "<tr id=\"metadata_ctags\"><td>Content tags:<br />";
-		print "</td>\n<td>" unless %$ctags;
-		print "<form action=\"$show_ctags\" method=\"post\"><input type=\"hidden\" name=\"p\" value=\"$project\" />Add: <input type=\"text\" name=\"t\" size=\"8\" /></form>";
-		print "</td>\n<td>" if %$ctags;
-		print git_show_project_tagcloud($cloud, 48);
-		print "</td></tr>";
+		print {$output_handler} "<tr id=\"metadata_ctags\"><td>Content tags:<br />";
+		print {$output_handler} "</td>\n<td>" unless %$ctags;
+		print {$output_handler} "<form action=\"$show_ctags\" method=\"post\"><input type=\"hidden\" name=\"p\" value=\"$project\" />Add: <input type=\"text\" name=\"t\" size=\"8\" /></form>";
+		print {$output_handler} "</td>\n<td>" if %$ctags;
+		print {$output_handler} git_show_project_tagcloud($cloud, 48);
+		print {$output_handler} "</td></tr>";
 	}
 
-	print "</table>\n";
+	print {$output_handler} "</table>\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 "<div class=\"title\">readme</div>\n" .
+		print {$output_handler} "<div class=\"title\">readme</div>\n" .
 		      "<div class=\"readme\">\n";
 		insert_file("$projectroot/$project/README.html");
-		print "\n</div>\n"; # class="readme"
+		print {$output_handler} "\n</div>\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 "<div class=\"title_text\">\n" .
+	print {$output_handler} "<div class=\"title_text\">\n" .
 	      "<table class=\"object_header\">\n" .
 	      "<tr>\n" .
 	      "<td>object</td>\n" .
@@ -4997,15 +5003,15 @@ sub git_tag {
 	if (defined($tag{'author'})) {
 		git_print_authorship_rows(\%tag, 'author');
 	}
-	print "</table>\n\n" .
+	print {$output_handler} "</table>\n\n" .
 	      "</div>\n";
-	print "<div class=\"page_body\">";
+	print {$output_handler} "<div class=\"page_body\">";
 	my $comment = $tag{'comment'};
 	foreach my $line (@$comment) {
 		chomp $line;
-		print esc_html($line, -nbsp=>1) . "<br/>\n";
+		print {$output_handler} esc_html($line, -nbsp=>1) . "<br/>\n";
 	}
-	print "</div>\n";
+	print {$output_handler} "</div>\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 "<noscript>\n<div class=\"error\"><center><b>\n".
+		print {$output_handler} "<noscript>\n<div class=\"error\"><center><b>\n".
 		      "This page requires JavaScript to run.\n Use ".
 		      $cgi->a({-href => href(action=>'blame',javascript=>0,-replay=>1)},
 		              'this page').
 		      " instead.\n".
 		      "</b></center></div>\n</noscript>\n";
 
-		print qq!<div id="progress_bar" style="width: 100%; background-color: yellow"></div>\n!;
+		print {$output_handler} qq!<div id="progress_bar" style="width: 100%; background-color: yellow"></div>\n!;
 	}
 
-	print qq!<div class="page_body">\n!;
-	print qq!<div id="progress_info">... / ...</div>\n!
+	print {$output_handler} qq!<div class="page_body">\n!;
+	print {$output_handler} qq!<div id="progress_info">... / ...</div>\n!
 		if ($format eq 'incremental');
-	print qq!<table id="blame_table" class="blame" width="100%">\n!.
+	print {$output_handler} qq!<table id="blame_table" class="blame" width="100%">\n!.
 	      #qq!<col width="5.5em" /><col width="2.5em" /><col width="*" />\n!.
 	      qq!<thead>\n!.
 	      qq!<tr><th>Commit</th><th>Line</th><th>Data</th></tr>\n!.
@@ -5137,12 +5145,12 @@ sub git_blame_common {
 			chomp $line;
 			$linenr++;
 
-			print qq!<tr id="l$linenr" class="$color_class">!.
+			print {$output_handler} qq!<tr id="l$linenr" class="$color_class">!.
 			      qq!<td class="sha1"><a href=""> </a></td>!.
 			      qq!<td class="linenr">!.
 			      qq!<a class="linenr" href="">$linenr</a></td>!;
-			print qq!<td class="pre">! . esc_html($line) . "</td>\n";
-			print qq!</tr>\n!;
+			print {$output_handler} qq!<td class="pre">! . esc_html($line) . "</td>\n";
+			print {$output_handler} qq!</tr>\n!;
 		}
 
 	} else { # porcelain, i.e. ordinary blame
@@ -5183,25 +5191,25 @@ sub git_blame_common {
 			$tr_class .= ' boundary' if (exists $meta->{'boundary'});
 			$tr_class .= ' no-previous' if ($meta->{'nprevious'} == 0);
 			$tr_class .= ' multiple-previous' if ($meta->{'nprevious'} > 1);
-			print "<tr id=\"l$lineno\" class=\"$tr_class\">\n";
+			print {$output_handler} "<tr id=\"l$lineno\" class=\"$tr_class\">\n";
 			if ($group_size) {
-				print "<td class=\"sha1\"";
-				print " title=\"". esc_html($author) . ", $date\"";
-				print " rowspan=\"$group_size\"" if ($group_size > 1);
-				print ">";
-				print $cgi->a({-href => href(action=>"commit",
+				print {$output_handler} "<td class=\"sha1\"";
+				print {$output_handler} " title=\"". esc_html($author) . ", $date\"";
+				print {$output_handler} " rowspan=\"$group_size\"" if ($group_size > 1);
+				print {$output_handler} ">";
+				print {$output_handler} $cgi->a({-href => href(action=>"commit",
 				                             hash=>$full_rev,
 				                             file_name=>$file_name)},
 				              esc_html($short_rev));
 				if ($group_size >= 2) {
 					my @author_initials = ($author =~ /\b([[:upper:]])\B/g);
 					if (@author_initials) {
-						print "<br />" .
+						print {$output_handler} "<br />" .
 						      esc_html(join('', @author_initials));
 						#           or join('.', ...)
 					}
 				}
-				print "</td>\n";
+				print {$output_handler} "</td>\n";
 			}
 			# 'previous' <sha1 of parent commit> <filename at commit>
 			if (exists $meta->{'previous'} &&
@@ -5218,23 +5226,23 @@ sub git_blame_common {
 			my $blamed = href(action => 'blame',
 			                  file_name => $linenr_filename,
 			                  hash_base => $linenr_commit);
-			print "<td class=\"linenr\">";
-			print $cgi->a({ -href => "$blamed#l$orig_lineno",
+			print {$output_handler} "<td class=\"linenr\">";
+			print {$output_handler} $cgi->a({ -href => "$blamed#l$orig_lineno",
 			                -class => "linenr" },
 			              esc_html($lineno));
-			print "</td>";
-			print "<td class=\"pre\">" . esc_html($data) . "</td>\n";
-			print "</tr>\n";
+			print {$output_handler} "</td>";
+			print {$output_handler} "<td class=\"pre\">" . esc_html($data) . "</td>\n";
+			print {$output_handler} "</tr>\n";
 		} # end while
 
 	}
 
 	# footer
-	print "</tbody>\n".
+	print {$output_handler} "</tbody>\n".
 	      "</table>\n"; # class="blame"
-	print "</div>\n";   # class="blame_body"
+	print {$output_handler} "</div>\n";   # class="blame_body"
 	close $fd
-		or print "Reading blob failed\n";
+		or print {$output_handler} "Reading blob failed\n";
 
 	git_footer_html();
 }
@@ -5317,16 +5325,17 @@ sub git_blob_plain {
 	my $sandbox = $prevent_xss &&
 		$type !~ m!^(?:text/plain|image/(?:gif|png|jpeg))$!;
 
-	print $cgi->header(
+	print {$output_handler} $cgi->header(
 		-type => $type,
 		-expires => $expires,
 		-content_disposition =>
 			($sandbox ? 'attachment' : 'inline')
 			. '; filename="' . $save_as . '"');
 	local $/ = undef;
-	binmode STDOUT, ':raw';
-	print <$fd>;
-	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
+
+	binmode $output_handler_bin, ':raw';
+	print {$output_handler_bin} <$fd>;
+	binmode $output_handler_bin, ':utf8'; # as set at the beginning of gitweb.cgi
 	close $fd;
 }
 
@@ -5385,18 +5394,18 @@ sub git_blob {
 		git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
 		git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
 	} else {
-		print "<div class=\"page_nav\">\n" .
+		print {$output_handler} "<div class=\"page_nav\">\n" .
 		      "<br/><br/></div>\n" .
 		      "<div class=\"title\">$hash</div>\n";
 	}
 	git_print_page_path($file_name, "blob", $hash_base);
-	print "<div class=\"page_body\">\n";
+	print {$output_handler} "<div class=\"page_body\">\n";
 	if ($mimetype =~ m!^image/!) {
-		print qq!<img type="$mimetype"!;
+		print {$output_handler} qq!<img type="$mimetype"!;
 		if ($file_name) {
-			print qq! alt="$file_name" title="$file_name"!;
+			print {$output_handler} qq! alt="$file_name" title="$file_name"!;
 		}
-		print qq! src="! .
+		print {$output_handler} qq! src="! .
 		      href(action=>"blob_plain", hash=>$hash,
 		           hash_base=>$hash_base, file_name=>$file_name) .
 		      qq!" />\n!;
@@ -5406,14 +5415,14 @@ sub git_blob {
 			chomp $line;
 			$nr++;
 			$line = untabify($line);
-			printf "<div class=\"pre\"><a id=\"l%i\" href=\"" . href(-replay => 1)
+			printf {$output_handler} "<div class=\"pre\"><a id=\"l%i\" href=\"" . href(-replay => 1)
 				. "#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
 			       $nr, $nr, $nr, esc_html($line, -nbsp=>1);
 		}
 	}
 	close $fd
-		or print "Reading blob failed.\n";
-	print "</div>";
+		or print {$output_handler} "Reading blob failed.\n";
+	print {$output_handler} "</div>";
 	git_footer_html();
 }
 
@@ -5468,9 +5477,9 @@ sub git_tree {
 		git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base);
 	} else {
 		undef $hash_base;
-		print "<div class=\"page_nav\">\n";
-		print "<br/><br/></div>\n";
-		print "<div class=\"title\">$hash</div>\n";
+		print {$output_handler} "<div class=\"page_nav\">\n";
+		print {$output_handler} "<br/><br/></div>\n";
+		print {$output_handler} "<div class=\"title\">$hash</div>\n";
 	}
 	if (defined $file_name) {
 		$basedir = $file_name;
@@ -5479,16 +5488,16 @@ sub git_tree {
 		}
 		git_print_page_path($file_name, 'tree', $hash_base);
 	}
-	print "<div class=\"page_body\">\n";
-	print "<table class=\"tree\">\n";
+	print {$output_handler} "<div class=\"page_body\">\n";
+	print {$output_handler} "<table class=\"tree\">\n";
 	my $alternate = 1;
 	# '..' (top directory) link if possible
 	if (defined $hash_base &&
 	    defined $file_name && $file_name =~ m![^/]+$!) {
 		if ($alternate) {
-			print "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
 
@@ -5496,33 +5505,33 @@ sub git_tree {
 		$up =~ s!/?[^/]+$!!;
 		undef $up unless $up;
 		# based on git_print_tree_entry
-		print '<td class="mode">' . mode_str('040000') . "</td>\n";
-		print '<td class="size">&nbsp;</td>'."\n" if $show_sizes;
-		print '<td class="list">';
-		print $cgi->a({-href => href(action=>"tree",
+		print {$output_handler} '<td class="mode">' . mode_str('040000') . "</td>\n";
+		print {$output_handler} '<td class="size">&nbsp;</td>'."\n" if $show_sizes;
+		print {$output_handler} '<td class="list">';
+		print {$output_handler} $cgi->a({-href => href(action=>"tree",
 		                             hash_base=>$hash_base,
 		                             file_name=>$up)},
 		              "..");
-		print "</td>\n";
-		print "<td class=\"link\"></td>\n";
+		print {$output_handler} "</td>\n";
+		print {$output_handler} "<td class=\"link\"></td>\n";
 
-		print "</tr>\n";
+		print {$output_handler} "</tr>\n";
 	}
 	foreach my $line (@entries) {
 		my %t = parse_ls_tree_line($line, -z => 1, -l => $show_sizes);
 
 		if ($alternate) {
-			print "<tr class=\"dark\">\n";
+			print {$output_handler} "<tr class=\"dark\">\n";
 		} else {
-			print "<tr class=\"light\">\n";
+			print {$output_handler} "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
 
 		git_print_tree_entry(\%t, $basedir, $hash_base, $have_blame);
 
-		print "</tr>\n";
+		print {$output_handler} "</tr>\n";
 	}
-	print "</table>\n" .
+	print {$output_handler} "</table>\n" .
 	      "</div>";
 	git_footer_html();
 }
@@ -5599,16 +5608,16 @@ sub git_snapshot {
 	}
 
 	$filename =~ s/(["\\])/\\$1/g;
-	print $cgi->header(
+	print {$output_handler} $cgi->header(
 		-type => $known_snapshot_formats{$format}{'type'},
 		-content_disposition => 'inline; filename="' . $filename . '"',
 		-status => '200 OK');
 
 	open my $fd, "-|", $cmd
 		or die_error(500, "Execute git-archive failed");
-	binmode STDOUT, ':raw';
-	print <$fd>;
-	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
+	binmode $output_handler_bin, ':raw';
+	print {$output_handler_bin} <$fd>;
+	binmode $output_handler_bin, ':utf8'; # as set at the beginning of gitweb.cgi
 	close $fd;
 }
 
@@ -5759,11 +5768,11 @@ sub git_commit {
 	} else {
 		git_print_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash);
 	}
-	print "<div class=\"title_text\">\n" .
+	print {$output_handler} "<div class=\"title_text\">\n" .
 	      "<table class=\"object_header\">\n";
 	git_print_authorship_rows(\%co);
-	print "<tr><td>commit</td><td class=\"sha1\">$co{'id'}</td></tr>\n";
-	print "<tr>" .
+	print {$output_handler} "<tr><td>commit</td><td class=\"sha1\">$co{'id'}</td></tr>\n";
+	print {$output_handler} "<tr>" .
 	      "<td>tree</td>" .
 	      "<td class=\"sha1\">" .
 	      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash),
@@ -5774,13 +5783,13 @@ sub git_commit {
 	              "tree");
 	my $snapshot_links = format_snapshot_links($hash);
 	if (defined $snapshot_links) {
-		print " | " . $snapshot_links;
+		print {$output_handler} " | " . $snapshot_links;
 	}
-	print "</td>" .
+	print {$output_handler} "</td>" .
 	      "</tr>\n";
 
 	foreach my $par (@$parents) {
-		print "<tr>" .
+		print {$output_handler} "<tr>" .
 		      "<td>parent</td>" .
 		      "<td class=\"sha1\">" .
 		      $cgi->a({-href => href(action=>"commit", hash=>$par),
@@ -5793,12 +5802,12 @@ sub git_commit {
 		      "</td>" .
 		      "</tr>\n";
 	}
-	print "</table>".
+	print {$output_handler} "</table>".
 	      "</div>\n";
 
-	print "<div class=\"page_body\">\n";
+	print {$output_handler} "<div class=\"page_body\">\n";
 	git_print_log($co{'comment'});
-	print "</div>\n";
+	print {$output_handler} "</div>\n";
 
 	git_difftree_body(\@difftree, $hash, @$parents);
 
@@ -5846,7 +5855,7 @@ sub git_object {
 		die_error(400, "Not enough information to find object");
 	}
 
-	print $cgi->redirect(-uri => href(action=>$type, -full=>1,
+	print {$output_handler} $cgi->redirect(-uri => href(action=>$type, -full=>1,
 	                                  hash=>$hash, hash_base=>$hash_base,
 	                                  file_name=>$file_name),
 	                     -status => '302 Found');
@@ -5937,23 +5946,23 @@ sub git_blobdiff {
 			git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
 			git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
 		} else {
-			print "<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n";
-			print "<div class=\"title\">$hash vs $hash_parent</div>\n";
+			print {$output_handler} "<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n";
+			print {$output_handler} "<div class=\"title\">$hash vs $hash_parent</div>\n";
 		}
 		if (defined $file_name) {
 			git_print_page_path($file_name, "blob", $hash_base);
 		} else {
-			print "<div class=\"page_path\"></div>\n";
+			print {$output_handler} "<div class=\"page_path\"></div>\n";
 		}
 
 	} elsif ($format eq 'plain') {
-		print $cgi->header(
+		print {$output_handler} $cgi->header(
 			-type => 'text/plain',
 			-charset => 'utf-8',
 			-expires => $expires,
 			-content_disposition => 'inline; filename="' . "$file_name" . '.patch"');
 
-		print "X-Git-Url: " . $cgi->self_url() . "\n\n";
+		print {$output_handler} "X-Git-Url: " . $cgi->self_url() . "\n\n";
 
 	} else {
 		die_error(400, "Unknown blobdiff format");
@@ -5961,12 +5970,12 @@ sub git_blobdiff {
 
 	# patch
 	if ($format eq 'html') {
-		print "<div class=\"page_body\">\n";
+		print {$output_handler} "<div class=\"page_body\">\n";
 
 		git_patchset_body($fd, [ \%diffinfo ], $hash_base, $hash_parent_base);
 		close $fd;
 
-		print "</div>\n"; # class="page_body"
+		print {$output_handler} "</div>\n"; # class="page_body"
 		git_footer_html();
 
 	} else {
@@ -5974,12 +5983,12 @@ sub git_blobdiff {
 			$line =~ s!a/($hash|$hash_parent)!'a/'.esc_path($diffinfo{'from_file'})!eg;
 			$line =~ s!b/($hash|$hash_parent)!'b/'.esc_path($diffinfo{'to_file'})!eg;
 
-			print $line;
+			print {$output_handler} $line;
 
 			last if $line =~ m!^\+\+\+!;
 		}
 		local $/ = undef;
-		print <$fd>;
+		print {$output_handler} <$fd>;
 		close $fd;
 	}
 }
@@ -6142,16 +6151,16 @@ sub git_commitdiff {
 		git_header_html(undef, $expires);
 		git_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);
 		git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash);
-		print "<div class=\"title_text\">\n" .
+		print {$output_handler} "<div class=\"title_text\">\n" .
 		      "<table class=\"object_header\">\n";
 		git_print_authorship_rows(\%co);
-		print "</table>".
+		print {$output_handler} "</table>".
 		      "</div>\n";
-		print "<div class=\"page_body\">\n";
+		print {$output_handler} "<div class=\"page_body\">\n";
 		if (@{$co{'comment'}} > 1) {
-			print "<div class=\"log\">\n";
+			print {$output_handler} "<div class=\"log\">\n";
 			git_print_log($co{'comment'}, -final_empty_line=> 1, -remove_title => 1);
-			print "</div>\n"; # class="log"
+			print {$output_handler} "</div>\n"; # class="log"
 		}
 
 	} elsif ($format eq 'plain') {
@@ -6159,27 +6168,27 @@ sub git_commitdiff {
 		my $tagname = git_get_rev_name_tags($hash);
 		my $filename = basename($project) . "-$hash.patch";
 
-		print $cgi->header(
+		print {$output_handler} $cgi->header(
 			-type => 'text/plain',
 			-charset => 'utf-8',
 			-expires => $expires,
 			-content_disposition => 'inline; filename="' . "$filename" . '"');
 		my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});
-		print "From: " . to_utf8($co{'author'}) . "\n";
-		print "Date: $ad{'rfc2822'} ($ad{'tz_local'})\n";
-		print "Subject: " . to_utf8($co{'title'}) . "\n";
+		print {$output_handler} "From: " . to_utf8($co{'author'}) . "\n";
+		print {$output_handler} "Date: $ad{'rfc2822'} ($ad{'tz_local'})\n";
+		print {$output_handler} "Subject: " . to_utf8($co{'title'}) . "\n";
 
-		print "X-Git-Tag: $tagname\n" if $tagname;
-		print "X-Git-Url: " . $cgi->self_url() . "\n\n";
+		print {$output_handler} "X-Git-Tag: $tagname\n" if $tagname;
+		print {$output_handler} "X-Git-Url: " . $cgi->self_url() . "\n\n";
 
 		foreach my $line (@{$co{'comment'}}) {
-			print to_utf8($line) . "\n";
+			print {$output_handler} to_utf8($line) . "\n";
 		}
-		print "---\n\n";
+		print {$output_handler} "---\n\n";
 	} elsif ($format eq 'patch') {
 		my $filename = basename($project) . "-$hash.patch";
 
-		print $cgi->header(
+		print {$output_handler} $cgi->header(
 			-type => 'text/plain',
 			-charset => 'utf-8',
 			-expires => $expires,
@@ -6192,24 +6201,24 @@ sub git_commitdiff {
 			$hash_parent eq '-c' || $hash_parent eq '--cc';
 		git_difftree_body(\@difftree, $hash,
 		                  $use_parents ? @{$co{'parents'}} : $hash_parent);
-		print "<br/>\n";
+		print {$output_handler} "<br/>\n";
 
 		git_patchset_body($fd, \@difftree, $hash,
 		                  $use_parents ? @{$co{'parents'}} : $hash_parent);
 		close $fd;
-		print "</div>\n"; # class="page_body"
+		print {$output_handler} "</div>\n"; # class="page_body"
 		git_footer_html();
 
 	} elsif ($format eq 'plain') {
 		local $/ = undef;
-		print <$fd>;
+		print {$output_handler} <$fd>;
 		close $fd
-			or print "Reading git-diff-tree failed\n";
+			or print {$output_handler} "Reading git-diff-tree failed\n";
 	} elsif ($format eq 'patch') {
 		local $/ = undef;
-		print <$fd>;
+		print {$output_handler} <$fd>;
 		close $fd
-			or print "Reading git-format-patch failed\n";
+			or print {$output_handler} "Reading git-format-patch failed\n";
 	}
 }
 
@@ -6312,7 +6321,7 @@ sub git_search {
 		git_print_page_nav('','', $hash,$co{'tree'},$hash);
 		git_print_header_div('commit', esc_html($co{'title'}), $hash);
 
-		print "<table class=\"pickaxe search\">\n";
+		print {$output_handler} "<table class=\"pickaxe search\">\n";
 		my $alternate = 1;
 		local $/ = "\n";
 		open my $fd, '-|', git_cmd(), '--no-pager', 'log', @diff_opts,
@@ -6328,24 +6337,24 @@ sub git_search {
 			if (defined $set{'commit'}) {
 				# finish previous commit
 				if (%co) {
-					print "</td>\n" .
+					print {$output_handler} "</td>\n" .
 					      "<td class=\"link\">" .
 					      $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") .
 					      " | " .
 					      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree");
-					print "</td>\n" .
+					print {$output_handler} "</td>\n" .
 					      "</tr>\n";
 				}
 
 				if ($alternate) {
-					print "<tr class=\"dark\">\n";
+					print {$output_handler} "<tr class=\"dark\">\n";
 				} else {
-					print "<tr class=\"light\">\n";
+					print {$output_handler} "<tr class=\"light\">\n";
 				}
 				$alternate ^= 1;
 				%co = parse_commit($set{'commit'});
 				my $author = chop_and_escape_str($co{'author_name'}, 15, 5);
-				print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+				print {$output_handler} "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
 				      "<td><i>$author</i></td>\n" .
 				      "<td>" .
 				      $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
@@ -6354,7 +6363,7 @@ sub git_search {
 			} elsif (defined $set{'to_id'}) {
 				next if ($set{'to_id'} =~ m/^0{40}$/);
 
-				print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'},
+				print {$output_handler} $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'},
 				                             hash=>$set{'to_id'}, file_name=>$set{'to_file'}),
 				              -class => "list"},
 				              "<span class=\"match\">" . esc_path($set{'file'}) . "</span>") .
@@ -6365,23 +6374,23 @@ sub git_search {
 
 		# finish last commit (warning: repetition!)
 		if (%co) {
-			print "</td>\n" .
+			print {$output_handler} "</td>\n" .
 			      "<td class=\"link\">" .
 			      $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") .
 			      " | " .
 			      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree");
-			print "</td>\n" .
+			print {$output_handler} "</td>\n" .
 			      "</tr>\n";
 		}
 
-		print "</table>\n";
+		print {$output_handler} "</table>\n";
 	}
 
 	if ($searchtype eq 'grep') {
 		git_print_page_nav('','', $hash,$co{'tree'},$hash);
 		git_print_header_div('commit', esc_html($co{'title'}), $hash);
 
-		print "<table class=\"grep_search\">\n";
+		print {$output_handler} "<table class=\"grep_search\">\n";
 		my $alternate = 1;
 		my $matches = 0;
 		local $/ = "\n";
@@ -6400,21 +6409,21 @@ sub git_search {
 				(undef, $file, $lno, $ltext) = split(/:/, $line, 4);
 			}
 			if ($file ne $lastfile) {
-				$lastfile and print "</td></tr>\n";
+				$lastfile and print {$output_handler} "</td></tr>\n";
 				if ($alternate++) {
-					print "<tr class=\"dark\">\n";
+					print {$output_handler} "<tr class=\"dark\">\n";
 				} else {
-					print "<tr class=\"light\">\n";
+					print {$output_handler} "<tr class=\"light\">\n";
 				}
-				print "<td class=\"list\">".
+				print {$output_handler} "<td class=\"list\">".
 					$cgi->a({-href => href(action=>"blob", hash=>$co{'hash'},
 							       file_name=>"$file"),
 						-class => "list"}, esc_path($file));
-				print "</td><td>\n";
+				print {$output_handler} "</td><td>\n";
 				$lastfile = $file;
 			}
 			if ($binary) {
-				print "<div class=\"binary\">Binary file</div>\n";
+				print {$output_handler} "<div class=\"binary\">Binary file</div>\n";
 			} else {
 				$ltext = untabify($ltext);
 				if ($ltext =~ m/^(.*)($search_regexp)(.*)$/i) {
@@ -6426,7 +6435,7 @@ sub git_search {
 				} else {
 					$ltext = esc_html($ltext, -nbsp=>1);
 				}
-				print "<div class=\"pre\">" .
+				print {$output_handler} "<div class=\"pre\">" .
 					$cgi->a({-href => href(action=>"blob", hash=>$co{'hash'},
 							       file_name=>"$file").'#l'.$lno,
 						-class => "linenr"}, sprintf('%4i', $lno))
@@ -6434,16 +6443,16 @@ sub git_search {
 			}
 		}
 		if ($lastfile) {
-			print "</td></tr>\n";
+			print {$output_handler} "</td></tr>\n";
 			if ($matches > 1000) {
-				print "<div class=\"diff nodifferences\">Too many matches, listing trimmed</div>\n";
+				print {$output_handler} "<div class=\"diff nodifferences\">Too many matches, listing trimmed</div>\n";
 			}
 		} else {
-			print "<div class=\"diff nodifferences\">No matches found</div>\n";
+			print {$output_handler} "<div class=\"diff nodifferences\">No matches found</div>\n";
 		}
 		close $fd;
 
-		print "</table>\n";
+		print {$output_handler} "</table>\n";
 	}
 	git_footer_html();
 }
@@ -6451,7 +6460,7 @@ sub git_search {
 sub git_search_help {
 	git_header_html();
 	git_print_page_nav('','', $hash,$hash,$hash);
-	print <<EOT;
+	print {$output_handler} <<EOT;
 <p><strong>Pattern</strong> is by default a normal string that is matched precisely (but without
 regard to case, except in the case of pickaxe). However, when you check the <em>re</em> checkbox,
 the pattern entered is recognized as the POSIX extended
@@ -6463,7 +6472,7 @@ insensitive).</p>
 EOT
 	my $have_grep = gitweb_check_feature('grep');
 	if ($have_grep) {
-		print <<EOT;
+		print {$output_handler} <<EOT;
 <dt><b>grep</b></dt>
 <dd>All files in the currently selected tree (HEAD unless you are explicitly browsing
     a different one) are searched for the given pattern. On large trees, this search can take
@@ -6472,7 +6481,7 @@ due to git-grep peculiarity, currently if regexp mode is turned off, the matches
 case-sensitive.</dd>
 EOT
 	}
-	print <<EOT;
+	print {$output_handler} <<EOT;
 <dt><b>author</b></dt>
 <dd>Name and e-mail of the change author and date of birth of the patch will be scanned for the given pattern.</dd>
 <dt><b>committer</b></dt>
@@ -6480,7 +6489,7 @@ EOT
 EOT
 	my $have_pickaxe = gitweb_check_feature('pickaxe');
 	if ($have_pickaxe) {
-		print <<EOT;
+		print {$output_handler} <<EOT;
 <dt><b>pickaxe</b></dt>
 <dd>All commits that caused the string to appear or disappear from any file (changes that
 added, removed or "modified" the string) will be listed. This search can take a while and
@@ -6488,7 +6497,7 @@ takes a lot of strain on the server, so please use it wisely. Note that since yo
 interested even in changes just changing the case as well, this search is case sensitive.</dd>
 EOT
 	}
-	print "</dl>\n";
+	print {$output_handler} "</dl>\n";
 	git_footer_html();
 }
 
@@ -6535,7 +6544,7 @@ sub git_feed {
 				$since = Time::ParseDate::parsedate($if_modified, GMT => 1);
 			}
 			if (defined $since && $latest_epoch <= $since) {
-				print $cgi->header(
+				print {$output_handler} $cgi->header(
 					-type => $content_type,
 					-charset => 'utf-8',
 					-last_modified => $latest_date{'rfc2822'},
@@ -6543,12 +6552,12 @@ sub git_feed {
 				return;
 			}
 		}
-		print $cgi->header(
+		print {$output_handler} $cgi->header(
 			-type => $content_type,
 			-charset => 'utf-8',
 			-last_modified => $latest_date{'rfc2822'});
 	} else {
-		print $cgi->header(
+		print {$output_handler} $cgi->header(
 			-type => $content_type,
 			-charset => 'utf-8');
 	}
@@ -6592,13 +6601,13 @@ sub git_feed {
 	} else {
 		$alt_url = href(-full=>1, action=>"summary");
 	}
-	print qq!<?xml version="1.0" encoding="utf-8"?>\n!;
+	print {$output_handler} qq!<?xml version="1.0" encoding="utf-8"?>\n!;
 	if ($format eq 'rss') {
-		print <<XML;
+		print {$output_handler} <<XML;
 <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/";>
 <channel>
 XML
-		print "<title>$title</title>\n" .
+		print {$output_handler} "<title>$title</title>\n" .
 		      "<link>$alt_url</link>\n" .
 		      "<description>$descr</description>\n" .
 		      "<language>en</language>\n" .
@@ -6608,22 +6617,22 @@ XML
 			# prefer the logo to the favicon, since RSS
 			# doesn't allow both
 			my $img = esc_url($logo || $favicon);
-			print "<image>\n" .
+			print {$output_handler} "<image>\n" .
 			      "<url>$img</url>\n" .
 			      "<title>$title</title>\n" .
 			      "<link>$alt_url</link>\n" .
 			      "</image>\n";
 		}
 		if (%latest_date) {
-			print "<pubDate>$latest_date{'rfc2822'}</pubDate>\n";
-			print "<lastBuildDate>$latest_date{'rfc2822'}</lastBuildDate>\n";
+			print {$output_handler} "<pubDate>$latest_date{'rfc2822'}</pubDate>\n";
+			print {$output_handler} "<lastBuildDate>$latest_date{'rfc2822'}</lastBuildDate>\n";
 		}
-		print "<generator>gitweb v.$version/$git_version</generator>\n";
+		print {$output_handler} "<generator>gitweb v.$version/$git_version</generator>\n";
 	} elsif ($format eq 'atom') {
-		print <<XML;
+		print {$output_handler} <<XML;
 <feed xmlns="http://www.w3.org/2005/Atom";>
 XML
-		print "<title>$title</title>\n" .
+		print {$output_handler} "<title>$title</title>\n" .
 		      "<subtitle>$descr</subtitle>\n" .
 		      '<link rel="alternate" type="text/html" href="' .
 		      $alt_url . '" />' . "\n" .
@@ -6633,19 +6642,19 @@ XML
 		      # use project owner for feed author
 		      "<author><name>$owner</name></author>\n";
 		if (defined $favicon) {
-			print "<icon>" . esc_url($favicon) . "</icon>\n";
+			print {$output_handler} "<icon>" . esc_url($favicon) . "</icon>\n";
 		}
 		if (defined $logo_url) {
 			# not twice as wide as tall: 72 x 27 pixels
-			print "<logo>" . esc_url($logo) . "</logo>\n";
+			print {$output_handler} "<logo>" . esc_url($logo) . "</logo>\n";
 		}
 		if (! %latest_date) {
 			# dummy date to keep the feed valid until commits trickle in:
-			print "<updated>1970-01-01T00:00:00Z</updated>\n";
+			print {$output_handler} "<updated>1970-01-01T00:00:00Z</updated>\n";
 		} else {
-			print "<updated>$latest_date{'iso-8601'}</updated>\n";
+			print {$output_handler} "<updated>$latest_date{'iso-8601'}</updated>\n";
 		}
-		print "<generator version='$version/$git_version'>gitweb</generator>\n";
+		print {$output_handler} "<generator version='$version/$git_version'>gitweb</generator>\n";
 	}
 
 	# contents
@@ -6670,7 +6679,7 @@ XML
 		# print element (entry, item)
 		my $co_url = href(-full=>1, action=>"commitdiff", hash=>$commit);
 		if ($format eq 'rss') {
-			print "<item>\n" .
+			print {$output_handler} "<item>\n" .
 			      "<title>" . esc_html($co{'title'}) . "</title>\n" .
 			      "<author>" . esc_html($co{'author'}) . "</author>\n" .
 			      "<pubDate>$cd{'rfc2822'}</pubDate>\n" .
@@ -6680,22 +6689,22 @@ XML
 			      "<content:encoded>" .
 			      "<![CDATA[\n";
 		} elsif ($format eq 'atom') {
-			print "<entry>\n" .
+			print {$output_handler} "<entry>\n" .
 			      "<title type=\"html\">" . esc_html($co{'title'}) . "</title>\n" .
 			      "<updated>$cd{'iso-8601'}</updated>\n" .
 			      "<author>\n" .
 			      "  <name>" . esc_html($co{'author_name'}) . "</name>\n";
 			if ($co{'author_email'}) {
-				print "  <email>" . esc_html($co{'author_email'}) . "</email>\n";
+				print {$output_handler} "  <email>" . esc_html($co{'author_email'}) . "</email>\n";
 			}
-			print "</author>\n" .
+			print {$output_handler} "</author>\n" .
 			      # use committer for contributor
 			      "<contributor>\n" .
 			      "  <name>" . esc_html($co{'committer_name'}) . "</name>\n";
 			if ($co{'committer_email'}) {
-				print "  <email>" . esc_html($co{'committer_email'}) . "</email>\n";
+				print {$output_handler} "  <email>" . esc_html($co{'committer_email'}) . "</email>\n";
 			}
-			print "</contributor>\n" .
+			print {$output_handler} "</contributor>\n" .
 			      "<published>$cd{'iso-8601'}</published>\n" .
 			      "<link rel=\"alternate\" type=\"text/html\" href=\"$co_url\" />\n" .
 			      "<id>$co_url</id>\n" .
@@ -6703,19 +6712,19 @@ XML
 			      "<div xmlns=\"http://www.w3.org/1999/xhtml\";>\n";
 		}
 		my $comment = $co{'comment'};
-		print "<pre>\n";
+		print {$output_handler} "<pre>\n";
 		foreach my $line (@$comment) {
 			$line = esc_html($line);
-			print "$line\n";
+			print {$output_handler} "$line\n";
 		}
-		print "</pre><ul>\n";
+		print {$output_handler} "</pre><ul>\n";
 		foreach my $difftree_line (@difftree) {
 			my %difftree = parse_difftree_raw_line($difftree_line);
 			next if !$difftree{'from_id'};
 
 			my $file = $difftree{'file'} || $difftree{'to_file'};
 
-			print "<li>" .
+			print {$output_handler} "<li>" .
 			      "[" .
 			      $cgi->a({-href => href(-full=>1, action=>"blobdiff",
 			                             hash=>$difftree{'to_id'}, hash_parent=>$difftree{'from_id'},
@@ -6723,26 +6732,26 @@ XML
 			                             file_name=>$file, file_parent=>$difftree{'from_file'}),
 			              -title => "diff"}, 'D');
 			if ($have_blame) {
-				print $cgi->a({-href => href(-full=>1, action=>"blame",
+				print {$output_handler} $cgi->a({-href => href(-full=>1, action=>"blame",
 				                             file_name=>$file, hash_base=>$commit),
 				              -title => "blame"}, 'B');
 			}
 			# if this is not a feed of a file history
 			if (!defined $file_name || $file_name ne $file) {
-				print $cgi->a({-href => href(-full=>1, action=>"history",
+				print {$output_handler} $cgi->a({-href => href(-full=>1, action=>"history",
 				                             file_name=>$file, hash=>$commit),
 				              -title => "history"}, 'H');
 			}
 			$file = esc_path($file);
-			print "] ".
+			print {$output_handler} "] ".
 			      "$file</li>\n";
 		}
 		if ($format eq 'rss') {
-			print "</ul>]]>\n" .
+			print {$output_handler} "</ul>]]>\n" .
 			      "</content:encoded>\n" .
 			      "</item>\n";
 		} elsif ($format eq 'atom') {
-			print "</ul>\n</div>\n" .
+			print {$output_handler} "</ul>\n</div>\n" .
 			      "</content>\n" .
 			      "</entry>\n";
 		}
@@ -6750,9 +6759,9 @@ XML
 
 	# end of feed
 	if ($format eq 'rss') {
-		print "</channel>\n</rss>\n";
+		print {$output_handler} "</channel>\n</rss>\n";
 	} elsif ($format eq 'atom') {
-		print "</feed>\n";
+		print {$output_handler} "</feed>\n";
 	}
 }
 
@@ -6766,13 +6775,12 @@ sub git_atom {
 
 sub git_opml {
 	my @list = git_get_projects_list();
-
-	print $cgi->header(
+	print {$output_handler} $cgi->header(
 		-type => 'text/xml',
 		-charset => 'utf-8',
 		-content_disposition => 'inline; filename="opml.xml"');
 
-	print <<XML;
+	print {$output_handler} <<XML;
 <?xml version="1.0" encoding="utf-8"?>
 <opml version="1.0">
 <head>
@@ -6797,9 +6805,9 @@ XML
 		my $path = esc_html(chop_str($proj{'path'}, 25, 5));
 		my $rss  = href('project' => $proj{'path'}, 'action' => 'rss', -full => 1);
 		my $html = href('project' => $proj{'path'}, 'action' => 'summary', -full => 1);
-		print "<outline type=\"rss\" text=\"$path\" title=\"$path\" xmlUrl=\"$rss\" htmlUrl=\"$html\"/>\n";
+		print {$output_handler} "<outline type=\"rss\" text=\"$path\" title=\"$path\" xmlUrl=\"$rss\" htmlUrl=\"$html\"/>\n";
 	}
-	print <<XML;
+	print {$output_handler} <<XML;
 </outline>
 </body>
 </opml>
-- 
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]