PageRenderTime 114ms CodeModel.GetById 3ms RepoModel.GetById 0ms app.codeStats 0ms

/res/scripts/check-mime.pl

https://bitbucket.org/chittoor/tomcat7
Perl | 415 lines | 269 code | 46 blank | 100 comment | 47 complexity | 2fdc4c1f6f6d8768637ad6b1cc35eb0a MD5 | raw file
Possible License(s): Apache-2.0
  1. #!/usr/bin/perl
  2. # Licensed to the Apache Software Foundation (ASF) under one or more
  3. # contributor license agreements. See the NOTICE file distributed with
  4. # this work for additional information regarding copyright ownership.
  5. # The ASF licenses this file to You under the Apache License, Version 2.0
  6. # (the "License"); you may not use this file except in compliance with
  7. # the License. You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. # -----------------------------------------------------------------------------
  17. # Merge the MIME type definitions contained in the
  18. # file mime.types from the httpd project into Tomcat web.xml.
  19. # -----------------------------------------------------------------------------
  20. # The script uses two mime type lists to describe
  21. # the merging between httpd and Tomcat mime types.
  22. #
  23. # 1) %TOMCAT_ONLY: Additional extensions for Tomcat that do not exist in httpd
  24. # 2) %TOMCAT_KEEP: Mime type differences for common extensions where we stick to
  25. # the Tomcat definition
  26. # The script checks consistency between Tomcat and httpd according
  27. # to the lists 1) and 2) and generates a new web.xml:
  28. #
  29. # A) Additional extensions in Tomcat which are not part of 1)
  30. # are logged. They will be removed in the generated new web.xml.
  31. # If you want to keep them, add them to the list 1) and run the
  32. # script again. If you want to remove them, commit the generated
  33. # new web.xml.
  34. # B) Mime type differences for the same extension between httpd
  35. # and Tomcat that are not part of the list 2) are logged.
  36. # They will be overwritten wit the httpd definition in the generated
  37. # new web.xml. If you want to keep their Tomcat definition, add them
  38. # to the list 1) and run the script again. If you want to use the
  39. # definitions from httpd, commit the generated new web.xml.
  40. # C) Additional extensions in httpd are logged. The script outputs a
  41. # merged web.xml, which already includes all those additional
  42. # extensions. If you want to keep them, update web.xml with the
  43. # generated new web.xml.
  44. # D) If the extensions are not sorted alphabetically, a message is logged.
  45. # The generated web.xml will be always be sorted alphabetically.
  46. # If you want to fix the sort order, update web.xml with the generated
  47. # new web.xml.
  48. use strict;
  49. use locale;
  50. use POSIX qw(locale_h);
  51. use Getopt::Std;
  52. ################### BEGIN VARIABLES WHICH MUST BE MAINTAINED #####################
  53. # Script version, printed via getopts with "--version"
  54. our $VERSION = '1.1';
  55. # Locale used via LC_COLLATE when sorting extensions
  56. my $LOCALE = 'en.UTF-8';
  57. # Mime types that are part of the Tomcat
  58. # configuration, but missing from httpd
  59. my %TOMCAT_ONLY = qw(
  60. abs audio/x-mpeg
  61. aim application/x-aim
  62. anx application/annodex
  63. art image/x-jg
  64. avx video/x-rad-screenplay
  65. axa audio/annodex
  66. axv video/annodex
  67. body text/html
  68. dib image/bmp
  69. dv video/x-dv
  70. flac audio/flac
  71. gz application/x-gzip
  72. hqx application/mac-binhex40
  73. htc text/x-component
  74. jsf text/plain
  75. jspf text/plain
  76. m4a audio/mp4
  77. m4b audio/mp4
  78. m4r audio/mp4
  79. mp1 audio/mpeg
  80. mpa audio/mpeg
  81. mac image/x-macpaint
  82. mpega audio/x-mpeg
  83. mpv2 video/mpeg2
  84. pict image/pict
  85. pnt image/x-macpaint
  86. qti image/x-quicktime
  87. qtif image/x-quicktime
  88. shtml text/x-server-parsed-html
  89. ulw audio/basic
  90. z application/x-compress
  91. Z application/x-compress
  92. );
  93. # Mime types, that are defined differently
  94. # in Tomcat than in httpd
  95. my %TOMCAT_KEEP = qw(
  96. cdf application/x-cdf
  97. class application/java
  98. exe application/octet-stream
  99. m4v video/mp4
  100. mif application/x-mif
  101. pct image/pict
  102. pic image/pict
  103. pls audio/x-scpls
  104. );
  105. ################### END VARIABLES WHICH MUST BE MAINTAINED #####################
  106. # Global data variables
  107. # Mime type definitions from httpd
  108. my %httpd;
  109. # Mime type definitions from Tomcat
  110. my %tomcat;
  111. # Comments found when parsing mime type definitions
  112. my %tomcat_comments;
  113. # Is the whole mime type commented out?
  114. my %tomcat_commented;
  115. # List of extensions found in the original order
  116. my @tomcat_extensions;
  117. # Text in web.xml before and after the mime-type definitions
  118. my $tomcat_pre; my $tomcat_post;
  119. # Helper variables
  120. my $i;
  121. my $line;
  122. my $mimetype;
  123. my @extensions;
  124. my $extension;
  125. my $type;
  126. my $comment;
  127. my $commented;
  128. my $msg;
  129. my $previous;
  130. my $current;
  131. # File handles
  132. my $mimetypes_fh;
  133. my $webxml_fh;
  134. my $output_fh;
  135. # Usage/Help
  136. sub HELP_MESSAGE {
  137. my $fh = shift;
  138. print $fh "Usage:: $0 -m MIMEFILE -i INPUTFILE -o OUTPUTFILE\n";
  139. print $fh " MIMEFILE: path to mime.types from the httpd project\n";
  140. print $fh " INPUTFILE: path to existing web.xml, which will be checked\n";
  141. print $fh " OUTPUTFILE: path to the new (generated) web.xml. Any existing\n";
  142. print $fh " file will be overwritten.\n";
  143. }
  144. # Parse arguments:
  145. # -m: mime.types file (httpd) to use
  146. # -i: input web.xml file to check
  147. # -o: output web.xml file (gets generated and overwritten)
  148. $Getopt::Std::STANDARD_HELP_VERSION = 1;
  149. our ($opt_m, $opt_i, $opt_o);
  150. getopts('m:i:o:');
  151. # Check whether mandatory arguments are given
  152. if ($opt_m eq '' || $opt_i eq '' || $opt_o eq '') {
  153. HELP_MESSAGE(*STDOUT);
  154. exit 1;
  155. }
  156. # Switch locale for alphabetical ordering
  157. setlocale(LC_COLLATE, $LOCALE);
  158. # Read and parse httpd mime.types, build up hash extension->mime-type
  159. open($mimetypes_fh, '<', $opt_m) or die "Could not open file '$opt_m' for read - Aborting!";
  160. while (<$mimetypes_fh>) {
  161. chomp($_);
  162. $line = $_;
  163. $line =~ s/#.*//;
  164. $line =~ s/^\s+//;
  165. if ($line ne '') {
  166. ($mimetype, @extensions) = split(/\s+/, $line);
  167. if (@extensions > 0) {
  168. for $extension (@extensions) {
  169. $httpd{$extension} = $mimetype;
  170. }
  171. } else {
  172. print STDERR "WARN mime.types line ignored: $_\n";
  173. }
  174. }
  175. }
  176. close($mimetypes_fh);
  177. # Read and parse web.xml, build up hash extension->mime-type
  178. # and store the file parts form before and after mime mappings.
  179. open($webxml_fh, '<', $opt_i) or die "Could not open file '$opt_i' for read - Aborting!";
  180. # Skip and record all lines before the first mime type definition.
  181. # Because of comment handling we need to read one line ahead.
  182. $line = '';
  183. while (<$webxml_fh>) {
  184. if ($_ !~ /<mime-mapping>/) {
  185. $tomcat_pre .= $line;
  186. } else {
  187. last;
  188. }
  189. $line = $_;
  190. }
  191. $commented = 0;
  192. # If the previous line was start of a comment
  193. # set marker, else add it to pre.
  194. if ($line =~ /^\s*<!--[^>]*$/) {
  195. $commented = 1;
  196. } else {
  197. $tomcat_pre .= $line;
  198. }
  199. # Now we parse blocks of the form:
  200. # <mime-mapping>
  201. # <extension>abs</extension>
  202. # <mime-type>audio/x-mpeg</mime-type>
  203. # </mime-mapping>
  204. # Optional single comment lines directly after "<mime-mapping>"
  205. # are allowed. The whole block is also allowed to be commented out.
  206. while ($_ =~ /^\s*<mime-mapping>\s*$/) {
  207. $_ = <$webxml_fh>;
  208. chomp($_);
  209. $comment = '';
  210. if ($_ =~ /^\s*<!--([^>]*)-->\s*$/) {
  211. $comment = $1;
  212. $_ = <$webxml_fh>;
  213. chomp($_);
  214. }
  215. if ($_ =~ /^\s*<extension>([^<]*)<\/extension>\s*$/ ) {
  216. $extension = $1;
  217. $extension =~ s/^\s+//;
  218. $extension =~ s/\s+$//;
  219. } else {
  220. print STDERR "ERROR Parse error in Tomcat mime-mapping line $.\n";
  221. print STDERR "ERROR Expected <extension>...</extension>', got '$_' - Aborting!\n";
  222. close($webxml_fh);
  223. exit 2;
  224. }
  225. $_ = <$webxml_fh>;
  226. chomp($_);
  227. if ($_ =~ /^\s*<mime-type>([^<]*)<\/mime-type>\s*$/ ) {
  228. $type = $1;
  229. $type =~ s/^\s+//;
  230. $type =~ s/\s+$//;
  231. if (exists($tomcat{$extension}) && $tomcat{$extension} ne $type) {
  232. print STDERR "WARN MIME mapping redefinition detected!\n";
  233. print STDERR "WARN Kept '$extension' -> '$tomcat{$extension}'\n";
  234. print STDERR "WARN Ignored '$extension' -> '$type'\n";
  235. } else {
  236. $tomcat{$extension} = $type;
  237. if ($comment ne '') {
  238. $tomcat_comments{$extension} = $comment;
  239. }
  240. if ($commented) {
  241. $tomcat_commented{$extension} = 1;
  242. }
  243. push(@tomcat_extensions, $extension);
  244. }
  245. } else {
  246. print STDERR "ERROR Parse error in Tomcat mime-mapping line $.\n";
  247. print STDERR "ERROR Expected <mime-type>...</mime-type>', got '$_' - Aborting!\n";
  248. close($webxml_fh);
  249. exit 3;
  250. }
  251. $_ = <$webxml_fh>;
  252. chomp($_);
  253. if ($_ !~ /^\s*<\/mime-mapping>\s*$/) {
  254. print STDERR "ERROR Parse error in Tomcat mime-mapping line $.\n";
  255. print STDERR "ERROR Expected '</mime-mapping>', got '$_' - Aborting!\n";
  256. close($webxml_fh);
  257. exit 4;
  258. }
  259. $_ = <$webxml_fh>;
  260. # Check for comment closure
  261. if ($commented && $_ =~ /^[^<]*-->\s*$/) {
  262. $commented = 0;
  263. $_ = <$webxml_fh>;
  264. }
  265. # Check for comment opening
  266. if ($_ =~ /^\s*<!--[^>]*$/) {
  267. $commented = 1;
  268. $line = $_;
  269. $_ = <$webxml_fh>;
  270. }
  271. }
  272. # Add back the last comment line already digested
  273. if ($commented) {
  274. $tomcat_post = $line;
  275. }
  276. # Read and record the remaining lines
  277. $tomcat_post .= $_;
  278. while (<$webxml_fh>) {
  279. if ($_ =~ /<mime-mapping>/) {
  280. print STDERR "ERROR mime-mapping blocks are not consecutive\n";
  281. print STDERR "ERROR See line $. in $opt_i - Aborting!\n";
  282. close($webxml_fh);
  283. exit 5;
  284. }
  285. $tomcat_post .= $_;
  286. }
  287. close($webxml_fh);
  288. # Look for extensions existing for Tomcat but not for httpd.
  289. # Log them if they are not in TOMCAT_ONLY
  290. for $extension (@tomcat_extensions) {
  291. if (!exists($httpd{$extension})) {
  292. if (!exists($TOMCAT_ONLY{$extension})) {
  293. print STDERR "WARN Extension '$extension' found in web.xml but not in mime.types is missing from TOMCAT_ONLY list.\n";
  294. print STDERR "WARN Definition '$extension' -> '$tomcat{$extension}' will be removed from generated web.xml.\n";
  295. } elsif ($tomcat{$extension} ne $TOMCAT_ONLY{$extension}) {
  296. print STDERR "WARN Additional extension '$extension' allowed by TOMCAT_ONLY list, but has new definition.\n";
  297. print STDERR "WARN Definition '$extension' -> '$tomcat{$extension}' will be replaced" .
  298. " by '$extension' -> '$TOMCAT_ONLY{$extension}' in generated web.xml.\n";
  299. }
  300. }
  301. }
  302. # Look for extensions with inconsistent mime types for Tomcat and httpd.
  303. # Log them if they are not in TOMCAT_KEEP
  304. for $extension (@tomcat_extensions) {
  305. if (exists($httpd{$extension}) && $tomcat{$extension} ne $httpd{$extension}) {
  306. if (!exists($TOMCAT_KEEP{$extension})) {
  307. print STDERR "WARN Mapping '$extension' inconsistency is missing from TOMCAT_KEEP list.\n";
  308. print STDERR "WARN Definition '$extension' -> '$tomcat{$extension}' will be replaced" .
  309. " by '$extension' -> '$httpd{$extension}' in generated web.xml.\n";
  310. } elsif ($tomcat{$extension} ne $TOMCAT_KEEP{$extension}) {
  311. print STDERR "WARN Extension '$extension' inconsistency allowed by TOMCAT_KEEP list, but has new definition.\n";
  312. print STDERR "WARN Definition '$extension' -> '$tomcat{$extension}' will be replaced" .
  313. " by '$extension' -> '$TOMCAT_KEEP{$extension}' in generated web.xml.\n";
  314. }
  315. }
  316. }
  317. # Log if extensions in web.xml are not sorted alphabetically.
  318. $msg = '';
  319. $previous = '';
  320. for $current (@tomcat_extensions) {
  321. if ($previous ge $current) {
  322. $msg .= "WARN Extension '$previous' defined before '$current'\n";
  323. }
  324. $previous = $current;
  325. }
  326. if ($msg ne '') {
  327. print STDERR "WARN MIME type definitions in web.xml were not sorted alphabetically by extension\n";
  328. print STDERR $msg;
  329. print STDERR "WARN This will be fixed in the new generated web.xml file '$opt_o'.\n";
  330. }
  331. # Log all extensions defined for httpd but not for Tomcat
  332. for $extension (sort keys %httpd) {
  333. if (!exists($tomcat{$extension})) {
  334. print STDERR "INFO Extension '$extension' found for httpd, but not for Tomcat.\n";
  335. print STDERR "INFO Definition '$extension' -> '$httpd{$extension}' will be added" .
  336. " to the generated web.xml.\n";
  337. }
  338. }
  339. # Generate new web.xml:
  340. # - Use definitions from httpd
  341. # - Add TOMCAT_ONLY
  342. # - Fix TOMCAT_KEEP
  343. # - output tomcat_pre, sorted mime-mappings, tomcat_post.
  344. while (($extension, $mimetype) = each %TOMCAT_ONLY) {
  345. $httpd{$extension} = $mimetype;
  346. }
  347. while (($extension, $mimetype) = each %TOMCAT_KEEP) {
  348. $httpd{$extension} = $mimetype;
  349. }
  350. open ($output_fh, '>', $opt_o) or die "Could not open file '$opt_o' for write - Aborting!";
  351. print $output_fh $tomcat_pre;
  352. for $extension (sort keys %httpd) {
  353. if (exists($tomcat_commented{$extension})) {
  354. print $output_fh " <!--\n";
  355. }
  356. print $output_fh " <mime-mapping>\n";
  357. if (exists($tomcat_comments{$extension})) {
  358. print $output_fh " <!--$tomcat_comments{$extension}-->\n";
  359. }
  360. print $output_fh " <extension>$extension</extension>\n";
  361. print $output_fh " <mime-type>$httpd{$extension}</mime-type>\n";
  362. print $output_fh " </mime-mapping>\n";
  363. if (exists($tomcat_commented{$extension})) {
  364. print $output_fh " -->\n";
  365. }
  366. }
  367. print $output_fh $tomcat_post;
  368. close($output_fh);
  369. print "New file '$opt_o' has been written.\n";