Skip to content

Commit aa5c0dc

Browse files
yuzawa-sanbclozel
authored andcommitted
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 <[email protected]>
1 parent 4a46d95 commit aa5c0dc

File tree

2 files changed

+9
-5
lines changed

2 files changed

+9
-5
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ protected org.springframework.web.accept.PathExtensionContentNegotiationStrategy
569569
* If the resource exists, the request will be checked for the presence of the
570570
* {@code Last-Modified} header, and its value will be compared against the last-modified
571571
* timestamp of the given resource, returning a {@code 304} status code if the
572-
* {@code Last-Modified} value is greater. If the resource is newer than the
572+
* {@code Last-Modified} value is greater. If the resource is newer than the
573573
* {@code Last-Modified} value, or the header is not present, the content resource
574574
* of the resource will be written to the response with caching headers
575575
* set to expire one year in the future.
@@ -593,6 +593,9 @@ public void handleRequest(HttpServletRequest request, HttpServletResponse respon
593593
// Supported methods and required session
594594
checkRequest(request);
595595

596+
// Apply cache settings, if any
597+
prepareResponse(response);
598+
596599
// Header phase
597600
String eTagValue = (this.getEtagGenerator() != null) ? this.getEtagGenerator().apply(resource) : null;
598601
long lastModified = (this.isUseLastModified()) ? resource.lastModified() : -1;
@@ -601,9 +604,6 @@ public void handleRequest(HttpServletRequest request, HttpServletResponse respon
601604
return;
602605
}
603606

604-
// Apply cache settings, if any
605-
prepareResponse(response);
606-
607607
// Check the media type for the resource
608608
MediaType mediaType = getMediaType(request, resource);
609609
setHeaders(response, resource, mediaType);

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -479,11 +479,13 @@ void configureVersionResourceResolver() throws Exception {
479479

480480
@Test
481481
void shouldRespondWithNotModifiedWhenModifiedSince() throws Exception {
482+
this.handler.setCacheSeconds(3600);
482483
this.handler.afterPropertiesSet();
483484
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
484485
this.request.addHeader("If-Modified-Since", resourceLastModified("test/foo.css"));
485486
this.handler.handleRequest(this.request, this.response);
486487
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_NOT_MODIFIED);
488+
assertThat(this.response.getHeader("Cache-Control")).isEqualTo("max-age=3600");
487489
}
488490

489491
@Test
@@ -498,12 +500,14 @@ void shouldRespondWithModifiedResource() throws Exception {
498500

499501
@Test
500502
void shouldRespondWithNotModifiedWhenEtag() throws Exception {
503+
this.handler.setCacheSeconds(3600);
501504
this.handler.setEtagGenerator(resource -> "testEtag");
502505
this.handler.afterPropertiesSet();
503506
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
504507
this.request.addHeader("If-None-Match", "\"testEtag\"");
505508
this.handler.handleRequest(this.request, this.response);
506509
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_NOT_MODIFIED);
510+
assertThat(this.response.getHeader("Cache-Control")).isEqualTo("max-age=3600");
507511
}
508512

509513
@Test

0 commit comments

Comments
 (0)