From c96bfdba72f8da8f52bc76f0a134152655790dad Mon Sep 17 00:00:00 2001 From: Torben Barsballe Date: Fri, 31 Mar 2017 12:37:18 +0200 Subject: [PATCH] Handle resource content GET --- .../org/geoserver/rest/MVCConfiguration.java | 1 + .../rest/converters/InputStreamConverter.java | 45 +++++++++++++++++++ .../rest/resources/ResourceController.java | 20 ++++----- .../resources/ResourceControllerTest.java | 33 ++++++++++++++ 4 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/rest-ng/src/main/java/org/geoserver/rest/converters/InputStreamConverter.java diff --git a/src/rest-ng/src/main/java/org/geoserver/rest/MVCConfiguration.java b/src/rest-ng/src/main/java/org/geoserver/rest/MVCConfiguration.java index 63db60fac77..3a175f7d924 100644 --- a/src/rest-ng/src/main/java/org/geoserver/rest/MVCConfiguration.java +++ b/src/rest-ng/src/main/java/org/geoserver/rest/MVCConfiguration.java @@ -72,6 +72,7 @@ protected void configureMessageConverters(List> converte gsConverters.add(new XStreamJSONMessageConverter()); gsConverters.add(new XStreamCatalogListConverter.XMLXStreamListConverter()); gsConverters.add(new XStreamCatalogListConverter.JSONXStreamListConverter()); + gsConverters.add(new InputStreamConverter()); //Deal with the various Style handler EntityResolver entityResolver = catalog.getResourcePool().getEntityResolver(); diff --git a/src/rest-ng/src/main/java/org/geoserver/rest/converters/InputStreamConverter.java b/src/rest-ng/src/main/java/org/geoserver/rest/converters/InputStreamConverter.java new file mode 100644 index 00000000000..b4b63c45720 --- /dev/null +++ b/src/rest-ng/src/main/java/org/geoserver/rest/converters/InputStreamConverter.java @@ -0,0 +1,45 @@ +package org.geoserver.rest.converters; + +import org.apache.commons.io.IOUtils; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.List; + +/** + * Created by tbarsballe on 2017-03-31. + */ +public class InputStreamConverter extends BaseMessageConverter { + @Override + public boolean canRead(Class clazz, MediaType mediaType) { + return false; + } + + @Override + public boolean canWrite(Class clazz, MediaType mediaType) { + return InputStream.class.isAssignableFrom(clazz); + } + + @Override + public List getSupportedMediaTypes() { + return Arrays.asList(MediaType.ALL); + } + + @Override + public Object read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { + throw new UnsupportedOperationException(); + } + + @Override + public void write(Object o, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { + IOUtils.copy((InputStream)o,outputMessage.getBody()); + ((InputStream) o).close(); + } +} diff --git a/src/restconfig-ng/src/main/java/org/geoserver/rest/resources/ResourceController.java b/src/restconfig-ng/src/main/java/org/geoserver/rest/resources/ResourceController.java index a52065bd115..e12b952d1d7 100644 --- a/src/restconfig-ng/src/main/java/org/geoserver/rest/resources/ResourceController.java +++ b/src/restconfig-ng/src/main/java/org/geoserver/rest/resources/ResourceController.java @@ -63,7 +63,7 @@ import freemarker.template.ObjectWrapper; @RestController -@RequestMapping(path = {ROOT_PATH + "/resource", ROOT_PATH + "/resource/**"}, produces="*") +@RequestMapping(path = {ROOT_PATH + "/resource", ROOT_PATH + "/resource/**"}) public class ResourceController extends RestBaseController { private ResourceStore resources; static Logger LOGGER = Logging.getLogger("org.geoserver.catalog.rest"); @@ -176,8 +176,8 @@ protected static String formatHtmlLink(String link) { * @param response Response provided allowing us to set headers (content type, content length, Resource-Parent, Resource-Type). * @return Returns wrapped info object, or direct access to resource contents depending on requested operation */ - @RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD}) - public Object resourceGet(HttpServletRequest request, HttpServletResponse response) { + @RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD}, produces = {MediaType.ALL_VALUE}) + public Object get(HttpServletRequest request, HttpServletResponse response) { Resource resource = resource(request); Operation operation = operation(request); Object result; @@ -189,16 +189,16 @@ public Object resourceGet(HttpServletRequest request, HttpServletResponse respon if (resource.getType() == Resource.Type.UNDEFINED) { throw new ResourceNotFoundException("Undefined resource path."); } else { + HttpHeaders responseHeaders = new HttpHeaders(); + MediaType mediaType = getMediaType(resource, request); + responseHeaders.setContentType(mediaType); + response.setContentType(mediaType.toString()); + if (request.getMethod().equals("HEAD")) { - result = wrapObject("", String.class); + result = new ResponseEntity("", responseHeaders, HttpStatus.OK); } else if (resource.getType() == Resource.Type.DIRECTORY) { result = wrapObject(new ResourceDirectoryInfo(resource, request), ResourceDirectoryInfo.class); } else { - HttpHeaders responseHeaders = new HttpHeaders(); - MediaType mediaType = getMediaType(resource, request); - responseHeaders.setContentType(mediaType); - response.setContentType(mediaType.toString()); - result = new ResponseEntity(resource.in(), responseHeaders, HttpStatus.OK); } response.setHeader("Location", href(resource.path())); @@ -242,7 +242,7 @@ public void resourceDelete(HttpServletRequest request){ } /** - * Verifies mime type and use {@link RESTUtil + * Verifies mime type and use {@link RESTUtils} * @param directory * @param filename * @param request diff --git a/src/restconfig-ng/src/test/java/org/geoserver/rest/resources/ResourceControllerTest.java b/src/restconfig-ng/src/test/java/org/geoserver/rest/resources/ResourceControllerTest.java index 4e80369f9e5..7e39c20c5cb 100644 --- a/src/restconfig-ng/src/test/java/org/geoserver/rest/resources/ResourceControllerTest.java +++ b/src/restconfig-ng/src/test/java/org/geoserver/rest/resources/ResourceControllerTest.java @@ -21,6 +21,7 @@ import org.junit.Assume; import org.junit.Before; import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.w3c.dom.Document; @@ -155,6 +156,18 @@ public void testResourceHeaders() throws Exception { assertContentType("image/png", response); } + @Test + public void testResourceHead() throws Exception { + MockHttpServletResponse response = headAsServletResponse(RestBaseController.ROOT_PATH+"/resource/mydir2/fake.png"); + Assert.assertEquals( + FORMAT_HEADER.format(getDataDirectory().get("/mydir2/fake.png").lastmodified()), + response.getHeader("Last-Modified")); + Assert.assertEquals("http://localhost:8080/geoserver"+RestBaseController.ROOT_PATH+"/resource/mydir2", + response.getHeader("Resource-Parent")); + Assert.assertEquals("resource", response.getHeader("Resource-Type")); + assertContentType("image/png", response); + } + @Test public void testSpecialCharacterNames() throws Exception { // if the file system encoded the file with a ? we need to skip this test @@ -239,6 +252,17 @@ public void testDirectoryHeaders() throws Exception { Assert.assertEquals("directory", response.getHeader("Resource-Type")); assertContentType("application/xml", response); } + + @Test + public void testDirectoryHead() throws Exception { + MockHttpServletResponse response = headAsServletResponse(RestBaseController.ROOT_PATH+"/resource/mydir?format=xml"); + Assert.assertEquals(FORMAT_HEADER.format(myRes.parent().lastmodified()), + response.getHeader("Last-Modified")); + Assert.assertEquals("http://localhost:8080/geoserver"+RestBaseController.ROOT_PATH+"/resource/", + response.getHeader("Resource-Parent")); + Assert.assertEquals("directory", response.getHeader("Resource-Type")); + assertContentType("application/xml", response); + } @Test public void testDirectoryMimeTypes() throws Exception { @@ -348,4 +372,13 @@ public void testErrorResponseCodes() throws Exception { } + //TODO: Migrate this (properly) to GeoServerSystemTestSupport) + public MockHttpServletResponse headAsServletResponse(String path) throws Exception { + MockHttpServletRequest request = createRequest( path ); + request.setMethod( "HEAD" ); + request.setContent(new byte[]{}); + + return dispatch( request, null ); + } + }