Skip to content

Commit da4c2db

Browse files
committed
Ensure default mime mappings are applied
Fixes gh-40860
1 parent baf34c4 commit da4c2db

File tree

7 files changed

+55
-9
lines changed

7 files changed

+55
-9
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public class ServerProperties {
120120
/**
121121
* Custom MIME mappings in addition to the default MIME mappings.
122122
*/
123-
private final MimeMappings mimeMappings = MimeMappings.lazyCopy(MimeMappings.DEFAULT);
123+
private final MimeMappings mimeMappings = new MimeMappings();
124124

125125
@NestedConfigurationProperty
126126
private final Http2 http2 = new Http2();

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryCustomizer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public void customize(ConfigurableServletWebServerFactory factory) {
9595
map.from(() -> this.cookieSameSiteSuppliers)
9696
.whenNot(CollectionUtils::isEmpty)
9797
.to(factory::setCookieSameSiteSuppliers);
98-
map.from(this.serverProperties::getMimeMappings).to(factory::setMimeMappings);
98+
map.from(this.serverProperties::getMimeMappings).to(factory::addMimeMappings);
9999
this.webListenerRegistrars.forEach((registrar) -> registrar.register(factory));
100100
}
101101

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,12 @@ void testContextPathWithLeadingAndTrailingWhitespaceAndContextWithSpace() {
187187

188188
@Test
189189
void testDefaultMimeMapping() {
190-
assertThat(this.properties.getMimeMappings())
191-
.containsExactly(MimeMappings.DEFAULT.getAll().toArray(new Mapping[0]));
190+
assertThat(this.properties.getMimeMappings()).isEmpty();
192191
}
193192

194193
@Test
195194
void testCustomizedMimeMapping() {
196-
MimeMappings expectedMappings = MimeMappings.lazyCopy(MimeMappings.DEFAULT);
195+
MimeMappings expectedMappings = new MimeMappings();
197196
expectedMappings.add("mjs", "text/javascript");
198197
bind("server.mime-mappings.mjs", "text/javascript");
199198
assertThat(this.properties.getMimeMappings())

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryCustomizerTests.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222

2323
import org.junit.jupiter.api.BeforeEach;
2424
import org.junit.jupiter.api.Test;
25+
import org.mockito.ArgumentCaptor;
2526

2627
import org.springframework.boot.autoconfigure.web.ServerProperties;
2728
import org.springframework.boot.context.properties.bind.Bindable;
2829
import org.springframework.boot.context.properties.bind.Binder;
2930
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
3031
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
3132
import org.springframework.boot.web.server.Cookie;
33+
import org.springframework.boot.web.server.MimeMappings;
3234
import org.springframework.boot.web.server.Shutdown;
3335
import org.springframework.boot.web.server.Ssl;
3436
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
@@ -74,10 +76,25 @@ void testCustomizeDisplayName() {
7476
}
7577

7678
@Test
77-
void testCustomMimeMappings() {
79+
void withNoCustomMimeMappingsThenEmptyMimeMappingsIsAdded() {
7880
ConfigurableServletWebServerFactory factory = mock(ConfigurableServletWebServerFactory.class);
7981
this.customizer.customize(factory);
80-
then(factory).should().setMimeMappings(this.properties.getMimeMappings());
82+
ArgumentCaptor<MimeMappings> mimeMappingsCaptor = ArgumentCaptor.forClass(MimeMappings.class);
83+
then(factory).should().addMimeMappings(mimeMappingsCaptor.capture());
84+
MimeMappings mimeMappings = mimeMappingsCaptor.getValue();
85+
assertThat(mimeMappings.getAll()).isEmpty();
86+
}
87+
88+
@Test
89+
void withCustomMimeMappingsThenPopulatedMimeMappingsIsAdded() {
90+
this.properties.getMimeMappings().add("a", "alpha");
91+
this.properties.getMimeMappings().add("b", "bravo");
92+
ConfigurableServletWebServerFactory factory = mock(ConfigurableServletWebServerFactory.class);
93+
this.customizer.customize(factory);
94+
ArgumentCaptor<MimeMappings> mimeMappingsCaptor = ArgumentCaptor.forClass(MimeMappings.class);
95+
then(factory).should().addMimeMappings(mimeMappingsCaptor.capture());
96+
MimeMappings mimeMappings = mimeMappingsCaptor.getValue();
97+
assertThat(mimeMappings.getAll()).hasSize(2);
8198
}
8299

83100
@Test

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactory.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -178,6 +178,11 @@ public void setMimeMappings(MimeMappings mimeMappings) {
178178
this.mimeMappings = new MimeMappings(mimeMappings);
179179
}
180180

181+
@Override
182+
public void addMimeMappings(MimeMappings mimeMappings) {
183+
mimeMappings.forEach((mapping) -> this.mimeMappings.add(mapping.getExtension(), mapping.getMimeType()));
184+
}
185+
181186
/**
182187
* Returns the document root which will be used by the web context to serve static
183188
* files.

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ConfigurableServletWebServerFactory.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -82,6 +82,13 @@ public interface ConfigurableServletWebServerFactory
8282
*/
8383
void setMimeMappings(MimeMappings mimeMappings);
8484

85+
/**
86+
* Adds mime-type mappings.
87+
* @param mimeMappings the mime type mappings to add
88+
* @since 3.3.0
89+
*/
90+
void addMimeMappings(MimeMappings mimeMappings);
91+
8592
/**
8693
* Sets the document root directory which will be used by the web context to serve
8794
* static files.

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java

+18
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.security.cert.CertificateException;
3535
import java.security.cert.X509Certificate;
3636
import java.time.Duration;
37+
import java.util.ArrayList;
3738
import java.util.Arrays;
3839
import java.util.Collection;
3940
import java.util.Date;
@@ -1010,6 +1011,23 @@ void mimeMappingsAreCorrectlyConfigured() {
10101011
assertThat(configuredMimeMappings).containsExactlyInAnyOrderElementsOf(expectedMimeMappings);
10111012
}
10121013

1014+
@Test
1015+
void additionalMimeMappingsCanBeConfigured() {
1016+
AbstractServletWebServerFactory factory = getFactory();
1017+
MimeMappings additionalMimeMappings = new MimeMappings();
1018+
additionalMimeMappings.add("a", "alpha");
1019+
additionalMimeMappings.add("b", "bravo");
1020+
factory.addMimeMappings(additionalMimeMappings);
1021+
this.webServer = factory.getWebServer();
1022+
Collection<MimeMappings.Mapping> configuredMimeMappings = getActualMimeMappings().entrySet()
1023+
.stream()
1024+
.map((entry) -> new MimeMappings.Mapping(entry.getKey(), entry.getValue()))
1025+
.toList();
1026+
List<MimeMappings.Mapping> expectedMimeMappings = new ArrayList<>(MimeMappings.DEFAULT.getAll());
1027+
expectedMimeMappings.addAll(additionalMimeMappings.getAll());
1028+
assertThat(configuredMimeMappings).containsExactlyInAnyOrderElementsOf(expectedMimeMappings);
1029+
}
1030+
10131031
@Test
10141032
void rootServletContextResource() {
10151033
AbstractServletWebServerFactory factory = getFactory();

0 commit comments

Comments
 (0)