From 059f25640628072fa3d4756ef5c8a88dc81be152 Mon Sep 17 00:00:00 2001 From: Cristian Turlica Date: Thu, 23 Jan 2020 13:40:57 +0200 Subject: [PATCH] MNT-21250: The fix for MNT-20734 introduces a problem whereby files larger than 4MB cannot be downloaded (#516) - fixed temp file handling issue --- .../repo/web/scripts/BufferedResponse.java | 13 ++++- .../framework/webscripts/ApiWebScript.java | 2 - .../alfresco/rest/api/tests/NodeApiTest.java | 57 +++++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/alfresco/repo/web/scripts/BufferedResponse.java b/src/main/java/org/alfresco/repo/web/scripts/BufferedResponse.java index 6b32bf3411..f5811b01ad 100644 --- a/src/main/java/org/alfresco/repo/web/scripts/BufferedResponse.java +++ b/src/main/java/org/alfresco/repo/web/scripts/BufferedResponse.java @@ -261,9 +261,16 @@ public class BufferedResponse implements WrappingWebScriptResponse { if (logger.isDebugEnabled()) logger.debug("Writing Transactional response: size=" + outputStream.getLength()); - - outputStream.flush(); - FileCopyUtils.copy(outputStream.getInputStream(), res.getOutputStream()); + + try + { + outputStream.flush(); + FileCopyUtils.copy(outputStream.getInputStream(), res.getOutputStream()); + } + finally + { + outputStream.destroy(); + } } } catch (IOException e) diff --git a/src/main/java/org/alfresco/rest/framework/webscripts/ApiWebScript.java b/src/main/java/org/alfresco/rest/framework/webscripts/ApiWebScript.java index a9fa4eea83..c848eb05e7 100644 --- a/src/main/java/org/alfresco/rest/framework/webscripts/ApiWebScript.java +++ b/src/main/java/org/alfresco/rest/framework/webscripts/ApiWebScript.java @@ -57,7 +57,6 @@ public abstract class ApiWebScript extends AbstractWebScript protected int memoryThreshold = 4 * 1024 * 1024; // 4mb protected long maxContentSize = (long) 4 * 1024 * 1024 * 1024; // 4gb protected TempOutputStreamFactory streamFactory = null; - protected TempOutputStreamFactory responseStreamFactory = null; protected TransactionService transactionService; public void setTransactionService(TransactionService transactionService) @@ -98,7 +97,6 @@ public abstract class ApiWebScript extends AbstractWebScript { File tempDirectory = TempFileProvider.getTempDir(tempDirectoryName); this.streamFactory = new TempOutputStreamFactory(tempDirectory, memoryThreshold, maxContentSize, false, false); - this.responseStreamFactory = new TempOutputStreamFactory(tempDirectory, memoryThreshold, maxContentSize, false, true); } @Override diff --git a/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java b/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java index 0d8bbaa0d3..6e14d98b0c 100644 --- a/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java +++ b/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java @@ -2856,6 +2856,12 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest documentResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class); assertTrue("File size is 0 bytes", documentResp.getContent().getSizeInBytes().intValue() > 0); + + // Download text content - by default with Content-Disposition header + response = getSingle(NodesEntityResource.class, docId + "/content", null, 200); + + byte[] bytes = response.getResponseAsBytes(); + assertEquals(contentSize.intValue(), bytes.length); } private class UpdateNodeRunnable implements Runnable @@ -3705,6 +3711,57 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest getSingle(getNodeContentUrl(contentNodeId), null, null, headers, 304); } + /** + * Tests download of file/content using backed temp file for streaming. + *

+ * GET: + *

+ * {@literal :/alfresco/api/-default-/public/alfresco/versions/1/nodes//content} + */ + @Test + public void testDownloadFileContentUsingTempFile() throws Exception + { + setRequestContext(user1); + + // This should be grater then TempOutputStream.DEFAULT_MEMORY_THRESHOLD + Long contentSize = 5 * 1024 * 1024L; + String fileName = "tempFile.txt"; + + File file = null; + try + { + file = TempFileProvider.createTempFile(getClass().getSimpleName(), ".txt"); + RandomAccessFile rndFile = new RandomAccessFile(file.getPath(), "rw"); + rndFile.setLength(contentSize); + rndFile.close(); + + MultiPartBuilder multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file)); + MultiPartRequest reqBody = multiPartBuilder.build(); + + // Upload text content + HttpResponse response = post(getNodeChildrenUrl(Nodes.PATH_MY), reqBody.getBody(), null, reqBody.getContentType(), 201); + Document document = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class); + + String contentNodeId = document.getId(); + + // Check the upload response + assertEquals(fileName, document.getName()); + ContentInfo contentInfo = document.getContent(); + assertNotNull(contentInfo); + assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, contentInfo.getMimeType()); + + // Download text content + response = getSingle(NodesEntityResource.class, contentNodeId + "/content", null, 200); + + byte[] bytes = response.getResponseAsBytes(); + assertEquals(contentSize.intValue(), bytes.length); + } + finally + { + file.delete(); + } + } + /** * Tests download of file/content - basic read permission *

GET: