diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ContentResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ContentResource.java index 06acec1409..4108a7634f 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ContentResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ContentResource.java @@ -16,7 +16,9 @@ import javax.ws.rs.GET; import javax.ws.rs.HEAD; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.StreamingOutput; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -41,8 +43,10 @@ public class ContentResource { StreamingOutput stream = os -> { try { repositoryService.getCatCommand().setRevision(revision).retriveContent(os, path); + } catch (PathNotFoundException e) { + throw new WebApplicationException(Status.NOT_FOUND); } catch (RepositoryException e) { - e.printStackTrace(); + throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR); } os.close(); }; @@ -52,16 +56,16 @@ public class ContentResource { return responseBuilder.build(); } catch (PathNotFoundException e) { - return Response.status(404).build(); + return Response.status(Status.NOT_FOUND).build(); } catch (IOException e) { LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e); - return Response.status(500).entity(e.getMessage()).build(); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } catch (RepositoryException e) { LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e); - return Response.status(500).entity(e.getMessage()).build(); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } } catch (RepositoryNotFoundException e) { - return Response.status(404).build(); + return Response.status(Status.NOT_FOUND).build(); } } @@ -76,16 +80,16 @@ public class ContentResource { appendContentType(path, getHead(revision, path, repositoryService), responseBuilder); return responseBuilder.build(); } catch (PathNotFoundException e) { - return Response.status(404).build(); + return Response.status(Status.NOT_FOUND).build(); } catch (IOException e) { LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e); - return Response.status(500).entity(e.getMessage()).build(); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } catch (RepositoryException e) { LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e); - return Response.status(500).entity(e.getMessage()).build(); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } } catch (RepositoryNotFoundException e) { - return Response.status(404).build(); + return Response.status(Status.NOT_FOUND).build(); } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ContentResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ContentResourceTest.java index b2434905e7..23544e8cf6 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ContentResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ContentResourceTest.java @@ -18,6 +18,7 @@ import sonia.scm.repository.api.RepositoryServiceFactory; import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.OutputStream; import java.net.URL; @@ -64,8 +65,7 @@ public class ContentResourceTest { Response response = contentResource.get(NAMESPACE, REPO_NAME, REV, "file"); assertEquals(200, response.getStatus()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ((StreamingOutput) response.getEntity()).write(baos); + ByteArrayOutputStream baos = readOutputStream(response); assertEquals("Hello", baos.toString()); } @@ -115,6 +115,15 @@ public class ContentResourceTest { assertEquals("application/octet-stream", response.getHeaderString("Content-Type")); } + @Test + public void shouldHandleExceptionsInStreamProcessing() throws Exception { + Response response = contentResource.get(NAMESPACE, REPO_NAME, REV, "MissingFile"); + + ByteArrayOutputStream baos = readOutputStream(response); + + assertEquals(404, response.getStatus()); + } + private void mockContentFromResource(String fileName) throws Exception { URL url = Resources.getResource(fileName); mockContent(fileName, Resources.toByteArray(url)); @@ -128,4 +137,10 @@ public class ContentResourceTest { return null; }).when(catCommand).retriveContent(any(), eq(path)); } + + private ByteArrayOutputStream readOutputStream(Response response) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ((StreamingOutput) response.getEntity()).write(baos); + return baos; + } }