Align MimeMappings with Tomcat's defaults

Update `MimeMappings` to align with the default values used in
Tomcat. The mime mapping are now loaded from a properties file
and a test has been added to ensure that they remain in sync
with Tomcat's defaults.

See gh-32101
pull/32162/head
Guirong Hu 2 years ago committed by Phillip Webb
parent c67010ddd1
commit 7728ae4e00

@ -16,12 +16,16 @@
package org.springframework.boot.web.server; package org.springframework.boot.web.server;
import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -40,183 +44,16 @@ public final class MimeMappings implements Iterable<MimeMappings.Mapping> {
static { static {
MimeMappings mappings = new MimeMappings(); MimeMappings mappings = new MimeMappings();
mappings.add("abs", "audio/x-mpeg"); try {
mappings.add("ai", "application/postscript"); Properties defaultMimeMappings = PropertiesLoaderUtils
mappings.add("aif", "audio/x-aiff"); .loadProperties(new ClassPathResource("mime-mappings.properties", MimeMappings.class));
mappings.add("aifc", "audio/x-aiff"); for (String extension : defaultMimeMappings.stringPropertyNames()) {
mappings.add("aiff", "audio/x-aiff"); mappings.add(extension, defaultMimeMappings.getProperty(extension));
mappings.add("aim", "application/x-aim"); }
mappings.add("art", "image/x-jg"); }
mappings.add("asf", "video/x-ms-asf"); catch (IOException ex) {
mappings.add("asx", "video/x-ms-asf"); throw new IllegalArgumentException("Unable to load the default MIME types", ex);
mappings.add("au", "audio/basic"); }
mappings.add("avi", "video/x-msvideo");
mappings.add("avx", "video/x-rad-screenplay");
mappings.add("bcpio", "application/x-bcpio");
mappings.add("bin", "application/octet-stream");
mappings.add("bmp", "image/bmp");
mappings.add("body", "text/html");
mappings.add("cdf", "application/x-cdf");
mappings.add("cer", "application/pkix-cert");
mappings.add("class", "application/java");
mappings.add("cpio", "application/x-cpio");
mappings.add("csh", "application/x-csh");
mappings.add("css", "text/css");
mappings.add("dib", "image/bmp");
mappings.add("doc", "application/msword");
mappings.add("dtd", "application/xml-dtd");
mappings.add("dv", "video/x-dv");
mappings.add("dvi", "application/x-dvi");
mappings.add("eot", "application/vnd.ms-fontobject");
mappings.add("eps", "application/postscript");
mappings.add("etx", "text/x-setext");
mappings.add("exe", "application/octet-stream");
mappings.add("gif", "image/gif");
mappings.add("gtar", "application/x-gtar");
mappings.add("gz", "application/x-gzip");
mappings.add("hdf", "application/x-hdf");
mappings.add("hqx", "application/mac-binhex40");
mappings.add("htc", "text/x-component");
mappings.add("htm", "text/html");
mappings.add("html", "text/html");
mappings.add("ief", "image/ief");
mappings.add("jad", "text/vnd.sun.j2me.app-descriptor");
mappings.add("jar", "application/java-archive");
mappings.add("java", "text/x-java-source");
mappings.add("jnlp", "application/x-java-jnlp-file");
mappings.add("jpe", "image/jpeg");
mappings.add("jpeg", "image/jpeg");
mappings.add("jpg", "image/jpeg");
mappings.add("js", "application/javascript");
mappings.add("jsf", "text/plain");
mappings.add("json", "application/json");
mappings.add("jspf", "text/plain");
mappings.add("kar", "audio/midi");
mappings.add("latex", "application/x-latex");
mappings.add("m3u", "audio/x-mpegurl");
mappings.add("mac", "image/x-macpaint");
mappings.add("man", "text/troff");
mappings.add("mathml", "application/mathml+xml");
mappings.add("me", "text/troff");
mappings.add("mid", "audio/midi");
mappings.add("midi", "audio/midi");
mappings.add("mif", "application/x-mif");
mappings.add("mov", "video/quicktime");
mappings.add("movie", "video/x-sgi-movie");
mappings.add("mp1", "audio/mpeg");
mappings.add("mp2", "audio/mpeg");
mappings.add("mp3", "audio/mpeg");
mappings.add("mp4", "video/mp4");
mappings.add("mpa", "audio/mpeg");
mappings.add("mpe", "video/mpeg");
mappings.add("mpeg", "video/mpeg");
mappings.add("mpega", "audio/x-mpeg");
mappings.add("mpg", "video/mpeg");
mappings.add("mpv2", "video/mpeg2");
mappings.add("ms", "application/x-wais-source");
mappings.add("nc", "application/x-netcdf");
mappings.add("oda", "application/oda");
mappings.add("odb", "application/vnd.oasis.opendocument.database");
mappings.add("odc", "application/vnd.oasis.opendocument.chart");
mappings.add("odf", "application/vnd.oasis.opendocument.formula");
mappings.add("odg", "application/vnd.oasis.opendocument.graphics");
mappings.add("odi", "application/vnd.oasis.opendocument.image");
mappings.add("odm", "application/vnd.oasis.opendocument.text-master");
mappings.add("odp", "application/vnd.oasis.opendocument.presentation");
mappings.add("ods", "application/vnd.oasis.opendocument.spreadsheet");
mappings.add("odt", "application/vnd.oasis.opendocument.text");
mappings.add("otg", "application/vnd.oasis.opendocument.graphics-template");
mappings.add("oth", "application/vnd.oasis.opendocument.text-web");
mappings.add("otp", "application/vnd.oasis.opendocument.presentation-template");
mappings.add("ots", "application/vnd.oasis.opendocument.spreadsheet-template");
mappings.add("ott", "application/vnd.oasis.opendocument.text-template");
mappings.add("ogx", "application/ogg");
mappings.add("ogv", "video/ogg");
mappings.add("oga", "audio/ogg");
mappings.add("ogg", "audio/ogg");
mappings.add("otf", "application/x-font-opentype");
mappings.add("spx", "audio/ogg");
mappings.add("flac", "audio/flac");
mappings.add("anx", "application/annodex");
mappings.add("axa", "audio/annodex");
mappings.add("axv", "video/annodex");
mappings.add("xspf", "application/xspf+xml");
mappings.add("pbm", "image/x-portable-bitmap");
mappings.add("pct", "image/pict");
mappings.add("pdf", "application/pdf");
mappings.add("pgm", "image/x-portable-graymap");
mappings.add("pic", "image/pict");
mappings.add("pict", "image/pict");
mappings.add("pls", "audio/x-scpls");
mappings.add("png", "image/png");
mappings.add("pnm", "image/x-portable-anymap");
mappings.add("pnt", "image/x-macpaint");
mappings.add("ppm", "image/x-portable-pixmap");
mappings.add("ppt", "application/vnd.ms-powerpoint");
mappings.add("pps", "application/vnd.ms-powerpoint");
mappings.add("ps", "application/postscript");
mappings.add("psd", "image/vnd.adobe.photoshop");
mappings.add("qt", "video/quicktime");
mappings.add("qti", "image/x-quicktime");
mappings.add("qtif", "image/x-quicktime");
mappings.add("ras", "image/x-cmu-raster");
mappings.add("rdf", "application/rdf+xml");
mappings.add("rgb", "image/x-rgb");
mappings.add("rm", "application/vnd.rn-realmedia");
mappings.add("roff", "text/troff");
mappings.add("rtf", "application/rtf");
mappings.add("rtx", "text/richtext");
mappings.add("sfnt", "application/font-sfnt");
mappings.add("sh", "application/x-sh");
mappings.add("shar", "application/x-shar");
mappings.add("sit", "application/x-stuffit");
mappings.add("snd", "audio/basic");
mappings.add("src", "application/x-wais-source");
mappings.add("sv4cpio", "application/x-sv4cpio");
mappings.add("sv4crc", "application/x-sv4crc");
mappings.add("svg", "image/svg+xml");
mappings.add("svgz", "image/svg+xml");
mappings.add("swf", "application/x-shockwave-flash");
mappings.add("t", "text/troff");
mappings.add("tar", "application/x-tar");
mappings.add("tcl", "application/x-tcl");
mappings.add("tex", "application/x-tex");
mappings.add("texi", "application/x-texinfo");
mappings.add("texinfo", "application/x-texinfo");
mappings.add("tif", "image/tiff");
mappings.add("tiff", "image/tiff");
mappings.add("tr", "text/troff");
mappings.add("tsv", "text/tab-separated-values");
mappings.add("ttf", "application/x-font-ttf");
mappings.add("txt", "text/plain");
mappings.add("ulw", "audio/basic");
mappings.add("ustar", "application/x-ustar");
mappings.add("vxml", "application/voicexml+xml");
mappings.add("xbm", "image/x-xbitmap");
mappings.add("xht", "application/xhtml+xml");
mappings.add("xhtml", "application/xhtml+xml");
mappings.add("xls", "application/vnd.ms-excel");
mappings.add("xml", "application/xml");
mappings.add("xpm", "image/x-xpixmap");
mappings.add("xsl", "application/xml");
mappings.add("xslt", "application/xslt+xml");
mappings.add("xul", "application/vnd.mozilla.xul+xml");
mappings.add("xwd", "image/x-xwindowdump");
mappings.add("vsd", "application/vnd.visio");
mappings.add("wasm", "application/wasm");
mappings.add("wav", "audio/x-wav");
mappings.add("wbmp", "image/vnd.wap.wbmp");
mappings.add("wml", "text/vnd.wap.wml");
mappings.add("wmlc", "application/vnd.wap.wmlc");
mappings.add("wmls", "text/vnd.wap.wmlsc");
mappings.add("wmlscriptc", "application/vnd.wap.wmlscriptc");
mappings.add("wmv", "video/x-ms-wmv");
mappings.add("woff", "application/font-woff");
mappings.add("woff2", "application/font-woff2");
mappings.add("wrl", "model/vrml");
mappings.add("wspolicy", "application/wspolicy+xml");
mappings.add("z", "application/x-compress");
mappings.add("zip", "application/zip");
DEFAULT = unmodifiableMappings(mappings); DEFAULT = unmodifiableMappings(mappings);
} }

@ -45,6 +45,7 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@ -77,6 +78,7 @@ import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
@ -134,6 +136,7 @@ import org.springframework.boot.web.servlet.server.Session.SessionTrackingMode;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequest;
@ -958,6 +961,20 @@ public abstract class AbstractServletWebServerFactoryTests {
assertThat(configuredMimeMappings.size()).isEqualTo(expectedMimeMappings.size()); assertThat(configuredMimeMappings.size()).isEqualTo(expectedMimeMappings.size());
} }
@Test
void mimeMappingsContainsDefaultsOfTomcat() throws IOException {
AbstractServletWebServerFactory factory = getFactory();
this.webServer = factory.getWebServer();
Map<String, String> configuredMimeMappings = getActualMimeMappings();
// override defaults, see org.apache.catalina.startup.MimeTypeMappings.properties
Properties tomcatDefaultMimeMappings = PropertiesLoaderUtils
.loadProperties(new ClassPathResource("MimeTypeMappings.properties", Tomcat.class));
for (String extension : tomcatDefaultMimeMappings.stringPropertyNames()) {
assertThat(configuredMimeMappings).containsEntry(extension,
tomcatDefaultMimeMappings.getProperty(extension));
}
}
@Test @Test
void rootServletContextResource() { void rootServletContextResource() {
AbstractServletWebServerFactory factory = getFactory(); AbstractServletWebServerFactory factory = getFactory();

Loading…
Cancel
Save