summaryrefslogtreecommitdiff
path: root/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java
diff options
context:
space:
mode:
Diffstat (limited to 'spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java')
-rw-r--r--spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java207
1 files changed, 154 insertions, 53 deletions
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 453bdbdc..c78f7573 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
@@ -16,20 +16,14 @@
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.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
-
import javax.servlet.http.HttpServletResponse;
import org.hamcrest.Matchers;
@@ -39,19 +33,27 @@ import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.util.StringUtils;
import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.accept.ContentNegotiationManager;
+import org.springframework.web.accept.ContentNegotiationManagerFactoryBean;
import org.springframework.web.servlet.HandlerMapping;
+import static org.junit.Assert.*;
+
/**
* Unit tests for ResourceHttpRequestHandler.
*
* @author Keith Donald
* @author Jeremy Grelle
* @author Rossen Stoyanchev
+ * @author Brian Clozel
*/
public class ResourceHttpRequestHandlerTests {
@@ -94,10 +96,39 @@ public class ResourceHttpRequestHandlerTests {
assertEquals("max-age=3600", this.response.getHeader("Cache-Control"));
assertTrue(this.response.containsHeader("Last-Modified"));
assertEquals(this.response.getHeader("Last-Modified"), resourceLastModifiedDate("test/foo.css"));
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
assertEquals("h1 { color:red; }", this.response.getContentAsString());
}
@Test
+ public void getResourceHttpHeader() throws Exception {
+ this.request.setMethod("HEAD");
+ this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
+ this.handler.handleRequest(this.request, this.response);
+
+ assertEquals(200, this.response.getStatus());
+ assertEquals("text/css", this.response.getContentType());
+ assertEquals(17, this.response.getContentLength());
+ assertEquals("max-age=3600", this.response.getHeader("Cache-Control"));
+ assertTrue(this.response.containsHeader("Last-Modified"));
+ assertEquals(this.response.getHeader("Last-Modified"), resourceLastModifiedDate("test/foo.css"));
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
+ assertEquals(0, this.response.getContentAsByteArray().length);
+ }
+
+ @Test
+ public void getResourceHttpOptions() throws Exception {
+ this.request.setMethod("OPTIONS");
+ this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
+ this.handler.handleRequest(this.request, this.response);
+
+ assertEquals(200, this.response.getStatus());
+ assertEquals("GET,HEAD,OPTIONS", this.response.getHeader("Allow"));
+ }
+
+ @Test
public void getResourceNoCache() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.handler.setCacheSeconds(0);
@@ -106,6 +137,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals("no-store", this.response.getHeader("Cache-Control"));
assertTrue(this.response.containsHeader("Last-Modified"));
assertEquals(this.response.getHeader("Last-Modified"), resourceLastModifiedDate("test/foo.css"));
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -119,6 +152,8 @@ public class ResourceHttpRequestHandlerTests {
this.handler.handleRequest(this.request, this.response);
assertEquals("\"versionString\"", this.response.getHeader("ETag"));
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -135,6 +170,8 @@ public class ResourceHttpRequestHandlerTests {
assertTrue(dateHeaderAsLong("Expires") >= System.currentTimeMillis() - 1000 + (3600 * 1000));
assertTrue(this.response.containsHeader("Last-Modified"));
assertEquals(this.response.getHeader("Last-Modified"), resourceLastModifiedDate("test/foo.css"));
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -153,6 +190,8 @@ public class ResourceHttpRequestHandlerTests {
assertTrue(dateHeaderAsLong("Expires") <= System.currentTimeMillis());
assertTrue(this.response.containsHeader("Last-Modified"));
assertEquals(dateHeaderAsLong("Last-Modified") / 1000, resourceLastModified("test/foo.css") / 1000);
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -164,6 +203,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals("max-age=3600", this.response.getHeader("Cache-Control"));
assertTrue(this.response.containsHeader("Last-Modified"));
assertEquals(this.response.getHeader("Last-Modified"), resourceLastModifiedDate("test/foo.html"));
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -176,6 +217,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals("max-age=3600", this.response.getHeader("Cache-Control"));
assertTrue(this.response.containsHeader("Last-Modified"));
assertEquals(this.response.getHeader("Last-Modified"), resourceLastModifiedDate("testalternatepath/baz.css"));
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
assertEquals("h1 { color:red; }", this.response.getContentAsString());
}
@@ -197,18 +240,96 @@ public class ResourceHttpRequestHandlerTests {
assertEquals("function foo() { console.log(\"hello world\"); }", this.response.getContentAsString());
}
+ @Test // SPR-13658
+ public void getResourceWithRegisteredMediaType() throws Exception {
+ ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean();
+ factory.addMediaType("css", new MediaType("foo", "bar"));
+ factory.afterPropertiesSet();
+ ContentNegotiationManager manager = factory.getObject();
+
+ List<Resource> paths = Collections.singletonList(new ClassPathResource("test/", getClass()));
+ this.handler = new ResourceHttpRequestHandler();
+ this.handler.setLocations(paths);
+ this.handler.setContentNegotiationManager(manager);
+ this.handler.afterPropertiesSet();
+
+ this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
+ this.handler.handleRequest(this.request, this.response);
+
+ assertEquals("foo/bar", this.response.getContentType());
+ assertEquals("h1 { color:red; }", this.response.getContentAsString());
+ }
+
+ @Test // SPR-13658
+ public void getResourceWithRegisteredMediaTypeDefaultStrategy() throws Exception {
+ ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean();
+ factory.setFavorPathExtension(false);
+ factory.setDefaultContentType(new MediaType("foo", "bar"));
+ factory.afterPropertiesSet();
+ ContentNegotiationManager manager = factory.getObject();
+
+ List<Resource> paths = Collections.singletonList(new ClassPathResource("test/", getClass()));
+ this.handler = new ResourceHttpRequestHandler();
+ this.handler.setLocations(paths);
+ this.handler.setContentNegotiationManager(manager);
+ this.handler.afterPropertiesSet();
+
+ this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
+ this.handler.handleRequest(this.request, this.response);
+
+ assertEquals("foo/bar", this.response.getContentType());
+ assertEquals("h1 { color:red; }", this.response.getContentAsString());
+ }
+
+ @Test // SPR-14368
+ public void getResourceWithMediaTypeResolvedThroughServletContext() throws Exception {
+ MockServletContext servletContext = new MockServletContext() {
+
+ @Override
+ public String getMimeType(String filePath) {
+ return "foo/bar";
+ }
+
+ @Override
+ public String getVirtualServerName() {
+ return null;
+ }
+ };
+
+ List<Resource> paths = Collections.singletonList(new ClassPathResource("test/", getClass()));
+ this.handler = new ResourceHttpRequestHandler();
+ this.handler.setServletContext(servletContext);
+ this.handler.setLocations(paths);
+ this.handler.afterPropertiesSet();
+
+ this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
+ this.handler.handleRequest(this.request, this.response);
+
+ assertEquals("foo/bar", this.response.getContentType());
+ assertEquals("h1 { color:red; }", this.response.getContentAsString());
+ }
+
@Test
public void invalidPath() throws Exception {
+ for (HttpMethod method : HttpMethod.values()) {
+ this.request = new MockHttpServletRequest("GET", "");
+ this.response = new MockHttpServletResponse();
+ testInvalidPath(method);
+ }
+ }
+
+ private void testInvalidPath(HttpMethod httpMethod) throws Exception {
+ this.request.setMethod(httpMethod.name());
Resource location = new ClassPathResource("test/", getClass());
- this.handler.setLocations(Arrays.asList(location));
+ this.handler.setLocations(Collections.singletonList(location));
testInvalidPath(location, "../testsecret/secret.txt");
testInvalidPath(location, "test/../../testsecret/secret.txt");
testInvalidPath(location, ":/../../testsecret/secret.txt");
location = new UrlResource(getClass().getResource("./test/"));
- this.handler.setLocations(Arrays.asList(location));
+ this.handler.setLocations(Collections.singletonList(location));
Resource secretResource = new UrlResource(getClass().getResource("testsecret/secret.txt"));
String secretPath = secretResource.getURL().getPath();
@@ -230,7 +351,7 @@ public class ResourceHttpRequestHandlerTests {
if (!location.createRelative(requestPath).exists() && !requestPath.contains(":")) {
fail(requestPath + " doesn't actually exist as a relative path");
}
- assertEquals(404, this.response.getStatus());
+ assertEquals(HttpStatus.NOT_FOUND.value(), this.response.getStatus());
}
@Test
@@ -290,7 +411,7 @@ public class ResourceHttpRequestHandlerTests {
pathResolver.setAllowedLocations(location1);
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
- handler.setResourceResolvers(Arrays.asList(pathResolver));
+ handler.setResourceResolvers(Collections.singletonList(pathResolver));
handler.setLocations(Arrays.asList(location1, location2));
handler.afterPropertiesSet();
@@ -352,9 +473,18 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void resourceNotFound() throws Exception {
+ for (HttpMethod method : HttpMethod.values()) {
+ this.request = new MockHttpServletRequest("GET", "");
+ this.response = new MockHttpServletResponse();
+ resourceNotFound(method);
+ }
+ }
+
+ private void resourceNotFound(HttpMethod httpMethod) throws Exception {
+ this.request.setMethod(httpMethod.name());
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "not-there.css");
this.handler.handleRequest(this.request, this.response);
- assertEquals(404, this.response.getStatus());
+ assertEquals(HttpStatus.NOT_FOUND.value(), this.response.getStatus());
}
@Test
@@ -368,6 +498,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals(2, this.response.getContentLength());
assertEquals("bytes 0-1/10", this.response.getHeader("Content-Range"));
assertEquals("So", this.response.getContentAsString());
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -381,6 +513,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals(1, this.response.getContentLength());
assertEquals("bytes 9-9/10", this.response.getHeader("Content-Range"));
assertEquals(".", this.response.getContentAsString());
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -394,6 +528,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals(1, this.response.getContentLength());
assertEquals("bytes 9-9/10", this.response.getHeader("Content-Range"));
assertEquals(".", this.response.getContentAsString());
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -407,6 +543,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals(1, this.response.getContentLength());
assertEquals("bytes 9-9/10", this.response.getHeader("Content-Range"));
assertEquals(".", this.response.getContentAsString());
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -420,6 +558,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals(10, this.response.getContentLength());
assertEquals("bytes 0-9/10", this.response.getHeader("Content-Range"));
assertEquals("Some text.", this.response.getContentAsString());
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -430,6 +570,8 @@ public class ResourceHttpRequestHandlerTests {
assertEquals(416, this.response.getStatus());
assertEquals("bytes */10", this.response.getHeader("Content-Range"));
+ assertEquals("bytes", this.response.getHeader("Accept-Ranges"));
+ assertEquals(1, this.response.getHeaders("Accept-Ranges").size());
}
@Test
@@ -462,47 +604,6 @@ 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());
- }
-
- // SPR-13620
- @Test
- public void writeContentInputStreamThrowingNullPointerException() throws Exception {
- Resource resource = mock(Resource.class);
- InputStream in = mock(InputStream.class);
- given(resource.getInputStream()).willReturn(in);
- given(in.read(any())).willThrow(NullPointerException.class);
-
- this.handler.writeContent(this.response, resource);
-
- assertEquals(200, this.response.getStatus());
- assertEquals(0, this.response.getContentLength());
- }
-
// SPR-14005
@Test
public void doOverwriteExistingCacheControlHeaders() throws Exception {