Skip to content

Commit a421bd2

Browse files
committed
Avoid duplicate Etag/Last-Modified header values
This commit improves SPR-13090 and avoids adding duplicate ETag and Last-Modified headers in HTTP responses. Previously, those were added twice to the response since: * we're adding all ResponseEntity headers to the response * the `checkNotModified` methods automatically add those headers Issue: SPR-13090
1 parent 8743b6b commit a421bd2

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,19 +168,27 @@ public void handleReturnValue(Object returnValue, MethodParameter returnType,
168168
}
169169

170170
HttpHeaders entityHeaders = responseEntity.getHeaders();
171-
if (!entityHeaders.isEmpty()) {
172-
outputMessage.getHeaders().putAll(entityHeaders);
173-
}
174171

175172
Object body = responseEntity.getBody();
176173
if (responseEntity instanceof ResponseEntity) {
174+
for (String headerName : entityHeaders.keySet()) {
175+
if(!HttpHeaders.LAST_MODIFIED.equals(headerName)
176+
&& !HttpHeaders.ETAG.equals(headerName)) {
177+
outputMessage.getHeaders().put(headerName, entityHeaders.get(headerName));
178+
}
179+
}
177180
if (isResourceNotModified(webRequest, (ResponseEntity<?>) responseEntity)) {
178181
// Ensure headers are flushed, no body should be written.
179182
outputMessage.flush();
180183
// Skip call to converters, as they may update the body.
181184
return;
182185
}
183186
}
187+
else {
188+
if (!entityHeaders.isEmpty()) {
189+
outputMessage.getHeaders().putAll(entityHeaders);
190+
}
191+
}
184192

185193
// Try even with null body. ResponseBodyAdvice could get involved.
186194
writeWithMessageConverters(body, returnType, inputMessage, outputMessage);

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ public void handleReturnTypeLastModified() throws Exception {
349349

350350
assertTrue(mavContainer.isRequestHandled());
351351
assertEquals(HttpStatus.NOT_MODIFIED.value(), servletResponse.getStatus());
352+
assertEquals(1, servletResponse.getHeaderValues(HttpHeaders.LAST_MODIFIED).size());
352353
assertEquals(dateFormat.format(oneMinuteAgo), servletResponse.getHeader(HttpHeaders.LAST_MODIFIED));
353354
assertEquals(0, servletResponse.getContentAsByteArray().length);
354355
}
@@ -369,6 +370,7 @@ public void handleReturnTypeEtag() throws Exception {
369370

370371
assertTrue(mavContainer.isRequestHandled());
371372
assertEquals(HttpStatus.NOT_MODIFIED.value(), servletResponse.getStatus());
373+
assertEquals(1, servletResponse.getHeaderValues(HttpHeaders.ETAG).size());
372374
assertEquals(etagValue, servletResponse.getHeader(HttpHeaders.ETAG));
373375
assertEquals(0, servletResponse.getContentAsByteArray().length);
374376
}
@@ -393,7 +395,9 @@ public void handleReturnTypeETagAndLastModified() throws Exception {
393395

394396
assertTrue(mavContainer.isRequestHandled());
395397
assertEquals(HttpStatus.NOT_MODIFIED.value(), servletResponse.getStatus());
398+
assertEquals(1, servletResponse.getHeaderValues(HttpHeaders.LAST_MODIFIED).size());
396399
assertEquals(dateFormat.format(oneMinuteAgo), servletResponse.getHeader(HttpHeaders.LAST_MODIFIED));
400+
assertEquals(1, servletResponse.getHeaderValues(HttpHeaders.ETAG).size());
397401
assertEquals(etagValue, servletResponse.getHeader(HttpHeaders.ETAG));
398402
assertEquals(0, servletResponse.getContentAsByteArray().length);
399403
}
@@ -419,7 +423,9 @@ public void handleReturnTypeChangedETagAndLastModified() throws Exception {
419423

420424
assertTrue(mavContainer.isRequestHandled());
421425
assertEquals(HttpStatus.OK.value(), servletResponse.getStatus());
426+
assertEquals(1, servletResponse.getHeaderValues(HttpHeaders.LAST_MODIFIED).size());
422427
assertEquals(dateFormat.format(oneMinuteAgo), servletResponse.getHeader(HttpHeaders.LAST_MODIFIED));
428+
assertEquals(1, servletResponse.getHeaderValues(HttpHeaders.ETAG).size());
423429
assertEquals(changedEtagValue, servletResponse.getHeader(HttpHeaders.ETAG));
424430
assertEquals(0, servletResponse.getContentAsByteArray().length);
425431
}

0 commit comments

Comments
 (0)