Merge pull request #32101 from terminux

* pr/32101:
  Polish 'Align MimeMappings with Tomcat's defaults'
  Align MimeMappings with Tomcat's defaults

Closes gh-32101
This commit is contained in:
Phillip Webb 2022-08-23 11:38:21 -07:00
commit 90b68d8465
8 changed files with 1396 additions and 225 deletions

View File

@ -17,6 +17,7 @@
package org.springframework.boot.web.embedded.tomcat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@ -30,6 +31,7 @@ import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardWrapper;
import org.apache.catalina.session.ManagerBase;
import org.springframework.boot.web.server.MimeMappings;
import org.springframework.boot.web.server.WebServerException;
import org.springframework.util.ClassUtils;
@ -44,6 +46,8 @@ class TomcatEmbeddedContext extends StandardContext {
private TomcatStarter starter;
private MimeMappings mimeMappings;
@Override
public boolean loadOnStartup(Container[] children) {
// deferred until later (see deferredLoadOnStartup)
@ -118,4 +122,27 @@ class TomcatEmbeddedContext extends StandardContext {
return this.starter;
}
void setMimeMappings(MimeMappings mimeMappings) {
this.mimeMappings = mimeMappings;
}
@Override
public String[] findMimeMappings() {
List<String> mappings = new ArrayList<>();
mappings.addAll(Arrays.asList(super.findMimeMappings()));
if (this.mimeMappings != null) {
this.mimeMappings.forEach((mapping) -> mappings.add(mapping.getExtension()));
}
return mappings.toArray(String[]::new);
}
@Override
public String findMimeMapping(String extension) {
String mimeMapping = super.findMimeMapping(extension);
if (mimeMapping != null) {
return mimeMapping;
}
return (this.mimeMappings != null) ? this.mimeMappings.get(extension) : null;
}
}

View File

@ -389,9 +389,7 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
tomcatErrorPage.setExceptionType(errorPage.getExceptionName());
context.addErrorPage(tomcatErrorPage);
}
for (MimeMappings.Mapping mapping : getMimeMappings()) {
context.addMimeMapping(mapping.getExtension(), mapping.getMimeType());
}
setMimeMappings(context);
configureSession(context);
configureCookieProcessor(context);
new DisableReferenceClearingContextCustomizer().customize(context);
@ -423,6 +421,16 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
}
}
private void setMimeMappings(Context context) {
if (context instanceof TomcatEmbeddedContext embeddedContext) {
embeddedContext.setMimeMappings(getMimeMappings());
return;
}
for (MimeMappings.Mapping mapping : getMimeMappings()) {
context.addMimeMapping(mapping.getExtension(), mapping.getMimeType());
}
}
private void configureCookieProcessor(Context context) {
SameSite sessionSameSite = getSession().getCookie().getSameSite();
List<CookieSameSiteSupplier> suppliers = new ArrayList<>();

View File

@ -16,12 +16,20 @@
package org.springframework.boot.web.server;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
/**
@ -29,196 +37,15 @@ import org.springframework.util.Assert;
* {@literal &lt;mime-mapping&gt;} element traditionally found in web.xml.
*
* @author Phillip Webb
* @author Guirong Hu
* @since 2.0.0
*/
public final class MimeMappings implements Iterable<MimeMappings.Mapping> {
public sealed class MimeMappings implements Iterable<MimeMappings.Mapping> {
/**
* Default mime mapping commonly used.
*/
public static final MimeMappings DEFAULT;
static {
MimeMappings mappings = new MimeMappings();
mappings.add("abs", "audio/x-mpeg");
mappings.add("ai", "application/postscript");
mappings.add("aif", "audio/x-aiff");
mappings.add("aifc", "audio/x-aiff");
mappings.add("aiff", "audio/x-aiff");
mappings.add("aim", "application/x-aim");
mappings.add("art", "image/x-jg");
mappings.add("asf", "video/x-ms-asf");
mappings.add("asx", "video/x-ms-asf");
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);
}
public static final MimeMappings DEFAULT = new DefaultMimeMappings();
private final Map<String, Mapping> map;
@ -253,14 +80,44 @@ public final class MimeMappings implements Iterable<MimeMappings.Mapping> {
* @param mappings source mappings
* @param mutable if the new object should be mutable.
*/
private MimeMappings(MimeMappings mappings, boolean mutable) {
MimeMappings(MimeMappings mappings, boolean mutable) {
Assert.notNull(mappings, "Mappings must not be null");
this.map = (mutable ? new LinkedHashMap<>(mappings.map) : Collections.unmodifiableMap(mappings.map));
}
@Override
public Iterator<Mapping> iterator() {
return getAll().iterator();
/**
* Add a new mime mapping.
* @param extension the file extension (excluding '.')
* @param mimeType the mime type to map
* @return any previous mapping or {@code null}
*/
public String add(String extension, String mimeType) {
Assert.notNull(extension, "Extension must not be null");
Assert.notNull(mimeType, "MimeType must not be null");
Mapping previous = this.map.put(extension.toLowerCase(Locale.ENGLISH), new Mapping(extension, mimeType));
return (previous != null) ? previous.getMimeType() : null;
}
/**
* Remove an existing mapping.
* @param extension the file extension (excluding '.')
* @return the removed mime mapping or {@code null} if no item was removed
*/
public String remove(String extension) {
Assert.notNull(extension, "Extension must not be null");
Mapping previous = this.map.remove(extension.toLowerCase(Locale.ENGLISH));
return (previous != null) ? previous.getMimeType() : null;
}
/**
* Get a mime mapping for the given extension.
* @param extension the file extension (excluding '.')
* @return a mime mapping or {@code null}
*/
public String get(String extension) {
Assert.notNull(extension, "Extension must not be null");
Mapping mapping = this.map.get(extension.toLowerCase(Locale.ENGLISH));
return (mapping != null) ? mapping.getMimeType() : null;
}
/**
@ -271,35 +128,9 @@ public final class MimeMappings implements Iterable<MimeMappings.Mapping> {
return this.map.values();
}
/**
* Add a new mime mapping.
* @param extension the file extension (excluding '.')
* @param mimeType the mime type to map
* @return any previous mapping or {@code null}
*/
public String add(String extension, String mimeType) {
Mapping previous = this.map.put(extension, new Mapping(extension, mimeType));
return (previous != null) ? previous.getMimeType() : null;
}
/**
* Get a mime mapping for the given extension.
* @param extension the file extension (excluding '.')
* @return a mime mapping or {@code null}
*/
public String get(String extension) {
Mapping mapping = this.map.get(extension);
return (mapping != null) ? mapping.getMimeType() : null;
}
/**
* Remove an existing mapping.
* @param extension the file extension (excluding '.')
* @return the removed mime mapping or {@code null} if no item was removed
*/
public String remove(String extension) {
Mapping previous = this.map.remove(extension);
return (previous != null) ? previous.getMimeType() : null;
@Override
public final Iterator<Mapping> iterator() {
return getAll().iterator();
}
@Override
@ -311,14 +142,18 @@ public final class MimeMappings implements Iterable<MimeMappings.Mapping> {
return true;
}
if (obj instanceof MimeMappings other) {
return this.map.equals(other.map);
return getMap().equals(other.map);
}
return false;
}
@Override
public int hashCode() {
return this.map.hashCode();
return getMap().hashCode();
}
Map<String, Mapping> getMap() {
return this.map;
}
/**
@ -328,9 +163,22 @@ public final class MimeMappings implements Iterable<MimeMappings.Mapping> {
* @return an unmodifiable view of the specified mappings.
*/
public static MimeMappings unmodifiableMappings(MimeMappings mappings) {
Assert.notNull(mappings, "Mappings must not be null");
return new MimeMappings(mappings, false);
}
/**
* Crate a new lazy copy of the given mappings will only copy entries if the mappings
* are mutated.
* @param mappings the source mappings
* @return a new mappings instance
* @since 3.0.0
*/
public static MimeMappings lazyCopy(MimeMappings mappings) {
Assert.notNull(mappings, "Mappings must not be null");
return new LazyMimeMappingsCopy(mappings);
}
/**
* A single mime mapping.
*/
@ -381,4 +229,175 @@ public final class MimeMappings implements Iterable<MimeMappings.Mapping> {
}
/**
* {@link MimeMappings} implementation used for {@link MimeMappings#DEFAULT}. Provides
* in-memory access for common mappings and lazily loads the complete set when
* necessary.
*/
static final class DefaultMimeMappings extends MimeMappings {
static final String MIME_MAPPINGS_PROPERTIES = "mime-mappings.properties";
private static final MimeMappings COMMON;
static {
MimeMappings mappings = new MimeMappings();
mappings.add("avi", "video/x-msvideo");
mappings.add("bin", "application/octet-stream");
mappings.add("body", "text/html");
mappings.add("class", "application/java");
mappings.add("css", "text/css");
mappings.add("dtd", "application/xml-dtd");
mappings.add("gif", "image/gif");
mappings.add("gtar", "application/x-gtar");
mappings.add("gz", "application/x-gzip");
mappings.add("htm", "text/html");
mappings.add("html", "text/html");
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("json", "application/json");
mappings.add("otf", "application/x-font-opentype");
mappings.add("pdf", "application/pdf");
mappings.add("png", "image/png");
mappings.add("ps", "application/postscript");
mappings.add("tar", "application/x-tar");
mappings.add("tif", "image/tiff");
mappings.add("tiff", "image/tiff");
mappings.add("ttf", "application/x-font-ttf");
mappings.add("txt", "text/plain");
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("xsl", "application/xml");
mappings.add("xslt", "application/xslt+xml");
mappings.add("wasm", "application/wasm");
mappings.add("zip", "application/zip");
COMMON = unmodifiableMappings(mappings);
}
private volatile Map<String, Mapping> loaded;
DefaultMimeMappings() {
super(new MimeMappings(), false);
}
@Override
public Collection<Mapping> getAll() {
return load().values();
}
@Override
public String get(String extension) {
Assert.notNull(extension, "Extension must not be null");
extension = extension.toLowerCase(Locale.ENGLISH);
Map<String, Mapping> loaded = this.loaded;
if (loaded != null) {
return get(loaded, extension);
}
String commonMimeType = COMMON.get(extension);
if (commonMimeType != null) {
return commonMimeType;
}
loaded = load();
return get(loaded, extension);
}
private String get(Map<String, Mapping> mappings, String extension) {
Mapping mapping = mappings.get(extension);
return (mapping != null) ? mapping.getMimeType() : null;
}
@Override
Map<String, Mapping> getMap() {
return load();
}
private Map<String, Mapping> load() {
Map<String, Mapping> loaded = this.loaded;
if (loaded != null) {
return loaded;
}
try {
loaded = new LinkedHashMap<>();
for (Entry<?, ?> entry : PropertiesLoaderUtils
.loadProperties(new ClassPathResource(MIME_MAPPINGS_PROPERTIES, getClass())).entrySet()) {
loaded.put((String) entry.getKey(),
new Mapping((String) entry.getKey(), (String) entry.getValue()));
}
loaded = Collections.unmodifiableMap(loaded);
this.loaded = loaded;
return loaded;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load the default MIME types", ex);
}
}
}
/**
* {@link MimeMappings} implementation used to create a lazy copy only when the
* mappings are mutated.
*/
static final class LazyMimeMappingsCopy extends MimeMappings {
private final MimeMappings source;
private AtomicBoolean copied = new AtomicBoolean();
LazyMimeMappingsCopy(MimeMappings source) {
this.source = source;
}
@Override
public String add(String extension, String mimeType) {
copyIfNecessary();
return super.add(extension, mimeType);
}
@Override
public String remove(String extension) {
copyIfNecessary();
return super.remove(extension);
}
private void copyIfNecessary() {
if (this.copied.compareAndSet(false, true)) {
this.source.forEach((mapping) -> add(mapping.getExtension(), mapping.getMimeType()));
}
}
@Override
public String get(String extension) {
return !this.copied.get() ? this.source.get(extension) : super.get(extension);
}
@Override
public Collection<Mapping> getAll() {
return !this.copied.get() ? this.source.getAll() : super.getAll();
}
@Override
Map<String, Mapping> getMap() {
return !this.copied.get() ? this.source.getMap() : super.getMap();
}
}
static class MimeMappingsRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.resources().registerPattern(
"org/springframework/boot/web/server/" + DefaultMimeMappings.MIME_MAPPINGS_PROPERTIES);
}
}
}

View File

@ -69,7 +69,7 @@ public abstract class AbstractServletWebServerFactory extends AbstractConfigurab
private boolean registerDefaultServlet = false;
private MimeMappings mimeMappings = new MimeMappings(MimeMappings.DEFAULT);
private MimeMappings mimeMappings = MimeMappings.lazyCopy(MimeMappings.DEFAULT);
private List<ServletContextInitializer> initializers = new ArrayList<>();
@ -173,6 +173,7 @@ public abstract class AbstractServletWebServerFactory extends AbstractConfigurab
@Override
public void setMimeMappings(MimeMappings mimeMappings) {
Assert.notNull(mimeMappings, "MimeMappings must not be null");
this.mimeMappings = new MimeMappings(mimeMappings);
}

View File

@ -1,11 +1,12 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.boot.SpringApplication.SpringApplicationRuntimeHints,\
org.springframework.boot.WebApplicationType.WebApplicationTypeRuntimeHints,\
org.springframework.boot.context.config.ConfigDataLocationRuntimeHints,\
org.springframework.boot.env.PropertySourceRuntimeHints,\
org.springframework.boot.json.JacksonRuntimeHints,\
org.springframework.boot.logging.java.JavaLoggingSystemRuntimeHints,\
org.springframework.boot.logging.logback.LogbackRuntimeHints,\
org.springframework.boot.SpringApplication.SpringApplicationRuntimeHints,\
org.springframework.boot.WebApplicationType.WebApplicationTypeRuntimeHints
org.springframework.boot.web.server.MimeMappings.MimeMappingsRuntimeHints
org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=\
org.springframework.boot.context.properties.ConfigurationPropertiesBeanFactoryInitializationAotProcessor

View File

@ -0,0 +1,1025 @@
# Copyright 2012-2022 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
123=application/vnd.lotus-1-2-3
3dml=text/vnd.in3d.3dml
3ds=image/x-3ds
3g2=video/3gpp2
3gp=video/3gpp
7z=application/x-7z-compressed
aab=application/x-authorware-bin
aac=audio/x-aac
aam=application/x-authorware-map
aas=application/x-authorware-seg
abs=audio/x-mpeg
abw=application/x-abiword
ac=application/pkix-attr-cert
acc=application/vnd.americandynamics.acc
ace=application/x-ace-compressed
acu=application/vnd.acucobol
acutc=application/vnd.acucorp
adp=audio/adpcm
aep=application/vnd.audiograph
afm=application/x-font-type1
afp=application/vnd.ibm.modcap
ahead=application/vnd.ahead.space
ai=application/postscript
aif=audio/x-aiff
aifc=audio/x-aiff
aiff=audio/x-aiff
aim=application/x-aim
air=application/vnd.adobe.air-application-installer-package+zip
ait=application/vnd.dvb.ait
ami=application/vnd.amiga.ami
anx=application/annodex
apk=application/vnd.android.package-archive
appcache=text/cache-manifest
application=application/x-ms-application
apr=application/vnd.lotus-approach
arc=application/x-freearc
art=image/x-jg
asc=application/pgp-signature
asf=video/x-ms-asf
asm=text/x-asm
aso=application/vnd.accpac.simply.aso
asx=video/x-ms-asf
atc=application/vnd.acucorp
atom=application/atom+xml
atomcat=application/atomcat+xml
atomsvc=application/atomsvc+xml
atx=application/vnd.antix.game-component
au=audio/basic
avi=video/x-msvideo
avx=video/x-rad-screenplay
aw=application/applixware
axa=audio/annodex
axv=video/annodex
azf=application/vnd.airzip.filesecure.azf
azs=application/vnd.airzip.filesecure.azs
azw=application/vnd.amazon.ebook
bat=application/x-msdownload
bcpio=application/x-bcpio
bdf=application/x-font-bdf
bdm=application/vnd.syncml.dm+wbxml
bed=application/vnd.realvnc.bed
bh2=application/vnd.fujitsu.oasysprs
bin=application/octet-stream
blb=application/x-blorb
blorb=application/x-blorb
bmi=application/vnd.bmi
bmp=image/bmp
body=text/html
book=application/vnd.framemaker
box=application/vnd.previewsystems.box
boz=application/x-bzip2
bpk=application/octet-stream
btif=image/prs.btif
bz=application/x-bzip
bz2=application/x-bzip2
c=text/x-c
c11amc=application/vnd.cluetrust.cartomobile-config
c11amz=application/vnd.cluetrust.cartomobile-config-pkg
c4d=application/vnd.clonk.c4group
c4f=application/vnd.clonk.c4group
c4g=application/vnd.clonk.c4group
c4p=application/vnd.clonk.c4group
c4u=application/vnd.clonk.c4group
cab=application/vnd.ms-cab-compressed
caf=audio/x-caf
cap=application/vnd.tcpdump.pcap
car=application/vnd.curl.car
cat=application/vnd.ms-pki.seccat
cb7=application/x-cbr
cba=application/x-cbr
cbr=application/x-cbr
cbt=application/x-cbr
cbz=application/x-cbr
cc=text/x-c
cct=application/x-director
ccxml=application/ccxml+xml
cdbcmsg=application/vnd.contact.cmsg
cdf=application/x-cdf
cdkey=application/vnd.mediastation.cdkey
cdmia=application/cdmi-capability
cdmic=application/cdmi-container
cdmid=application/cdmi-domain
cdmio=application/cdmi-object
cdmiq=application/cdmi-queue
cdx=chemical/x-cdx
cdxml=application/vnd.chemdraw+xml
cdy=application/vnd.cinderella
cer=application/pkix-cert
cfs=application/x-cfs-compressed
cgm=image/cgm
chat=application/x-chat
chm=application/vnd.ms-htmlhelp
chrt=application/vnd.kde.kchart
cif=chemical/x-cif
cii=application/vnd.anser-web-certificate-issue-initiation
cil=application/vnd.ms-artgalry
cla=application/vnd.claymore
class=application/java
clkk=application/vnd.crick.clicker.keyboard
clkp=application/vnd.crick.clicker.palette
clkt=application/vnd.crick.clicker.template
clkw=application/vnd.crick.clicker.wordbank
clkx=application/vnd.crick.clicker
clp=application/x-msclip
cmc=application/vnd.cosmocaller
cmdf=chemical/x-cmdf
cml=chemical/x-cml
cmp=application/vnd.yellowriver-custom-menu
cmx=image/x-cmx
cod=application/vnd.rim.cod
com=application/x-msdownload
conf=text/plain
cpio=application/x-cpio
cpp=text/x-c
cpt=application/mac-compactpro
crd=application/x-mscardfile
crl=application/pkix-crl
crt=application/x-x509-ca-cert
cryptonote=application/vnd.rig.cryptonote
csh=application/x-csh
csml=chemical/x-csml
csp=application/vnd.commonspace
css=text/css
cst=application/x-director
csv=text/csv
cu=application/cu-seeme
curl=text/vnd.curl
cww=application/prs.cww
cxt=application/x-director
cxx=text/x-c
dae=model/vnd.collada+xml
daf=application/vnd.mobius.daf
dart=application/vnd.dart
dataless=application/vnd.fdsn.seed
davmount=application/davmount+xml
dbk=application/docbook+xml
dcr=application/x-director
dcurl=text/vnd.curl.dcurl
dd2=application/vnd.oma.dd2+xml
ddd=application/vnd.fujixerox.ddd
deb=application/x-debian-package
def=text/plain
deploy=application/octet-stream
der=application/x-x509-ca-cert
dfac=application/vnd.dreamfactory
dgc=application/x-dgc-compressed
dib=image/bmp
dic=text/x-c
dir=application/x-director
dis=application/vnd.mobius.dis
dist=application/octet-stream
distz=application/octet-stream
djv=image/vnd.djvu
djvu=image/vnd.djvu
dll=application/x-msdownload
dmg=application/x-apple-diskimage
dmp=application/vnd.tcpdump.pcap
dms=application/octet-stream
dna=application/vnd.dna
doc=application/msword
docm=application/vnd.ms-word.document.macroenabled.12
docx=application/vnd.openxmlformats-officedocument.wordprocessingml.document
dot=application/msword
dotm=application/vnd.ms-word.template.macroenabled.12
dotx=application/vnd.openxmlformats-officedocument.wordprocessingml.template
dp=application/vnd.osgi.dp
dpg=application/vnd.dpgraph
dra=audio/vnd.dra
dsc=text/prs.lines.tag
dssc=application/dssc+der
dtb=application/x-dtbook+xml
dtd=application/xml-dtd
dts=audio/vnd.dts
dtshd=audio/vnd.dts.hd
dump=application/octet-stream
dv=video/x-dv
dvb=video/vnd.dvb.file
dvi=application/x-dvi
dwf=model/vnd.dwf
dwg=image/vnd.dwg
dxf=image/vnd.dxf
dxp=application/vnd.spotfire.dxp
dxr=application/x-director
ecelp4800=audio/vnd.nuera.ecelp4800
ecelp7470=audio/vnd.nuera.ecelp7470
ecelp9600=audio/vnd.nuera.ecelp9600
ecma=application/ecmascript
edm=application/vnd.novadigm.edm
edx=application/vnd.novadigm.edx
efif=application/vnd.picsel
ei6=application/vnd.pg.osasli
elc=application/octet-stream
emf=application/x-msmetafile
eml=message/rfc822
emma=application/emma+xml
emz=application/x-msmetafile
eol=audio/vnd.digital-winds
eot=application/vnd.ms-fontobject
eps=application/postscript
epub=application/epub+zip
es3=application/vnd.eszigno3+xml
esa=application/vnd.osgi.subsystem
esf=application/vnd.epson.esf
et3=application/vnd.eszigno3+xml
etx=text/x-setext
eva=application/x-eva
evy=application/x-envoy
exe=application/octet-stream
exi=application/exi
ext=application/vnd.novadigm.ext
ez=application/andrew-inset
ez2=application/vnd.ezpix-album
ez3=application/vnd.ezpix-package
f=text/x-fortran
f4v=video/x-f4v
f77=text/x-fortran
f90=text/x-fortran
fbs=image/vnd.fastbidsheet
fcdt=application/vnd.adobe.formscentral.fcdt
fcs=application/vnd.isac.fcs
fdf=application/vnd.fdf
fe_launch=application/vnd.denovo.fcselayout-link
fg5=application/vnd.fujitsu.oasysgp
fgd=application/x-director
fh=image/x-freehand
fh4=image/x-freehand
fh5=image/x-freehand
fh7=image/x-freehand
fhc=image/x-freehand
fig=application/x-xfig
flac=audio/flac
fli=video/x-fli
flo=application/vnd.micrografx.flo
flv=video/x-flv
flw=application/vnd.kde.kivio
flx=text/vnd.fmi.flexstor
fly=text/vnd.fly
fm=application/vnd.framemaker
fnc=application/vnd.frogans.fnc
for=text/x-fortran
fpx=image/vnd.fpx
frame=application/vnd.framemaker
fsc=application/vnd.fsc.weblaunch
fst=image/vnd.fst
ftc=application/vnd.fluxtime.clip
fti=application/vnd.anser-web-funds-transfer-initiation
fvt=video/vnd.fvt
fxp=application/vnd.adobe.fxp
fxpl=application/vnd.adobe.fxp
fzs=application/vnd.fuzzysheet
g2w=application/vnd.geoplan
g3=image/g3fax
g3w=application/vnd.geospace
gac=application/vnd.groove-account
gam=application/x-tads
gbr=application/rpki-ghostbusters
gca=application/x-gca-compressed
gdl=model/vnd.gdl
geo=application/vnd.dynageo
gex=application/vnd.geometry-explorer
ggb=application/vnd.geogebra.file
ggt=application/vnd.geogebra.tool
ghf=application/vnd.groove-help
gif=image/gif
gim=application/vnd.groove-identity-message
gml=application/gml+xml
gmx=application/vnd.gmx
gnumeric=application/x-gnumeric
gph=application/vnd.flographit
gpx=application/gpx+xml
gqf=application/vnd.grafeq
gqs=application/vnd.grafeq
gram=application/srgs
gramps=application/x-gramps-xml
gre=application/vnd.geometry-explorer
grv=application/vnd.groove-injector
grxml=application/srgs+xml
gsf=application/x-font-ghostscript
gtar=application/x-gtar
gtm=application/vnd.groove-tool-message
gtw=model/vnd.gtw
gv=text/vnd.graphviz
gxf=application/gxf
gxt=application/vnd.geonext
gz=application/x-gzip
h=text/x-c
h261=video/h261
h263=video/h263
h264=video/h264
hal=application/vnd.hal+xml
hbci=application/vnd.hbci
hdf=application/x-hdf
hh=text/x-c
hlp=application/winhlp
hpgl=application/vnd.hp-hpgl
hpid=application/vnd.hp-hpid
hps=application/vnd.hp-hps
hqx=application/mac-binhex40
htc=text/x-component
htke=application/vnd.kenameaapp
htm=text/html
html=text/html
hvd=application/vnd.yamaha.hv-dic
hvp=application/vnd.yamaha.hv-voice
hvs=application/vnd.yamaha.hv-script
i2g=application/vnd.intergeo
icc=application/vnd.iccprofile
ice=x-conference/x-cooltalk
icm=application/vnd.iccprofile
ico=image/x-icon
ics=text/calendar
ief=image/ief
ifb=text/calendar
ifm=application/vnd.shana.informed.formdata
iges=model/iges
igl=application/vnd.igloader
igm=application/vnd.insors.igm
igs=model/iges
igx=application/vnd.micrografx.igx
iif=application/vnd.shana.informed.interchange
imp=application/vnd.accpac.simply.imp
ims=application/vnd.ms-ims
in=text/plain
ink=application/inkml+xml
inkml=application/inkml+xml
install=application/x-install-instructions
iota=application/vnd.astraea-software.iota
ipfix=application/ipfix
ipk=application/vnd.shana.informed.package
irm=application/vnd.ibm.rights-management
irp=application/vnd.irepository.package+xml
iso=application/x-iso9660-image
itp=application/vnd.shana.informed.formtemplate
ivp=application/vnd.immervision-ivp
ivu=application/vnd.immervision-ivu
jad=text/vnd.sun.j2me.app-descriptor
jam=application/vnd.jam
jar=application/java-archive
java=text/x-java-source
jisp=application/vnd.jisp
jlt=application/vnd.hp-jlyt
jnlp=application/x-java-jnlp-file
joda=application/vnd.joost.joda-archive
jpe=image/jpeg
jpeg=image/jpeg
jpg=image/jpeg
jpgm=video/jpm
jpgv=video/jpeg
jpm=video/jpm
js=application/javascript
jsf=text/plain
json=application/json
jsonml=application/jsonml+json
jspf=text/plain
kar=audio/midi
karbon=application/vnd.kde.karbon
kfo=application/vnd.kde.kformula
kia=application/vnd.kidspiration
kml=application/vnd.google-earth.kml+xml
kmz=application/vnd.google-earth.kmz
kne=application/vnd.kinar
knp=application/vnd.kinar
kon=application/vnd.kde.kontour
kpr=application/vnd.kde.kpresenter
kpt=application/vnd.kde.kpresenter
kpxx=application/vnd.ds-keypoint
ksp=application/vnd.kde.kspread
ktr=application/vnd.kahootz
ktx=image/ktx
ktz=application/vnd.kahootz
kwd=application/vnd.kde.kword
kwt=application/vnd.kde.kword
lasxml=application/vnd.las.las+xml
latex=application/x-latex
lbd=application/vnd.llamagraphics.life-balance.desktop
lbe=application/vnd.llamagraphics.life-balance.exchange+xml
les=application/vnd.hhe.lesson-player
lha=application/x-lzh-compressed
link66=application/vnd.route66.link66+xml
list=text/plain
list3820=application/vnd.ibm.modcap
listafp=application/vnd.ibm.modcap
lnk=application/x-ms-shortcut
log=text/plain
lostxml=application/lost+xml
lrf=application/octet-stream
lrm=application/vnd.ms-lrm
ltf=application/vnd.frogans.ltf
lvp=audio/vnd.lucent.voice
lwp=application/vnd.lotus-wordpro
lzh=application/x-lzh-compressed
m13=application/x-msmediaview
m14=application/x-msmediaview
m1v=video/mpeg
m21=application/mp21
m2a=audio/mpeg
m2v=video/mpeg
m3a=audio/mpeg
m3u=audio/x-mpegurl
m3u8=application/vnd.apple.mpegurl
m4a=audio/mp4
m4b=audio/mp4
m4r=audio/mp4
m4u=video/vnd.mpegurl
m4v=video/mp4
ma=application/mathematica
mac=image/x-macpaint
mads=application/mads+xml
mag=application/vnd.ecowin.chart
maker=application/vnd.framemaker
man=text/troff
mar=application/octet-stream
mathml=application/mathml+xml
mb=application/mathematica
mbk=application/vnd.mobius.mbk
mbox=application/mbox
mc1=application/vnd.medcalcdata
mcd=application/vnd.mcd
mcurl=text/vnd.curl.mcurl
mdb=application/x-msaccess
mdi=image/vnd.ms-modi
me=text/troff
mesh=model/mesh
meta4=application/metalink4+xml
metalink=application/metalink+xml
mets=application/mets+xml
mfm=application/vnd.mfmp
mft=application/rpki-manifest
mgp=application/vnd.osgeo.mapguide.package
mgz=application/vnd.proteus.magazine
mid=audio/midi
midi=audio/midi
mie=application/x-mie
mif=application/x-mif
mime=message/rfc822
mj2=video/mj2
mjp2=video/mj2
mk3d=video/x-matroska
mka=audio/x-matroska
mks=video/x-matroska
mkv=video/x-matroska
mlp=application/vnd.dolby.mlp
mmd=application/vnd.chipnuts.karaoke-mmd
mmf=application/vnd.smaf
mmr=image/vnd.fujixerox.edmics-mmr
mng=video/x-mng
mny=application/x-msmoney
mobi=application/x-mobipocket-ebook
mods=application/mods+xml
mov=video/quicktime
movie=video/x-sgi-movie
mp1=audio/mpeg
mp2=audio/mpeg
mp21=application/mp21
mp2a=audio/mpeg
mp3=audio/mpeg
mp4=video/mp4
mp4a=audio/mp4
mp4s=application/mp4
mp4v=video/mp4
mpa=audio/mpeg
mpc=application/vnd.mophun.certificate
mpe=video/mpeg
mpeg=video/mpeg
mpega=audio/x-mpeg
mpg=video/mpeg
mpg4=video/mp4
mpga=audio/mpeg
mpkg=application/vnd.apple.installer+xml
mpm=application/vnd.blueice.multipass
mpn=application/vnd.mophun.application
mpp=application/vnd.ms-project
mpt=application/vnd.ms-project
mpv2=video/mpeg2
mpy=application/vnd.ibm.minipay
mqy=application/vnd.mobius.mqy
mrc=application/marc
mrcx=application/marcxml+xml
ms=text/troff
mscml=application/mediaservercontrol+xml
mseed=application/vnd.fdsn.mseed
mseq=application/vnd.mseq
msf=application/vnd.epson.msf
msh=model/mesh
msi=application/x-msdownload
msl=application/vnd.mobius.msl
msty=application/vnd.muvee.style
mts=model/vnd.mts
mus=application/vnd.musician
musicxml=application/vnd.recordare.musicxml+xml
mvb=application/x-msmediaview
mwf=application/vnd.mfer
mxf=application/mxf
mxl=application/vnd.recordare.musicxml
mxml=application/xv+xml
mxs=application/vnd.triscape.mxs
mxu=video/vnd.mpegurl
n-gage=application/vnd.nokia.n-gage.symbian.install
n3=text/n3
nb=application/mathematica
nbp=application/vnd.wolfram.player
nc=application/x-netcdf
ncx=application/x-dtbncx+xml
nfo=text/x-nfo
ngdat=application/vnd.nokia.n-gage.data
nitf=application/vnd.nitf
nlu=application/vnd.neurolanguage.nlu
nml=application/vnd.enliven
nnd=application/vnd.noblenet-directory
nns=application/vnd.noblenet-sealer
nnw=application/vnd.noblenet-web
npx=image/vnd.net-fpx
nsc=application/x-conference
nsf=application/vnd.lotus-notes
ntf=application/vnd.nitf
nzb=application/x-nzb
oa2=application/vnd.fujitsu.oasys2
oa3=application/vnd.fujitsu.oasys3
oas=application/vnd.fujitsu.oasys
obd=application/x-msbinder
obj=application/x-tgif
oda=application/oda
odb=application/vnd.oasis.opendocument.database
odc=application/vnd.oasis.opendocument.chart
odf=application/vnd.oasis.opendocument.formula
odft=application/vnd.oasis.opendocument.formula-template
odg=application/vnd.oasis.opendocument.graphics
odi=application/vnd.oasis.opendocument.image
odm=application/vnd.oasis.opendocument.text-master
odp=application/vnd.oasis.opendocument.presentation
ods=application/vnd.oasis.opendocument.spreadsheet
odt=application/vnd.oasis.opendocument.text
oga=audio/ogg
ogg=audio/ogg
ogv=video/ogg
ogx=application/ogg
omdoc=application/omdoc+xml
onepkg=application/onenote
onetmp=application/onenote
onetoc=application/onenote
onetoc2=application/onenote
opf=application/oebps-package+xml
opml=text/x-opml
oprc=application/vnd.palm
org=application/vnd.lotus-organizer
osf=application/vnd.yamaha.openscoreformat
osfpvg=application/vnd.yamaha.openscoreformat.osfpvg+xml
otc=application/vnd.oasis.opendocument.chart-template
otf=font/otf
otg=application/vnd.oasis.opendocument.graphics-template
oth=application/vnd.oasis.opendocument.text-web
oti=application/vnd.oasis.opendocument.image-template
otp=application/vnd.oasis.opendocument.presentation-template
ots=application/vnd.oasis.opendocument.spreadsheet-template
ott=application/vnd.oasis.opendocument.text-template
oxps=application/oxps
oxt=application/vnd.openofficeorg.extension
p=text/x-pascal
p10=application/pkcs10
p12=application/x-pkcs12
p7b=application/x-pkcs7-certificates
p7c=application/pkcs7-mime
p7m=application/pkcs7-mime
p7r=application/x-pkcs7-certreqresp
p7s=application/pkcs7-signature
p8=application/pkcs8
pas=text/x-pascal
paw=application/vnd.pawaafile
pbd=application/vnd.powerbuilder6
pbm=image/x-portable-bitmap
pcap=application/vnd.tcpdump.pcap
pcf=application/x-font-pcf
pcl=application/vnd.hp-pcl
pclxl=application/vnd.hp-pclxl
pct=image/pict
pcurl=application/vnd.curl.pcurl
pcx=image/x-pcx
pdb=application/vnd.palm
pdf=application/pdf
pfa=application/x-font-type1
pfb=application/x-font-type1
pfm=application/x-font-type1
pfr=application/font-tdpfr
pfx=application/x-pkcs12
pgm=image/x-portable-graymap
pgn=application/x-chess-pgn
pgp=application/pgp-encrypted
pic=image/pict
pict=image/pict
pkg=application/octet-stream
pki=application/pkixcmp
pkipath=application/pkix-pkipath
plb=application/vnd.3gpp.pic-bw-large
plc=application/vnd.mobius.plc
plf=application/vnd.pocketlearn
pls=audio/x-scpls
pml=application/vnd.ctc-posml
png=image/png
pnm=image/x-portable-anymap
pnt=image/x-macpaint
portpkg=application/vnd.macports.portpkg
pot=application/vnd.ms-powerpoint
potm=application/vnd.ms-powerpoint.template.macroenabled.12
potx=application/vnd.openxmlformats-officedocument.presentationml.template
ppam=application/vnd.ms-powerpoint.addin.macroenabled.12
ppd=application/vnd.cups-ppd
ppm=image/x-portable-pixmap
pps=application/vnd.ms-powerpoint
ppsm=application/vnd.ms-powerpoint.slideshow.macroenabled.12
ppsx=application/vnd.openxmlformats-officedocument.presentationml.slideshow
ppt=application/vnd.ms-powerpoint
pptm=application/vnd.ms-powerpoint.presentation.macroenabled.12
pptx=application/vnd.openxmlformats-officedocument.presentationml.presentation
pqa=application/vnd.palm
prc=application/x-mobipocket-ebook
pre=application/vnd.lotus-freelance
prf=application/pics-rules
ps=application/postscript
psb=application/vnd.3gpp.pic-bw-small
psd=image/vnd.adobe.photoshop
psf=application/x-font-linux-psf
pskcxml=application/pskc+xml
ptid=application/vnd.pvi.ptid1
pub=application/x-mspublisher
pvb=application/vnd.3gpp.pic-bw-var
pwn=application/vnd.3m.post-it-notes
pya=audio/vnd.ms-playready.media.pya
pyv=video/vnd.ms-playready.media.pyv
qam=application/vnd.epson.quickanime
qbo=application/vnd.intu.qbo
qfx=application/vnd.intu.qfx
qps=application/vnd.publishare-delta-tree
qt=video/quicktime
qti=image/x-quicktime
qtif=image/x-quicktime
qwd=application/vnd.quark.quarkxpress
qwt=application/vnd.quark.quarkxpress
qxb=application/vnd.quark.quarkxpress
qxd=application/vnd.quark.quarkxpress
qxl=application/vnd.quark.quarkxpress
qxt=application/vnd.quark.quarkxpress
ra=audio/x-pn-realaudio
ram=audio/x-pn-realaudio
rar=application/x-rar-compressed
ras=image/x-cmu-raster
rcprofile=application/vnd.ipunplugged.rcprofile
rdf=application/rdf+xml
rdz=application/vnd.data-vision.rdz
rep=application/vnd.businessobjects
res=application/x-dtbresource+xml
rgb=image/x-rgb
rif=application/reginfo+xml
rip=audio/vnd.rip
ris=application/x-research-info-systems
rl=application/resource-lists+xml
rlc=image/vnd.fujixerox.edmics-rlc
rld=application/resource-lists-diff+xml
rm=application/vnd.rn-realmedia
rmi=audio/midi
rmp=audio/x-pn-realaudio-plugin
rms=application/vnd.jcp.javame.midlet-rms
rmvb=application/vnd.rn-realmedia-vbr
rnc=application/relax-ng-compact-syntax
roa=application/rpki-roa
roff=text/troff
rp9=application/vnd.cloanto.rp9
rpss=application/vnd.nokia.radio-presets
rpst=application/vnd.nokia.radio-preset
rq=application/sparql-query
rs=application/rls-services+xml
rsd=application/rsd+xml
rss=application/rss+xml
rtf=application/rtf
rtx=text/richtext
s=text/x-asm
s3m=audio/s3m
saf=application/vnd.yamaha.smaf-audio
sbml=application/sbml+xml
sc=application/vnd.ibm.secure-container
scd=application/x-msschedule
scm=application/vnd.lotus-screencam
scq=application/scvp-cv-request
scs=application/scvp-cv-response
scurl=text/vnd.curl.scurl
sda=application/vnd.stardivision.draw
sdc=application/vnd.stardivision.calc
sdd=application/vnd.stardivision.impress
sdkd=application/vnd.solent.sdkm+xml
sdkm=application/vnd.solent.sdkm+xml
sdp=application/sdp
sdw=application/vnd.stardivision.writer
see=application/vnd.seemail
seed=application/vnd.fdsn.seed
sema=application/vnd.sema
semd=application/vnd.semd
semf=application/vnd.semf
ser=application/java-serialized-object
setpay=application/set-payment-initiation
setreg=application/set-registration-initiation
sfd-hdstx=application/vnd.hydrostatix.sof-data
sfs=application/vnd.spotfire.sfs
sfv=text/x-sfv
sgi=image/sgi
sgl=application/vnd.stardivision.writer-global
sgm=text/sgml
sgml=text/sgml
sh=application/x-sh
shar=application/x-shar
shf=application/shf+xml
sid=image/x-mrsid-image
sig=application/pgp-signature
sil=audio/silk
silo=model/mesh
sis=application/vnd.symbian.install
sisx=application/vnd.symbian.install
sit=application/x-stuffit
sitx=application/x-stuffitx
skd=application/vnd.koan
skm=application/vnd.koan
skp=application/vnd.koan
skt=application/vnd.koan
sldm=application/vnd.ms-powerpoint.slide.macroenabled.12
sldx=application/vnd.openxmlformats-officedocument.presentationml.slide
slt=application/vnd.epson.salt
sm=application/vnd.stepmania.stepchart
smf=application/vnd.stardivision.math
smi=application/smil+xml
smil=application/smil+xml
smv=video/x-smv
smzip=application/vnd.stepmania.package
snd=audio/basic
snf=application/x-font-snf
so=application/octet-stream
spc=application/x-pkcs7-certificates
spf=application/vnd.yamaha.smaf-phrase
spl=application/x-futuresplash
spot=text/vnd.in3d.spot
spp=application/scvp-vp-response
spq=application/scvp-vp-request
spx=audio/ogg
sql=application/x-sql
src=application/x-wais-source
srt=application/x-subrip
sru=application/sru+xml
srx=application/sparql-results+xml
ssdl=application/ssdl+xml
sse=application/vnd.kodak-descriptor
ssf=application/vnd.epson.ssf
ssml=application/ssml+xml
st=application/vnd.sailingtracker.track
stc=application/vnd.sun.xml.calc.template
std=application/vnd.sun.xml.draw.template
stf=application/vnd.wt.stf
sti=application/vnd.sun.xml.impress.template
stk=application/hyperstudio
stl=application/vnd.ms-pki.stl
str=application/vnd.pg.format
stw=application/vnd.sun.xml.writer.template
sub=text/vnd.dvb.subtitle
sus=application/vnd.sus-calendar
susp=application/vnd.sus-calendar
sv4cpio=application/x-sv4cpio
sv4crc=application/x-sv4crc
svc=application/vnd.dvb.service
svd=application/vnd.svd
svg=image/svg+xml
svgz=image/svg+xml
swa=application/x-director
swf=application/x-shockwave-flash
swi=application/vnd.aristanetworks.swi
sxc=application/vnd.sun.xml.calc
sxd=application/vnd.sun.xml.draw
sxg=application/vnd.sun.xml.writer.global
sxi=application/vnd.sun.xml.impress
sxm=application/vnd.sun.xml.math
sxw=application/vnd.sun.xml.writer
t=text/troff
t3=application/x-t3vm-image
taglet=application/vnd.mynfc
tao=application/vnd.tao.intent-module-archive
tar=application/x-tar
tcap=application/vnd.3gpp2.tcap
tcl=application/x-tcl
teacher=application/vnd.smart.teacher
tei=application/tei+xml
teicorpus=application/tei+xml
tex=application/x-tex
texi=application/x-texinfo
texinfo=application/x-texinfo
text=text/plain
tfi=application/thraud+xml
tfm=application/x-tex-tfm
tga=image/x-tga
thmx=application/vnd.ms-officetheme
tif=image/tiff
tiff=image/tiff
tmo=application/vnd.tmobile-livetv
torrent=application/x-bittorrent
tpl=application/vnd.groove-tool-template
tpt=application/vnd.trid.tpt
tr=text/troff
tra=application/vnd.trueapp
trm=application/x-msterminal
tsd=application/timestamped-data
tsv=text/tab-separated-values
ttc=font/collection
ttf=font/ttf
ttl=text/turtle
twd=application/vnd.simtech-mindmapper
twds=application/vnd.simtech-mindmapper
txd=application/vnd.genomatix.tuxedo
txf=application/vnd.mobius.txf
txt=text/plain
u32=application/x-authorware-bin
udeb=application/x-debian-package
ufd=application/vnd.ufdl
ufdl=application/vnd.ufdl
ulw=audio/basic
ulx=application/x-glulx
umj=application/vnd.umajin
unityweb=application/vnd.unity
uoml=application/vnd.uoml+xml
uri=text/uri-list
uris=text/uri-list
urls=text/uri-list
ustar=application/x-ustar
utz=application/vnd.uiq.theme
uu=text/x-uuencode
uva=audio/vnd.dece.audio
uvd=application/vnd.dece.data
uvf=application/vnd.dece.data
uvg=image/vnd.dece.graphic
uvh=video/vnd.dece.hd
uvi=image/vnd.dece.graphic
uvm=video/vnd.dece.mobile
uvp=video/vnd.dece.pd
uvs=video/vnd.dece.sd
uvt=application/vnd.dece.ttml+xml
uvu=video/vnd.uvvu.mp4
uvv=video/vnd.dece.video
uvva=audio/vnd.dece.audio
uvvd=application/vnd.dece.data
uvvf=application/vnd.dece.data
uvvg=image/vnd.dece.graphic
uvvh=video/vnd.dece.hd
uvvi=image/vnd.dece.graphic
uvvm=video/vnd.dece.mobile
uvvp=video/vnd.dece.pd
uvvs=video/vnd.dece.sd
uvvt=application/vnd.dece.ttml+xml
uvvu=video/vnd.uvvu.mp4
uvvv=video/vnd.dece.video
uvvx=application/vnd.dece.unspecified
uvvz=application/vnd.dece.zip
uvx=application/vnd.dece.unspecified
uvz=application/vnd.dece.zip
vcard=text/vcard
vcd=application/x-cdlink
vcf=text/x-vcard
vcg=application/vnd.groove-vcard
vcs=text/x-vcalendar
vcx=application/vnd.vcx
vis=application/vnd.visionary
viv=video/vnd.vivo
vob=video/x-ms-vob
vor=application/vnd.stardivision.writer
vox=application/x-authorware-bin
vrml=model/vrml
vsd=application/vnd.visio
vsf=application/vnd.vsf
vss=application/vnd.visio
vst=application/vnd.visio
vsw=application/vnd.visio
vtu=model/vnd.vtu
vxml=application/voicexml+xml
w3d=application/x-director
wad=application/x-doom
wasm=application/wasm
wav=audio/x-wav
wax=audio/x-ms-wax
wbmp=image/vnd.wap.wbmp
wbs=application/vnd.criticaltools.wbs+xml
wbxml=application/vnd.wap.wbxml
wcm=application/vnd.ms-works
wdb=application/vnd.ms-works
wdp=image/vnd.ms-photo
weba=audio/webm
webm=video/webm
webp=image/webp
wg=application/vnd.pmi.widget
wgt=application/widget
wks=application/vnd.ms-works
wm=video/x-ms-wm
wma=audio/x-ms-wma
wmd=application/x-ms-wmd
wmf=application/x-msmetafile
wml=text/vnd.wap.wml
wmlc=application/vnd.wap.wmlc
wmls=text/vnd.wap.wmlscript
wmlsc=application/vnd.wap.wmlscriptc
wmv=video/x-ms-wmv
wmx=video/x-ms-wmx
wmz=application/x-msmetafile
woff=font/woff
woff2=font/woff2
wpd=application/vnd.wordperfect
wpl=application/vnd.ms-wpl
wps=application/vnd.ms-works
wqd=application/vnd.wqd
wri=application/x-mswrite
wrl=model/vrml
wsdl=application/wsdl+xml
wspolicy=application/wspolicy+xml
wtb=application/vnd.webturbo
wvx=video/x-ms-wvx
x32=application/x-authorware-bin
x3d=model/x3d+xml
x3db=model/x3d+binary
x3dbz=model/x3d+binary
x3dv=model/x3d+vrml
x3dvz=model/x3d+vrml
x3dz=model/x3d+xml
xaml=application/xaml+xml
xap=application/x-silverlight-app
xar=application/vnd.xara
xbap=application/x-ms-xbap
xbd=application/vnd.fujixerox.docuworks.binder
xbm=image/x-xbitmap
xdf=application/xcap-diff+xml
xdm=application/vnd.syncml.dm+xml
xdp=application/vnd.adobe.xdp+xml
xdssc=application/dssc+xml
xdw=application/vnd.fujixerox.docuworks
xenc=application/xenc+xml
xer=application/patch-ops-error+xml
xfdf=application/vnd.adobe.xfdf
xfdl=application/vnd.xfdl
xht=application/xhtml+xml
xhtml=application/xhtml+xml
xhvml=application/xv+xml
xif=image/vnd.xiff
xla=application/vnd.ms-excel
xlam=application/vnd.ms-excel.addin.macroenabled.12
xlc=application/vnd.ms-excel
xlf=application/x-xliff+xml
xlm=application/vnd.ms-excel
xls=application/vnd.ms-excel
xlsb=application/vnd.ms-excel.sheet.binary.macroenabled.12
xlsm=application/vnd.ms-excel.sheet.macroenabled.12
xlsx=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
xlt=application/vnd.ms-excel
xltm=application/vnd.ms-excel.template.macroenabled.12
xltx=application/vnd.openxmlformats-officedocument.spreadsheetml.template
xlw=application/vnd.ms-excel
xm=audio/xm
xml=application/xml
xo=application/vnd.olpc-sugar
xop=application/xop+xml
xpi=application/x-xpinstall
xpl=application/xproc+xml
xpm=image/x-xpixmap
xpr=application/vnd.is-xpr
xps=application/vnd.ms-xpsdocument
xpw=application/vnd.intercon.formnet
xpx=application/vnd.intercon.formnet
xsl=application/xml
xslt=application/xslt+xml
xsm=application/vnd.syncml+xml
xspf=application/xspf+xml
xul=application/vnd.mozilla.xul+xml
xvm=application/xv+xml
xvml=application/xv+xml
xwd=image/x-xwindowdump
xyz=chemical/x-xyz
xz=application/x-xz
yang=application/yang
yin=application/yin+xml
z=application/x-compress
z1=application/x-zmachine
z2=application/x-zmachine
z3=application/x-zmachine
z4=application/x-zmachine
z5=application/x-zmachine
z6=application/x-zmachine
z7=application/x-zmachine
z8=application/x-zmachine
zaz=application/vnd.zzazz.deck+xml
zip=application/zip
zir=application/vnd.zul
zirz=application/vnd.zul
zmm=application/vnd.handheld-entertainment+xml

View File

@ -24,6 +24,13 @@ import java.util.regex.Pattern;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.boot.web.server.MimeMappings.DefaultMimeMappings;
import org.springframework.boot.web.server.MimeMappings.Mapping;
import org.springframework.boot.web.server.MimeMappings.MimeMappingsRuntimeHints;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -31,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Tests for {@link MimeMappings}.
*
* @author Phillip Webb
* @author Guirong Hu
*/
class MimeMappingsTests {
@ -143,4 +151,69 @@ class MimeMappingsTests {
assertThat(MimeMappings.DEFAULT).allSatisfy((mapping) -> assertThat(mapping.getMimeType()).matches(pattern));
}
@Test
void getCommonTypeOnDefaultMimeMappingsDoesNotLoadMappings() {
DefaultMimeMappings mappings = new DefaultMimeMappings();
assertThat(mappings.get("json")).isEqualTo("application/json");
assertThat((Object) mappings).extracting("loaded").isNull();
}
@Test
void getExoticTypeOnDefaultMimeMappingsLoadsMappings() {
DefaultMimeMappings mappings = new DefaultMimeMappings();
assertThat(mappings.get("123")).isEqualTo("application/vnd.lotus-1-2-3");
assertThat((Object) mappings).extracting("loaded").isNotNull();
}
@Test
void iterateOnDefaultMimeMappingsLoadsMappings() {
DefaultMimeMappings mappings = new DefaultMimeMappings();
assertThat(mappings).isNotEmpty();
assertThat((Object) mappings).extracting("loaded").isNotNull();
}
@Test
void commonMappingsAreSubsetOfAllMappings() {
MimeMappings commonMappings = (MimeMappings) ReflectionTestUtils.getField(DefaultMimeMappings.class, "COMMON");
for (Mapping commonMapping : commonMappings) {
assertThat(MimeMappings.DEFAULT.get(commonMapping.getExtension())).isEqualTo(commonMapping.getMimeType());
}
}
@Test
void lazyCopyWhenNotMutatedDelegates() {
DefaultMimeMappings mappings = new DefaultMimeMappings();
MimeMappings lazyCopy = MimeMappings.lazyCopy(mappings);
assertThat(lazyCopy.get("json")).isEqualTo("application/json");
assertThat((Object) mappings).extracting("loaded").isNull();
}
@Test
void lazyCopyWhenMutatedCreatesCopy() {
DefaultMimeMappings mappings = new DefaultMimeMappings();
MimeMappings lazyCopy = MimeMappings.lazyCopy(mappings);
lazyCopy.add("json", "other/json");
assertThat(lazyCopy.get("json")).isEqualTo("other/json");
assertThat((Object) mappings).extracting("loaded").isNotNull();
}
@Test
void lazyCopyWhenMutatedCreatesCopyOnlyOnce() {
MimeMappings mappings = new MimeMappings();
mappings.add("json", "one/json");
MimeMappings lazyCopy = MimeMappings.lazyCopy(mappings);
assertThat(lazyCopy.get("json")).isEqualTo("one/json");
mappings.add("json", "two/json");
lazyCopy.add("json", "other/json");
assertThat(lazyCopy.get("json")).isEqualTo("other/json");
}
@Test
void shouldRegisterHints() {
RuntimeHints runtimeHints = new RuntimeHints();
new MimeMappingsRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.resource()
.forResource("org/springframework/boot/web/server/mime-mappings.properties")).accepts(runtimeHints);
}
}

View File

@ -45,6 +45,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
@ -77,6 +78,7 @@ import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
import org.apache.http.HttpResponse;
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.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpRequest;
@ -958,6 +961,20 @@ public abstract class AbstractServletWebServerFactoryTests {
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
void rootServletContextResource() {
AbstractServletWebServerFactory factory = getFactory();