gitweb.cgi: Teach "a=blob" action to know the blob/file mime type
Now action "blob" knows the file type: if the file type is not "text/*" then action "blob" defaults to "blob_plain", i.e. the file is downloaded raw for the browser to interpret. If the file type is "text/*", then "blob" defaults to the current "cat -n"-like output, from which you can click "plain", to get the "blob_plain" output. Signed-off-by: Luben Tuikov <ltuikov@yahoo.com> Signed-off-by: Junio C Hamano <junkio@cox.net>maint
							parent
							
								
									9af2511796
								
							
						
					
					
						commit
						930cf7dd7c
					
				|  | @ -1458,6 +1458,91 @@ sub git_get_hash_by_path { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | sub mimetype_guess_file { | ||||||
|  | 	my $filename = shift; | ||||||
|  | 	my $mimemap = shift; | ||||||
|  | 	-r $mimemap or return undef; | ||||||
|  |  | ||||||
|  | 	my %mimemap; | ||||||
|  | 	open(MIME, $mimemap) or return undef; | ||||||
|  | 	while (<MIME>) { | ||||||
|  | 		my ($mime, $exts) = split(/\t+/); | ||||||
|  | 		my @exts = split(/\s+/, $exts); | ||||||
|  | 		foreach my $ext (@exts) { | ||||||
|  | 			$mimemap{$ext} = $mime; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	close(MIME); | ||||||
|  |  | ||||||
|  | 	$filename =~ /\.(.*?)$/; | ||||||
|  | 	return $mimemap{$1}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub mimetype_guess { | ||||||
|  | 	my $filename = shift; | ||||||
|  | 	my $mime; | ||||||
|  | 	$filename =~ /\./ or return undef; | ||||||
|  |  | ||||||
|  | 	if ($mimetypes_file) { | ||||||
|  | 		my $file = $mimetypes_file; | ||||||
|  | 		#$file =~ m#^/# or $file = "$projectroot/$path/$file"; | ||||||
|  | 		$mime = mimetype_guess_file($filename, $file); | ||||||
|  | 	} | ||||||
|  | 	$mime ||= mimetype_guess_file($filename, '/etc/mime.types'); | ||||||
|  | 	return $mime; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub git_blob_plain_mimetype { | ||||||
|  | 	my $fd = shift; | ||||||
|  | 	my $filename = shift; | ||||||
|  |  | ||||||
|  | 	if ($filename) { | ||||||
|  | 		my $mime = mimetype_guess($filename); | ||||||
|  | 		$mime and return $mime; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	# just in case | ||||||
|  | 	return $default_blob_plain_mimetype unless $fd; | ||||||
|  |  | ||||||
|  | 	if (-T $fd) { | ||||||
|  | 		return 'text/plain' . | ||||||
|  | 		       ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : ''); | ||||||
|  | 	} elsif (! $filename) { | ||||||
|  | 		return 'application/octet-stream'; | ||||||
|  | 	} elsif ($filename =~ m/\.png$/i) { | ||||||
|  | 		return 'image/png'; | ||||||
|  | 	} elsif ($filename =~ m/\.gif$/i) { | ||||||
|  | 		return 'image/gif'; | ||||||
|  | 	} elsif ($filename =~ m/\.jpe?g$/i) { | ||||||
|  | 		return 'image/jpeg'; | ||||||
|  | 	} else { | ||||||
|  | 		return 'application/octet-stream'; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub git_blob_plain { | ||||||
|  | 	my $type = shift; | ||||||
|  | 	open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error("Couldn't cat $file_name, $hash"); | ||||||
|  |  | ||||||
|  | 	$type ||= git_blob_plain_mimetype($fd, $file_name); | ||||||
|  |  | ||||||
|  | 	# save as filename, even when no $file_name is given | ||||||
|  | 	my $save_as = "$hash"; | ||||||
|  | 	if (defined $file_name) { | ||||||
|  | 		$save_as = $file_name; | ||||||
|  | 	} elsif ($type =~ m/^text\//) { | ||||||
|  | 		$save_as .= '.txt'; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	print $cgi->header(-type => "$type", '-content-disposition' => "inline; filename=\"$save_as\""); | ||||||
|  | 	undef $/; | ||||||
|  | 	binmode STDOUT, ':raw'; | ||||||
|  | 	print <$fd>; | ||||||
|  | 	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi | ||||||
|  | 	$/ = "\n"; | ||||||
|  | 	close $fd; | ||||||
|  | } | ||||||
|  |  | ||||||
| sub git_blob { | sub git_blob { | ||||||
| 	if (!defined $hash && defined $file_name) { | 	if (!defined $hash && defined $file_name) { | ||||||
| 		my $base = $hash_base || git_read_head($project); | 		my $base = $hash_base || git_read_head($project); | ||||||
|  | @ -1465,6 +1550,11 @@ sub git_blob { | ||||||
| 	} | 	} | ||||||
| 	my $have_blame = git_get_project_config_bool ('blame'); | 	my $have_blame = git_get_project_config_bool ('blame'); | ||||||
| 	open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error(undef, "Open failed."); | 	open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error(undef, "Open failed."); | ||||||
|  | 	my $mimetype = git_blob_plain_mimetype($fd, $file_name); | ||||||
|  | 	if ($mimetype !~ m/^text\//) { | ||||||
|  | 		close $fd; | ||||||
|  | 		return git_blob_plain($mimetype); | ||||||
|  | 	} | ||||||
| 	git_header_html(); | 	git_header_html(); | ||||||
| 	if (defined $hash_base && (my %co = git_read_commit($hash_base))) { | 	if (defined $hash_base && (my %co = git_read_commit($hash_base))) { | ||||||
| 		print "<div class=\"page_nav\">\n" . | 		print "<div class=\"page_nav\">\n" . | ||||||
|  | @ -1513,89 +1603,6 @@ sub git_blob { | ||||||
| 	git_footer_html(); | 	git_footer_html(); | ||||||
| } | } | ||||||
|  |  | ||||||
| sub mimetype_guess_file { |  | ||||||
| 	my $filename = shift; |  | ||||||
| 	my $mimemap = shift; |  | ||||||
| 	-r $mimemap or return undef; |  | ||||||
|  |  | ||||||
| 	my %mimemap; |  | ||||||
| 	open(MIME, $mimemap) or return undef; |  | ||||||
| 	while (<MIME>) { |  | ||||||
| 		my ($mime, $exts) = split(/\t+/); |  | ||||||
| 		my @exts = split(/\s+/, $exts); |  | ||||||
| 		foreach my $ext (@exts) { |  | ||||||
| 			$mimemap{$ext} = $mime; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	close(MIME); |  | ||||||
|  |  | ||||||
| 	$filename =~ /\.(.*?)$/; |  | ||||||
| 	return $mimemap{$1}; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| sub mimetype_guess { |  | ||||||
| 	my $filename = shift; |  | ||||||
| 	my $mime; |  | ||||||
| 	$filename =~ /\./ or return undef; |  | ||||||
|  |  | ||||||
| 	if ($mimetypes_file) { |  | ||||||
| 		my $file = $mimetypes_file; |  | ||||||
| 		#$file =~ m#^/# or $file = "$projectroot/$path/$file"; |  | ||||||
| 		$mime = mimetype_guess_file($filename, $file); |  | ||||||
| 	} |  | ||||||
| 	$mime ||= mimetype_guess_file($filename, '/etc/mime.types'); |  | ||||||
| 	return $mime; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| sub git_blob_plain_mimetype { |  | ||||||
| 	my $fd = shift; |  | ||||||
| 	my $filename = shift; |  | ||||||
|  |  | ||||||
| 	# just in case |  | ||||||
| 	return $default_blob_plain_mimetype unless $fd; |  | ||||||
|  |  | ||||||
| 	if ($filename) { |  | ||||||
| 		my $mime = mimetype_guess($filename); |  | ||||||
| 		$mime and return $mime; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (-T $fd) { |  | ||||||
| 		return 'text/plain' . |  | ||||||
| 		       ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : ''); |  | ||||||
| 	} elsif (! $filename) { |  | ||||||
| 		return 'application/octet-stream'; |  | ||||||
| 	} elsif ($filename =~ m/\.png$/i) { |  | ||||||
| 		return 'image/png'; |  | ||||||
| 	} elsif ($filename =~ m/\.gif$/i) { |  | ||||||
| 		return 'image/gif'; |  | ||||||
| 	} elsif ($filename =~ m/\.jpe?g$/i) { |  | ||||||
| 		return 'image/jpeg'; |  | ||||||
| 	} else { |  | ||||||
| 		return 'application/octet-stream'; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| sub git_blob_plain { |  | ||||||
| 	open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or return; |  | ||||||
| 	my $type = git_blob_plain_mimetype($fd, $file_name); |  | ||||||
|  |  | ||||||
| 	# save as filename, even when no $file_name is given |  | ||||||
| 	my $save_as = "$hash"; |  | ||||||
| 	if (defined $file_name) { |  | ||||||
| 		$save_as = $file_name; |  | ||||||
| 	} elsif ($type =~ m/^text\//) { |  | ||||||
| 		$save_as .= '.txt'; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	print $cgi->header(-type => "$type", '-content-disposition' => "inline; filename=\"$save_as\""); |  | ||||||
| 	undef $/; |  | ||||||
| 	binmode STDOUT, ':raw'; |  | ||||||
| 	print <$fd>; |  | ||||||
| 	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi |  | ||||||
| 	$/ = "\n"; |  | ||||||
| 	close $fd; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| sub git_tree { | sub git_tree { | ||||||
| 	if (!defined $hash) { | 	if (!defined $hash) { | ||||||
| 		$hash = git_read_head($project); | 		$hash = git_read_head($project); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Luben Tuikov
						Luben Tuikov