Browse Source

Add caching headers to unmodified static resources

per https://www.rfc-editor.org/rfc/rfc7232#section-4.1

The server generating a 304 response MUST generate any of the
following header fields that would have been sent in a 200 (OK)
response to the same request: Cache-Control, Content-Location, Date,
ETag, Expires, and Vary.

Closes gh-34614

Signed-off-by: James Yuzawa <jtyuzawa@gmail.com>
pull/35405/head
James Yuzawa 9 months ago committed by Brian Clozel
parent
commit
aa5c0dcd72
  1. 8
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java
  2. 6
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java

8
spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java

@ -569,7 +569,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @@ -569,7 +569,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
* If the resource exists, the request will be checked for the presence of the
* {@code Last-Modified} header, and its value will be compared against the last-modified
* timestamp of the given resource, returning a {@code 304} status code if the
* {@code Last-Modified} value is greater. If the resource is newer than the
* {@code Last-Modified} value is greater. If the resource is newer than the
* {@code Last-Modified} value, or the header is not present, the content resource
* of the resource will be written to the response with caching headers
* set to expire one year in the future.
@ -593,6 +593,9 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @@ -593,6 +593,9 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
// Supported methods and required session
checkRequest(request);
// Apply cache settings, if any
prepareResponse(response);
// Header phase
String eTagValue = (this.getEtagGenerator() != null) ? this.getEtagGenerator().apply(resource) : null;
long lastModified = (this.isUseLastModified()) ? resource.lastModified() : -1;
@ -601,9 +604,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @@ -601,9 +604,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
return;
}
// Apply cache settings, if any
prepareResponse(response);
// Check the media type for the resource
MediaType mediaType = getMediaType(request, resource);
setHeaders(response, resource, mediaType);

6
spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -479,11 +479,13 @@ class ResourceHttpRequestHandlerTests { @@ -479,11 +479,13 @@ class ResourceHttpRequestHandlerTests {
@Test
void shouldRespondWithNotModifiedWhenModifiedSince() throws Exception {
this.handler.setCacheSeconds(3600);
this.handler.afterPropertiesSet();
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.request.addHeader("If-Modified-Since", resourceLastModified("test/foo.css"));
this.handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_NOT_MODIFIED);
assertThat(this.response.getHeader("Cache-Control")).isEqualTo("max-age=3600");
}
@Test
@ -498,12 +500,14 @@ class ResourceHttpRequestHandlerTests { @@ -498,12 +500,14 @@ class ResourceHttpRequestHandlerTests {
@Test
void shouldRespondWithNotModifiedWhenEtag() throws Exception {
this.handler.setCacheSeconds(3600);
this.handler.setEtagGenerator(resource -> "testEtag");
this.handler.afterPropertiesSet();
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.request.addHeader("If-None-Match", "\"testEtag\"");
this.handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_NOT_MODIFIED);
assertThat(this.response.getHeader("Cache-Control")).isEqualTo("max-age=3600");
}
@Test

Loading…
Cancel
Save