diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 8d6783976e..efac7c9f05 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -16,6 +16,7 @@ package org.springframework.web.servlet.resource; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -432,18 +433,23 @@ public class ResourceHttpRequestHandler extends WebContentGenerator implements H * @throws IOException in case of errors while writing the content */ protected void writeContent(HttpServletResponse response, Resource resource) throws IOException { - InputStream in = resource.getInputStream(); try { - StreamUtils.copy(in, response.getOutputStream()); - } - finally { + InputStream in = resource.getInputStream(); try { - in.close(); + StreamUtils.copy(in, response.getOutputStream()); } - catch (IOException ex) { - // ignore + finally { + try { + in.close(); + } + catch (Throwable ex) { + // ignore, see SPR-12999 + } } } + catch (FileNotFoundException ex) { + // ignore, see SPR-12999 + } } /** diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index b2bb91be40..ed80ea0251 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -17,8 +17,12 @@ package org.springframework.web.servlet.resource; import static org.junit.Assert.*; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.*; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -60,6 +64,7 @@ public class ResourceHttpRequestHandlerTests { List paths = new ArrayList<>(2); paths.add(new ClassPathResource("test/", getClass())); paths.add(new ClassPathResource("testalternatepath/", getClass())); + paths.add(new ClassPathResource("META-INF/resources/webjars/")); this.handler = new ResourceHttpRequestHandler(); this.handler.setLocations(paths); @@ -247,9 +252,10 @@ public class ResourceHttpRequestHandlerTests { PathResourceResolver resolver = (PathResourceResolver) this.handler.getResourceResolvers().get(0); Resource[] locations = resolver.getAllowedLocations(); - assertEquals(2, locations.length); + assertEquals(3, locations.length); assertEquals("test/", ((ClassPathResource) locations[0]).getPath()); assertEquals("testalternatepath/", ((ClassPathResource) locations[1]).getPath()); + assertEquals("META-INF/resources/webjars/", ((ClassPathResource) locations[2]).getPath()); } @Test @@ -294,6 +300,14 @@ public class ResourceHttpRequestHandlerTests { assertEquals(404, this.response.getStatus()); } + @Test + public void directoryInJarFile() throws Exception { + this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "underscorejs/"); + this.handler.handleRequest(this.request, this.response); + assertEquals(200, this.response.getStatus()); + assertEquals(0, this.response.getContentLength()); + } + @Test public void missingResourcePath() throws Exception { this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, ""); @@ -425,6 +439,33 @@ public class ResourceHttpRequestHandlerTests { assertEquals("t.", ranges[11]); } + // SPR-12999 + @Test + public void writeContentNotGettingInputStream() throws Exception { + Resource resource = mock(Resource.class); + given(resource.getInputStream()).willThrow(FileNotFoundException.class); + + this.handler.writeContent(this.response, resource); + + assertEquals(200, this.response.getStatus()); + assertEquals(0, this.response.getContentLength()); + } + + // SPR-12999 + @Test + public void writeContentNotClosingInputStream() throws Exception { + Resource resource = mock(Resource.class); + InputStream inputStream = mock(InputStream.class); + given(resource.getInputStream()).willReturn(inputStream); + given(inputStream.read(any())).willReturn(-1); + doThrow(new NullPointerException()).when(inputStream).close(); + + this.handler.writeContent(this.response, resource); + + assertEquals(200, this.response.getStatus()); + assertEquals(0, this.response.getContentLength()); + } + private long headerAsLong(String responseHeaderName) { return Long.valueOf(this.response.getHeader(responseHeaderName));