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 { | ||||
| 	if (!defined $hash && defined $file_name) { | ||||
| 		my $base = $hash_base || git_read_head($project); | ||||
|  | @ -1465,6 +1550,11 @@ sub git_blob { | |||
| 	} | ||||
| 	my $have_blame = git_get_project_config_bool ('blame'); | ||||
| 	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(); | ||||
| 	if (defined $hash_base && (my %co = git_read_commit($hash_base))) { | ||||
| 		print "<div class=\"page_nav\">\n" . | ||||
|  | @ -1513,89 +1603,6 @@ sub git_blob { | |||
| 	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 { | ||||
| 	if (!defined $hash) { | ||||
| 		$hash = git_read_head($project); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Luben Tuikov
						Luben Tuikov