Fix conditional requests support for HttpEntity
Prior to this commit, `HttpEntityMethodProcessor` would rely on `ServletWebRequest` to process conditional requests and with incoming `"If-Modified-Since"` / `"If-None-Match"` request headers. This approach is problematic since in that class: * response is wrapped in a `ServletServerHttpResponse` * this wrapped response does not write response headers right away * `ServletWebRequest.checkNotModified` methods can't apply their logic with incomplete response headers This solution adds some minimal code duplication and applies the conditional request logic within the Processor. A possible alternative would be to improve the `ServletServerHttpResponse$ServletResponseHttpHeaders` implementation with write methods - but this solution would only work for Servlet 3.x applications. Issue: SPR-13090
This commit is contained in:
@@ -181,33 +181,21 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
|
||||
public boolean checkNotModified(long lastModifiedTimestamp) {
|
||||
HttpServletResponse response = getResponse();
|
||||
if (lastModifiedTimestamp >= 0 && !this.notModified) {
|
||||
if (response == null || isResponseCompatibleWithConditional(response, HEADER_LAST_MODIFIED)) {
|
||||
if (response == null || HttpStatus.valueOf(response.getStatus()).is2xxSuccessful()) {
|
||||
this.notModified = isTimeStampNotModified(lastModifiedTimestamp);
|
||||
if (response != null) {
|
||||
if (this.notModified && supportsNotModifiedStatus()) {
|
||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
}
|
||||
response.setHeader(HEADER_LAST_MODIFIED, formatDate(lastModifiedTimestamp));
|
||||
if(response.getHeader(HEADER_LAST_MODIFIED) == null) {
|
||||
response.setHeader(HEADER_LAST_MODIFIED, formatDate(lastModifiedTimestamp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.notModified;
|
||||
}
|
||||
|
||||
private boolean isResponseCompatibleWithConditional(HttpServletResponse response, String... headers) {
|
||||
if (response != null) {
|
||||
if (HttpStatus.valueOf(response.getStatus()).is2xxSuccessful()) {
|
||||
for (String header : headers) {
|
||||
if (response.containsHeader(header)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean isTimeStampNotModified(long lastModifiedTimestamp) {
|
||||
long ifModifiedSince = -1;
|
||||
@@ -235,14 +223,16 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
|
||||
public boolean checkNotModified(String etag) {
|
||||
HttpServletResponse response = getResponse();
|
||||
if (StringUtils.hasLength(etag) && !this.notModified) {
|
||||
if (response == null || isResponseCompatibleWithConditional(response, HEADER_ETAG)) {
|
||||
if (response == null || HttpStatus.valueOf(response.getStatus()).is2xxSuccessful()) {
|
||||
etag = addEtagPadding(etag);
|
||||
this.notModified = isETagNotModified(etag);
|
||||
if (response != null) {
|
||||
if (this.notModified && supportsNotModifiedStatus()) {
|
||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
}
|
||||
response.setHeader(HEADER_ETAG, etag);
|
||||
if(response.getHeader(HEADER_ETAG) == null) {
|
||||
response.setHeader(HEADER_ETAG, etag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,15 +273,19 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
|
||||
public boolean checkNotModified(String etag, long lastModifiedTimestamp) {
|
||||
HttpServletResponse response = getResponse();
|
||||
if (StringUtils.hasLength(etag) && !this.notModified) {
|
||||
if (response == null || isResponseCompatibleWithConditional(response, HEADER_ETAG, HEADER_LAST_MODIFIED)) {
|
||||
if (response == null || HttpStatus.valueOf(response.getStatus()).is2xxSuccessful()) {
|
||||
etag = addEtagPadding(etag);
|
||||
this.notModified = isETagNotModified(etag) && isTimeStampNotModified(lastModifiedTimestamp);
|
||||
if (response != null) {
|
||||
if (this.notModified && supportsNotModifiedStatus()) {
|
||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
}
|
||||
response.setHeader(HEADER_ETAG, etag);
|
||||
response.setHeader(HEADER_LAST_MODIFIED, formatDate(lastModifiedTimestamp));
|
||||
if(response.getHeader(HEADER_ETAG) == null) {
|
||||
response.setHeader(HEADER_ETAG, etag);
|
||||
}
|
||||
if(response.getHeader(HEADER_LAST_MODIFIED) == null) {
|
||||
response.setHeader(HEADER_LAST_MODIFIED, formatDate(lastModifiedTimestamp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user