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 014b9b90ef..4182fb9343 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 @@ -10,6 +10,7 @@ import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryNotFoundException; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; +import sonia.scm.util.IOUtil; import javax.inject.Inject; import javax.ws.rs.GET; @@ -20,12 +21,14 @@ 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; +import java.io.InputStream; +import java.util.Arrays; public class ContentResource { private static final Logger LOG = LoggerFactory.getLogger(ContentResource.class); + private static final int HEAD_BUFFER_SIZE = 1024; private final RepositoryServiceFactory serviceFactory; @@ -98,8 +101,17 @@ public class ContentResource { } private byte[] getHead(String revision, String path, RepositoryService repositoryService) throws IOException, RepositoryException { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - repositoryService.getCatCommand().setRevision(revision).retriveContent(outputStream, path); - return outputStream.toByteArray(); + InputStream stream = repositoryService.getCatCommand().setRevision(revision).getStream(path); + try { + byte[] buffer = new byte[HEAD_BUFFER_SIZE]; + int length = stream.read(buffer); + if (length < buffer.length) { + return Arrays.copyOf(buffer, length); + } else { + return buffer; + } + } finally { + IOUtil.close(stream); + } } } 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 3c926f7986..36f6c92c47 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 @@ -17,6 +17,7 @@ import sonia.scm.repository.api.RepositoryServiceFactory; import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -55,7 +56,7 @@ public class ContentResourceTest { // defaults for unknown things doThrow(new RepositoryNotFoundException("x")).when(repositoryServiceFactory).create(not(eq(existingNamespaceAndName))); - doThrow(new PathNotFoundException("x")).when(catCommand).retriveContent(any(), any()); + doThrow(new PathNotFoundException("x")).when(catCommand).getStream(any()); } @Test @@ -104,6 +105,17 @@ public class ContentResourceTest { assertEquals("text/plain", response.getHeaderString("Content-Type")); } + @Test + public void shouldRecognizeShebangSourceCode() throws Exception { + mockContentFromResource("someScript.sh"); + + Response response = contentResource.get(NAMESPACE, REPO_NAME, REV, "someScript.sh"); + assertEquals(200, response.getStatus()); + + assertEquals("PYTHON", response.getHeaderString("Language")); + assertEquals("application/x-sh", response.getHeaderString("Content-Type")); + } + @Test public void shouldHandleRandomByteFile() throws Exception { mockContentFromResource("JustBytes"); @@ -127,6 +139,7 @@ public class ContentResourceTest { outputStream.close(); return null; }).when(catCommand).retriveContent(any(), eq(path)); + doAnswer(invocation -> new ByteArrayInputStream(content)).when(catCommand).getStream(eq(path)); } private ByteArrayOutputStream readOutputStream(Response response) throws IOException { diff --git a/scm-webapp/src/test/resources/someScript.sh b/scm-webapp/src/test/resources/someScript.sh new file mode 100644 index 0000000000..0bcecb189d --- /dev/null +++ b/scm-webapp/src/test/resources/someScript.sh @@ -0,0 +1,6 @@ +#!/usr/bin/python + +for f in * ; do + ls $f +done +