Merge branch '5.2.x' into master
This commit is contained in:
commit
24cef14683
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -375,15 +375,9 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
|
|||
|
||||
// Check the media type for the resource
|
||||
MediaType mediaType = MediaTypeFactory.getMediaType(resource).orElse(null);
|
||||
setHeaders(exchange, resource, mediaType);
|
||||
|
||||
// Content phase
|
||||
if (HttpMethod.HEAD.matches(exchange.getRequest().getMethodValue())) {
|
||||
setHeaders(exchange, resource, mediaType);
|
||||
exchange.getResponse().getHeaders().set(HttpHeaders.ACCEPT_RANGES, "bytes");
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
setHeaders(exchange, resource, mediaType);
|
||||
ResourceHttpMessageWriter writer = getResourceHttpMessageWriter();
|
||||
Assert.state(writer != null, "No ResourceHttpMessageWriter");
|
||||
return writer.write(Mono.just(resource),
|
||||
|
@ -558,6 +552,7 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
|
|||
if (mediaType != null) {
|
||||
headers.setContentType(mediaType);
|
||||
}
|
||||
|
||||
if (resource instanceof HttpResource) {
|
||||
HttpHeaders resourceHeaders = ((HttpResource) resource).getResponseHeaders();
|
||||
exchange.getResponse().getHeaders().putAll(resourceHeaders);
|
||||
|
|
|
@ -118,10 +118,6 @@ public class ResourceWebHandlerTests {
|
|||
assertThat(resourceLastModifiedDate("test/foo.css") / 1000).isEqualTo(headers.getLastModified() / 1000);
|
||||
assertThat(headers.getFirst("Accept-Ranges")).isEqualTo("bytes");
|
||||
assertThat(headers.get("Accept-Ranges").size()).isEqualTo(1);
|
||||
|
||||
StepVerifier.create(exchange.getResponse().getBody())
|
||||
.expectErrorMatches(ex -> ex.getMessage().startsWith("No content was written"))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -531,22 +531,16 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
|||
|
||||
// Check the media type for the resource
|
||||
MediaType mediaType = getMediaType(request, resource);
|
||||
setHeaders(response, resource, mediaType);
|
||||
|
||||
// Content phase
|
||||
if (METHOD_HEAD.equals(request.getMethod())) {
|
||||
setHeaders(response, resource, mediaType);
|
||||
return;
|
||||
}
|
||||
|
||||
ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(response);
|
||||
if (request.getHeader(HttpHeaders.RANGE) == null) {
|
||||
Assert.state(this.resourceHttpMessageConverter != null, "Not initialized");
|
||||
setHeaders(response, resource, mediaType);
|
||||
this.resourceHttpMessageConverter.write(resource, mediaType, outputMessage);
|
||||
}
|
||||
else {
|
||||
Assert.state(this.resourceRegionHttpMessageConverter != null, "Not initialized");
|
||||
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
|
||||
ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(request);
|
||||
try {
|
||||
List<HttpRange> httpRanges = inputMessage.getHeaders().getRange();
|
||||
|
@ -555,7 +549,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
|||
HttpRange.toResourceRegions(httpRanges, resource), mediaType, outputMessage);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
response.setHeader("Content-Range", "bytes */" + resource.contentLength());
|
||||
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + resource.contentLength());
|
||||
response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
|
||||
}
|
||||
}
|
||||
|
@ -773,6 +767,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
|||
if (mediaType != null) {
|
||||
response.setContentType(mediaType.toString());
|
||||
}
|
||||
|
||||
if (resource instanceof HttpResource) {
|
||||
HttpHeaders resourceHeaders = ((HttpResource) resource).getResponseHeaders();
|
||||
resourceHeaders.forEach((headerName, headerValues) -> {
|
||||
|
@ -788,6 +783,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
@ -58,6 +59,7 @@ import static org.mockito.Mockito.mock;
|
|||
* @author Rossen Stoyanchev
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@ExtendWith(GzipSupport.class)
|
||||
public class ResourceHttpRequestHandlerTests {
|
||||
|
||||
private ResourceHttpRequestHandler handler;
|
||||
|
@ -116,7 +118,6 @@ public class ResourceHttpRequestHandlerTests {
|
|||
assertThat(this.response.getDateHeader("Last-Modified") / 1000).isEqualTo(resourceLastModified("test/foo.css") / 1000);
|
||||
assertThat(this.response.getHeader("Accept-Ranges")).isEqualTo("bytes");
|
||||
assertThat(this.response.getHeaders("Accept-Ranges").size()).isEqualTo(1);
|
||||
assertThat(this.response.getContentAsByteArray().length).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -657,6 +658,49 @@ public class ResourceHttpRequestHandlerTests {
|
|||
assertThat(ranges[11]).isEqualTo("t.");
|
||||
}
|
||||
|
||||
@Test // gh-25976
|
||||
public void partialContentByteRangeWithEncodedResource(GzipSupport.GzippedFiles gzippedFiles) throws Exception {
|
||||
String path = "js/foo.js";
|
||||
gzippedFiles.create(path);
|
||||
|
||||
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
|
||||
handler.setResourceResolvers(Arrays.asList(new EncodedResourceResolver(), new PathResourceResolver()));
|
||||
handler.setLocations(Collections.singletonList(new ClassPathResource("test/", getClass())));
|
||||
handler.setServletContext(new MockServletContext());
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
this.request.addHeader("Accept-Encoding", "gzip");
|
||||
this.request.addHeader("Range", "bytes=0-1");
|
||||
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, path);
|
||||
handler.handleRequest(this.request, this.response);
|
||||
|
||||
assertThat(this.response.getStatus()).isEqualTo(206);
|
||||
assertThat(this.response.getHeaderNames()).containsExactlyInAnyOrder(
|
||||
"Content-Type", "Content-Length", "Content-Range", "Accept-Ranges",
|
||||
"Last-Modified", "Content-Encoding", "Vary");
|
||||
|
||||
assertThat(this.response.getContentType()).isEqualTo("text/javascript");
|
||||
assertThat(this.response.getContentLength()).isEqualTo(2);
|
||||
assertThat(this.response.getHeader("Content-Range")).isEqualTo("bytes 0-1/66");
|
||||
assertThat(this.response.getHeaderValues("Accept-Ranges")).containsExactly("bytes");
|
||||
assertThat(this.response.getHeaderValues("Content-Encoding")).containsExactly("gzip");
|
||||
assertThat(this.response.getHeaderValues("Vary")).containsExactly("Accept-Encoding");
|
||||
}
|
||||
|
||||
@Test // gh-25976
|
||||
public void partialContentWithHttpHead() throws Exception {
|
||||
this.request.setMethod("HEAD");
|
||||
this.request.addHeader("Range", "bytes=0-1");
|
||||
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.txt");
|
||||
this.handler.handleRequest(this.request, this.response);
|
||||
|
||||
assertThat(this.response.getStatus()).isEqualTo(206);
|
||||
assertThat(this.response.getContentType()).isEqualTo("text/plain");
|
||||
assertThat(this.response.getContentLength()).isEqualTo(2);
|
||||
assertThat(this.response.getHeader("Content-Range")).isEqualTo("bytes 0-1/10");
|
||||
assertThat(this.response.getHeaderValues("Accept-Ranges")).containsExactly("bytes");
|
||||
}
|
||||
|
||||
@Test // SPR-14005
|
||||
public void doOverwriteExistingCacheControlHeaders() throws Exception {
|
||||
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
|
||||
|
|
Loading…
Reference in New Issue