Skip to content

Commit c98cdd4

Browse files
committed
Fix missing ETag/LastModified headers in responses
Prior to this commit, the `HttpEntityMethodProcessor` would avoid writing ETag/Last-Modified response headers before calling `ServletWebRequest` to process conditional requests. This was done to avoid duplicate response header values due to headers being already written to the underlying servlet response. This is still necessary for GET/HEAD requests, since this is properly handled by `ServletWebRequest` for those cases. But `HttpEntityMethodProcessor` should not make that decision for PUT/PATCH/POST responses since developers are adding response headers on purpose and should be in control of the situation — whereas `ServletWebRequest` does not write those headers in those cases. Issue: SPR-14767 Cherry-picked from: ee17f56
1 parent d04567b commit c98cdd4

File tree

2 files changed

+130
-152
lines changed

2 files changed

+130
-152
lines changed

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

+15-12
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.core.ResolvableType;
2929
import org.springframework.http.HttpEntity;
3030
import org.springframework.http.HttpHeaders;
31+
import org.springframework.http.HttpMethod;
3132
import org.springframework.http.RequestEntity;
3233
import org.springframework.http.ResponseEntity;
3334
import org.springframework.http.converter.HttpMessageConverter;
@@ -181,16 +182,16 @@ public void handleReturnValue(Object returnValue, MethodParameter returnType,
181182
}
182183

183184
if (responseEntity instanceof ResponseEntity) {
184-
int responseStatus = ((ResponseEntity<?>) responseEntity).getStatusCodeValue();
185-
outputMessage.getServletResponse().setStatus(responseStatus);
186-
if(responseStatus == 200) {
187-
if (isResourceNotModified(inputMessage, outputMessage)) {
188-
// Ensure headers are flushed, no body should be written.
189-
outputMessage.flush();
190-
// Skip call to converters, as they may update the body.
191-
return;
192-
}
193-
}
185+
int returnStatus = ((ResponseEntity<?>) responseEntity).getStatusCodeValue();
186+
outputMessage.getServletResponse().setStatus(returnStatus);
187+
if (returnStatus == 200) {
188+
if (isResourceNotModified(inputMessage, outputMessage)) {
189+
// Ensure headers are flushed, no body should be written.
190+
outputMessage.flush();
191+
// Skip call to converters, as they may update the body.
192+
return;
193+
}
194+
}
194195
}
195196

196197
// Try even with null body. ResponseBodyAdvice could get involved.
@@ -227,8 +228,10 @@ private boolean isResourceNotModified(ServletServerHttpRequest inputMessage, Ser
227228
HttpHeaders responseHeaders = outputMessage.getHeaders();
228229
String etag = responseHeaders.getETag();
229230
long lastModifiedTimestamp = responseHeaders.getLastModified();
230-
responseHeaders.remove(HttpHeaders.ETAG);
231-
responseHeaders.remove(HttpHeaders.LAST_MODIFIED);
231+
if (inputMessage.getMethod() == HttpMethod.GET || inputMessage.getMethod() == HttpMethod.HEAD) {
232+
responseHeaders.remove(HttpHeaders.ETAG);
233+
responseHeaders.remove(HttpHeaders.LAST_MODIFIED);
234+
}
232235

233236
return servletWebRequest.checkNotModified(etag, lastModifiedTimestamp);
234237
}

0 commit comments

Comments
 (0)