Refine Content-Range support for Resources
This commit restricts the support of `"Content-Range"` when returning `Resource` instances from Controllers - now only "HTTP 200 OK" responses will be considered, as Controllers might want to handle content range themselves. Issue: SPR-16921
This commit is contained in:
		
							parent
							
								
									d5df097e0e
								
							
						
					
					
						commit
						818e4b0776
					
				| 
						 | 
					@ -64,6 +64,7 @@ import org.springframework.web.util.UrlPathHelper;
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Arjen Poutsma
 | 
					 * @author Arjen Poutsma
 | 
				
			||||||
 * @author Rossen Stoyanchev
 | 
					 * @author Rossen Stoyanchev
 | 
				
			||||||
 | 
					 * @author Brian Clozel
 | 
				
			||||||
 * @since 3.1
 | 
					 * @since 3.1
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public abstract class AbstractMessageConverterMethodProcessor extends AbstractMessageConverterMethodArgumentResolver
 | 
					public abstract class AbstractMessageConverterMethodProcessor extends AbstractMessageConverterMethodArgumentResolver
 | 
				
			||||||
| 
						 | 
					@ -194,7 +195,8 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (isResourceType(value, returnType)) {
 | 
							if (isResourceType(value, returnType)) {
 | 
				
			||||||
			outputMessage.getHeaders().set(HttpHeaders.ACCEPT_RANGES, "bytes");
 | 
								outputMessage.getHeaders().set(HttpHeaders.ACCEPT_RANGES, "bytes");
 | 
				
			||||||
			if (value != null && inputMessage.getHeaders().getFirst(HttpHeaders.RANGE) != null) {
 | 
								if (value != null && inputMessage.getHeaders().getFirst(HttpHeaders.RANGE) != null
 | 
				
			||||||
 | 
										&& outputMessage.getServletResponse().getStatus() == 200) {
 | 
				
			||||||
				Resource resource = (Resource) value;
 | 
									Resource resource = (Resource) value;
 | 
				
			||||||
				try {
 | 
									try {
 | 
				
			||||||
					List<HttpRange> httpRanges = inputMessage.getHeaders().getRange();
 | 
										List<HttpRange> httpRanges = inputMessage.getHeaders().getRange();
 | 
				
			||||||
| 
						 | 
					@ -315,7 +317,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Return whether the returned value or the declared return type extend {@link Resource}.
 | 
						 * Return whether the returned value or the declared return type extends {@link Resource}.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	protected boolean isResourceType(@Nullable Object value, MethodParameter returnType) {
 | 
						protected boolean isResourceType(@Nullable Object value, MethodParameter returnType) {
 | 
				
			||||||
		Class<?> clazz = getReturnValueType(value, returnType);
 | 
							Class<?> clazz = getReturnValueType(value, returnType);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -568,8 +568,24 @@ public class HttpEntityMethodProcessorMockTests {
 | 
				
			||||||
		assertThat(servletResponse.getHeader(HttpHeaders.ACCEPT_RANGES), Matchers.isEmptyOrNullString());
 | 
							assertThat(servletResponse.getHeader(HttpHeaders.ACCEPT_RANGES), Matchers.isEmptyOrNullString());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Test //SPR-16921
 | 
				
			||||||
 | 
						public void disableRangeSupportIfContentRangePresent() throws Exception {
 | 
				
			||||||
 | 
							ResponseEntity<Resource> returnValue = ResponseEntity
 | 
				
			||||||
 | 
									.status(HttpStatus.PARTIAL_CONTENT)
 | 
				
			||||||
 | 
									.header(HttpHeaders.RANGE, "bytes=0-5")
 | 
				
			||||||
 | 
									.body(new ByteArrayResource("Content".getBytes(StandardCharsets.UTF_8)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							given(resourceRegionMessageConverter.canWrite(any(), eq(null))).willReturn(true);
 | 
				
			||||||
 | 
							given(resourceRegionMessageConverter.canWrite(any(), eq(APPLICATION_OCTET_STREAM))).willReturn(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							processor.handleReturnValue(returnValue, returnTypeResponseEntityResource, mavContainer, webRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							then(resourceRegionMessageConverter).should(never()).write(anyCollection(), any(), any());
 | 
				
			||||||
 | 
							assertEquals(206, servletResponse.getStatus());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Test  //SPR-14767
 | 
						@Test  //SPR-14767
 | 
				
			||||||
	public void shouldHandleValidatorHeadersInPutResponses() throws Exception {
 | 
						public void shouldHandleValidatorHeadersInputResponses() throws Exception {
 | 
				
			||||||
		servletRequest.setMethod("PUT");
 | 
							servletRequest.setMethod("PUT");
 | 
				
			||||||
		String etagValue = "\"some-etag\"";
 | 
							String etagValue = "\"some-etag\"";
 | 
				
			||||||
		ResponseEntity<String> returnValue = ResponseEntity.ok().header(HttpHeaders.ETAG, etagValue).body("body");
 | 
							ResponseEntity<String> returnValue = ResponseEntity.ok().header(HttpHeaders.ETAG, etagValue).body("body");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue