Add option for ignoring last-modified for static resources

Prior to this commit, the resource handler serving static resources for
Spring MVC and Spring WebFlux would always look at the
`Resource#lastModified` information, derive the `"Last-Modified"` HTTP
response header and support HTTP conditional requests with that
information.

In some cases, builds or packaging tools choose to set this last
modification date to a static date in the past. This allows tools to
have reproducible builds or to leverage caching given the static
resources content didn't change.

This can lead to problems where this static date (e.g. "1980-01-01") is
used literally in HTTP responses and will make the HTTP caching
mechanism counter-productive: the content of the resources changed, but
the application insists on saying it didn't change since the 80s...

This commit adds a new configuration option to disable this support -
there is no way to automatically discard those dates: there is no
standard for that and many don't use he "EPOCH 0 date" as it can lead to
compatibility issues with different OSes.

Closes gh-25845
This commit is contained in:
Brian Clozel
2020-10-06 16:23:51 +02:00
parent cf61545f41
commit a0af552d0f
9 changed files with 124 additions and 8 deletions

View File

@@ -212,6 +212,12 @@ public class ResourceHandlerRegistryTests {
assertThat(transformers.get(2)).isSameAs(cssLinkTransformer);
}
@Test
void ignoreLastModified() {
this.registration.setUseLastModified(false);
assertThat(getHandler("/resources/**").isUseLastModified()).isFalse();
}
private ResourceWebHandler getHandler(String pathPattern) {
SimpleUrlHandlerMapping mapping = (SimpleUrlHandlerMapping) this.registry.getHandlerMapping();

View File

@@ -631,6 +631,20 @@ public class ResourceWebHandlerTests {
assertThat(exchange.getResponse().getHeaders().getCacheControl()).isEqualTo("max-age=3600");
}
@Test
void ignoreLastModified() {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get(""));
setPathWithinHandlerMapping(exchange, "foo.css");
this.handler.setUseLastModified(false);
this.handler.handle(exchange).block(TIMEOUT);
HttpHeaders headers = exchange.getResponse().getHeaders();
assertThat(headers.getContentType()).isEqualTo(MediaType.parseMediaType("text/css"));
assertThat(headers.getContentLength()).isEqualTo(17);
assertThat(headers.containsKey("Last-Modified")).isFalse();
assertResponseBody(exchange, "h1 { color:red; }");
}
private void setPathWithinHandlerMapping(ServerWebExchange exchange, String path) {
exchange.getAttributes().put(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE,