diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index 1ec029bcd6..b943184bda 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -660,11 +660,24 @@ public class ServerProperties { */ public static class Resource { + /** + * Whether static resource caching is permitted for this web application. + */ + private boolean allowCaching = true; + /** * Time-to-live of the static resource cache. */ private Duration cacheTtl; + public boolean isAllowCaching() { + return this.allowCaching; + } + + public void setAllowCaching(boolean allowCaching) { + this.allowCaching = allowCaching; + } + public Duration getCacheTtl() { return this.cacheTtl; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java index b1e2c0272b..8df3d8db5c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java @@ -241,14 +241,14 @@ public class TomcatWebServerFactoryCustomizer implements private void customizeStaticResources(ConfigurableTomcatWebServerFactory factory) { ServerProperties.Tomcat.Resource resource = this.serverProperties.getTomcat() .getResource(); - if (resource.getCacheTtl() == null) { - return; - } factory.addContextCustomizers((context) -> { context.addLifecycleListener((event) -> { if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) { - long ttl = resource.getCacheTtl().toMillis(); - context.getResources().setCacheTtl(ttl); + context.getResources().setCachingAllowed(resource.isAllowCaching()); + if (resource.getCacheTtl() != null) { + long ttl = resource.getCacheTtl().toMillis(); + context.getResources().setCacheTtl(ttl); + } } }); }); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java index 3cf616e88a..ce43fac13d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java @@ -16,14 +16,17 @@ package org.springframework.boot.autoconfigure.web.embedded; +import java.util.Map; import java.util.function.Consumer; import org.apache.catalina.Context; import org.apache.catalina.Valve; +import org.apache.catalina.mapper.Mapper; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.valves.ErrorReportValve; import org.apache.catalina.valves.RemoteIpValve; +import org.apache.catalina.webresources.StandardRoot; import org.apache.coyote.AbstractProtocol; import org.junit.Before; import org.junit.Test; @@ -36,6 +39,7 @@ import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactor import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; import org.springframework.mock.env.MockEnvironment; import org.springframework.test.context.support.TestPropertySourceUtils; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -44,6 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Brian Clozel * @author Phillip Webb + * @author Rob Tompkins */ public class TomcatWebServerFactoryCustomizerTests { @@ -121,6 +126,20 @@ public class TomcatWebServerFactoryCustomizerTests { assertThat(remoteIpValve.getInternalProxies()).isEqualTo("192.168.0.1"); } + @Test + public void customStaticResourceAllowCaching() { + bind("server.tomcat.resource.allow-caching=false"); + customizeAndRunServer((server) -> { + Mapper mapper = server.getTomcat().getService().getMapper(); + Object contextObjectToContextVersionMap = ReflectionTestUtils.getField(mapper, + "contextObjectToContextVersionMap"); + Object tomcatEmbeddedContext = ((Map) contextObjectToContextVersionMap) + .values().toArray()[0]; + assertThat(((StandardRoot) ReflectionTestUtils.getField(tomcatEmbeddedContext, + "resources")).isCachingAllowed()).isFalse(); + }); + } + @Test public void customStaticResourceCacheTtl() { bind("server.tomcat.resource.cache-ttl=10000"); diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index da8528ec56..a149580bdb 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -259,6 +259,7 @@ content into your application. Rather, pick only the properties that you need. server.tomcat.protocol-header-https-value=https # Value of the protocol header indicating whether the incoming request uses SSL. server.tomcat.redirect-context-root= # Whether requests to the context root should be redirected by appending a / to the path. server.tomcat.remote-ip-header= # Name of the HTTP header from which the remote IP is extracted. For instance, `X-FORWARDED-FOR`. + server.tomcat.resource.allow-caching= # Whether static resource caching is permitted for this web application. server.tomcat.resource.cache-ttl= # Time-to-live of the static resource cache. server.tomcat.uri-encoding=UTF-8 # Character encoding to use to decode the URI. server.tomcat.use-relative-redirects= # Whether HTTP 1.1 and later location headers generated by a call to sendRedirect will use relative or absolute redirects.