File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / doc / scripts / create-mime.conf.pl
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:35:00 2016 UTC (8 years, 5 months ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_41p8, HEAD
lighttpd 1.4.41

    1: #!/usr/bin/perl -w
    2: 
    3: # Based on create-mime.assign.pl in debian lighttpd (1.4.x) package
    4: # Creates an example mime.conf from /etc/mime.types
    5: 
    6: use strict;
    7: 
    8: # text/* subtypes to serve as "text/...; charset=utf-8"
    9: # text/html IS NOT INCLUDED: html has its own method for defining charset
   10: #   (<meta>), but the standards specify that content-type in HTTP wins over
   11: #   the setting in the html document.
   12: my %text_utf8 = map { $_ => 1 } qw(
   13: 	css
   14: 	csv
   15: 	plain
   16: 	x-bibtex
   17: 	x-boo
   18: 	x-c++hdr
   19: 	x-c++src
   20: 	x-chdr
   21: 	x-csh
   22: 	x-csrc
   23: 	x-dsrc
   24: 	x-diff
   25: 	x-haskell
   26: 	x-java
   27: 	x-lilypond
   28: 	x-literate-haskell
   29: 	x-makefile
   30: 	x-moc
   31: 	x-pascal
   32: 	x-perl
   33: 	x-python
   34: 	x-scala
   35: 	x-sh
   36: 	x-tcl
   37: 	x-tex
   38: );
   39: 
   40: # map extension to hash which maps types to the type they should be replaced with
   41: my %manual_conflicts_resolve = (
   42: 	'.ra' => {
   43: 		'audio/x-pn-realaudio' => 'audio/x-realaudio',
   44: 	},
   45: );
   46: 
   47: open MIMETYPES, "/etc/mime.types" or die "Can't open /etc/mime.types: $!";
   48: 
   49: my %extensions;
   50: sub set {
   51: 	my ($extension, $mimetype) = @_;
   52: 	$extensions{$extension} = $mimetype;
   53: }
   54: sub add {
   55: 	my ($extension, $mimetype) = @_;
   56: 	my $have = $extensions{$extension};
   57: 
   58: 	my $r = $manual_conflicts_resolve{$extension};
   59: 	# update @_ too for calls to set
   60: 	$_[1] = $mimetype = $r->{$mimetype} if $r && $r->{$mimetype};
   61: 
   62: 	# mime.types can have same extension for different mime types
   63: 	if ($have) {
   64: 		# application/octet-stream means we couldn't resolve another conflict
   65: 		return if $have eq $mimetype || $have eq 'application/octet-stream';
   66: 
   67: 		my ($have_type, $have_subtype) = split /\//, $have, 2;
   68: 		my ($type, $subtype) = split /\//, $mimetype, 2;
   69: 
   70: 		my $have_x = ($have_type =~ /^x-/ || $have_subtype =~ /^x-/);
   71: 		my $x = ($type =~ /^x-/ || $subtype =~ /^x-/);
   72: 
   73: 		# entries without x- prefix in type/subtype win:
   74: 		if ($have_x && !$x) {
   75: 			return set @_; # overwrite
   76: 		} elsif ($x && !$have_x) {
   77: 			return; # ignore
   78: 		}
   79: 
   80: 		# text/ wins over application/ for same subtype
   81: 		if ($subtype eq $have_subtype) {
   82: 			if ($type eq "text" && $have_type eq "application") {
   83: 				return set @_; # overwrite
   84: 			} elsif ($have_type eq "text" && $type eq "application") {
   85: 				return; # ignore
   86: 			}
   87: 		}
   88: 
   89: 		print STDERR "Duplicate mimetype: '${extension}' => '${mimetype}' (already have '${have}'), merging to 'application/octet-stream'\n";
   90: 		set ($extension, 'application/octet-stream');
   91: 	} else {
   92: 		set @_;
   93: 	}
   94: }
   95: 
   96: sub print_type {
   97: 	my ($extension, $mimetype) = @_;
   98: 	if ($mimetype =~ /^text\/(.*)$/) {
   99: 		$mimetype .= "; charset=utf-8" if $text_utf8{$1};
  100: 	}
  101: 
  102: 	print "\t\"${extension}\" => \"${mimetype}\",\n";
  103: }
  104: 
  105: while (<MIMETYPES>) {
  106: 	chomp;
  107: 	s/\#.*//;
  108: 	next if /^\w*$/;
  109: 	if (/^([a-z0-9\/+-.]+)\s+((?:[a-z0-9.+-]+[ ]?)+)$/i) {
  110: 		my $mimetype = $1;
  111: 		my @extensions = split / /, $2;
  112: 
  113: 		foreach my $ext (@extensions) {
  114: 			add(".${ext}", $mimetype);
  115: 		}
  116: 	}
  117: }
  118: 
  119: # missing in /etc/mime.types;
  120: # from http://www.iana.org/assignments/media-types/media-types.xhtml
  121: add(".dtd", "application/xml-dtd");
  122: 
  123: # other useful mappings
  124: my %useful = (
  125: 	".tar.gz"  => "application/x-gtar-compressed",
  126: 	".gz"      => "application/x-gzip",
  127: 	".tbz"     => "application/x-gtar-compressed",
  128: 	".tar.bz2" => "application/x-gtar-compressed",
  129: 	".bz2"     => "application/x-bzip",
  130: 	".log"     => "text/plain",
  131: 	".conf"    => "text/plain",
  132: 	".spec"    => "text/plain",
  133: 	"README"   => "text/plain",
  134: 	"Makefile" => "text/x-makefile",
  135: );
  136: 
  137: while (my ($ext, $mimetype) = each %useful) {
  138: 	add($ext, $mimetype) unless $extensions{$ext};
  139: }
  140: 
  141: 
  142: print <<EOF;
  143: # created by create-mime.conf.pl
  144: 
  145: #######################################################################
  146: ##
  147: ##  MimeType handling
  148: ## -------------------
  149: ##
  150: ## https://redmine.lighttpd.net/projects/lighttpd/wiki/Mimetype_assignDetails
  151: 
  152: ##
  153: ## mimetype.xattr-name
  154: ## Set the extended file attribute name used to obtain mime type
  155: ## (must also set mimetype.use-xattr = "enable")
  156: ##
  157: ## Default value is "Content-Type"
  158: ##
  159: ## freedesktop.org Shared MIME-info Database specification suggests
  160: ## user-defined value ("user.mime_type") as name for extended file attribute
  161: #mimetype.xattr-name = "user.mime_type"
  162: 
  163: ##
  164: ## Use extended attribute named in mimetype.xattr-name (default "Content-Type")
  165: ## to obtain mime type if possible
  166: ##
  167: ## Disabled by default
  168: ##
  169: #mimetype.use-xattr = "enable"
  170: 
  171: ##
  172: ## mimetype ("Content-Type" HTTP header) mapping for static file handling
  173: ##
  174: ## The first matching suffix is used. If no mapping is found
  175: ## 'application/octet-stream' is used, and caching (etag/last-modified handling)
  176: ## is disabled to prevent clients from caching "unknown" mime types.
  177: ##
  178: ## Therefore the last mapping is:
  179: ##   "" => "application/octet-stream"
  180: ## This matches all extensions and acts as default mime type, and enables
  181: ## caching for those.
  182: mimetype.assign = (
  183: EOF
  184: 
  185: # sort "x-" and "vnd." prefixed names after everything else
  186: sub mimecmpvalue {
  187: 	my ($mimetype) = @_;
  188: 	$mimetype =~ s/(^|\/)(x-|vnd\.)/~$1$2/g;
  189: 	return $mimetype;
  190: }
  191: sub countdots {
  192: 	my ($s) = @_;
  193: 	return scalar(() = $s =~ /\./g);
  194: }
  195: # the first matching suffix wins, so we have to sort by "length"
  196: # as all extensions start with "." we use the number of "."s as length
  197: # the exceptions are "README" and "Makefile" which are assumed not to conflict
  198: #  (i.e. are not a suffix of any other extension)
  199: for my $ext (sort { countdots($b) <=> countdots($a) || mimecmpvalue($extensions{$a}) cmp mimecmpvalue($extensions{$b}) || $a cmp $b } keys(%extensions)) {
  200: 	print_type($ext, $extensions{$ext});
  201: }
  202: 
  203: print <<EOF;
  204: 
  205: 	# enable caching for unknown mime types:
  206: 	"" => "application/octet-stream"
  207: )
  208: EOF

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>