Do not process conditional requests for non-GET
Prior to this commit, HttpEntityMethodProcessor would process conditional requests even if those aren't GET requests. This is an issue for POST requests with "If-None-Match: *" headers and many other use cases, which should not receive an HTTP 304 Not Modified status in response. This commit only triggers ETag/Last-Modified conditional requests bits for GET requests. Issue: SPR-13496
This commit is contained in:
parent
525d111210
commit
583a48ab75
|
|
@ -172,7 +172,8 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
|||
Object body = responseEntity.getBody();
|
||||
if (responseEntity instanceof ResponseEntity) {
|
||||
outputMessage.setStatusCode(((ResponseEntity<?>) responseEntity).getStatusCode());
|
||||
if (isResourceNotModified(inputMessage, outputMessage)) {
|
||||
if (inputMessage.getServletRequest().getMethod() == "GET"
|
||||
&& isResourceNotModified(inputMessage, outputMessage)) {
|
||||
outputMessage.setStatusCode(HttpStatus.NOT_MODIFIED);
|
||||
// Ensure headers are flushed, no body should be written.
|
||||
outputMessage.flush();
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public class HttpEntityMethodProcessorMockTests {
|
|||
returnTypeInt = new MethodParameter(getClass().getMethod("handle3"), -1);
|
||||
|
||||
mavContainer = new ModelAndViewContainer();
|
||||
servletRequest = new MockHttpServletRequest("POST", "/foo");
|
||||
servletRequest = new MockHttpServletRequest("GET", "/foo");
|
||||
servletResponse = new MockHttpServletResponse();
|
||||
webRequest = new ServletWebRequest(servletRequest, servletResponse);
|
||||
}
|
||||
|
|
@ -182,6 +182,7 @@ public class HttpEntityMethodProcessorMockTests {
|
|||
@Test(expected = HttpMediaTypeNotSupportedException.class)
|
||||
public void resolveArgumentNotReadable() throws Exception {
|
||||
MediaType contentType = MediaType.TEXT_PLAIN;
|
||||
servletRequest.setMethod("POST");
|
||||
servletRequest.addHeader("Content-Type", contentType.toString());
|
||||
|
||||
given(messageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(contentType));
|
||||
|
|
@ -194,6 +195,7 @@ public class HttpEntityMethodProcessorMockTests {
|
|||
|
||||
@Test(expected = HttpMediaTypeNotSupportedException.class)
|
||||
public void resolveArgumentNoContentType() throws Exception {
|
||||
servletRequest.setMethod("POST");
|
||||
servletRequest.setContent("some content".getBytes(Charset.forName("UTF-8")));
|
||||
processor.resolveArgument(paramHttpEntity, mavContainer, webRequest, null);
|
||||
fail("Expected exception");
|
||||
|
|
@ -455,6 +457,32 @@ public class HttpEntityMethodProcessorMockTests {
|
|||
assertEquals(0, servletResponse.getContentAsByteArray().length);
|
||||
}
|
||||
|
||||
// SPR-13496
|
||||
@Test
|
||||
public void handleReturnTypePostRequestWithIfNotModified() throws Exception {
|
||||
String wildcardValue = "*";
|
||||
String etagValue = "\"some-etag\"";
|
||||
servletRequest.setMethod("POST");
|
||||
servletRequest.addHeader(HttpHeaders.IF_NONE_MATCH, wildcardValue);
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
responseHeaders.set(HttpHeaders.ETAG, etagValue);
|
||||
ResponseEntity<String> returnValue = new ResponseEntity<String>("body", responseHeaders, HttpStatus.OK);
|
||||
|
||||
given(messageConverter.canWrite(String.class, null)).willReturn(true);
|
||||
given(messageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.TEXT_PLAIN));
|
||||
given(messageConverter.canWrite(String.class, MediaType.TEXT_PLAIN)).willReturn(true);
|
||||
|
||||
|
||||
processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest);
|
||||
|
||||
assertTrue(mavContainer.isRequestHandled());
|
||||
assertEquals(HttpStatus.OK.value(), servletResponse.getStatus());
|
||||
assertEquals(1, servletResponse.getHeaderValues(HttpHeaders.ETAG).size());
|
||||
assertEquals(etagValue, servletResponse.getHeader(HttpHeaders.ETAG));
|
||||
ArgumentCaptor<HttpOutputMessage> outputMessage = ArgumentCaptor.forClass(HttpOutputMessage.class);
|
||||
verify(messageConverter).write(eq("body"), eq(MediaType.TEXT_PLAIN), outputMessage.capture());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public ResponseEntity<String> handle1(HttpEntity<String> httpEntity, ResponseEntity<String> entity,
|
||||
int i, RequestEntity<String> requestEntity) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue