Skip to content

Commit 4c5099e

Browse files
committed
The method createNewFile converts all the inputstream to memory. This could cause out of memory errors.
Now the process use a buffer to avoid this. Issue: 205339
1 parent 3e496be commit 4c5099e

File tree

2 files changed

+54
-19
lines changed

2 files changed

+54
-19
lines changed

gxcloudstorage-awss3/src/main/java/com/genexus/db/driver/ExternalProviderS3.java

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import com.amazonaws.services.s3.AmazonS3;
1919
import com.amazonaws.services.s3.AmazonS3Client;
20-
import com.amazonaws.util.IOUtils;
2120

2221
import java.io.FileNotFoundException;
2322
import java.io.FileOutputStream;
@@ -209,26 +208,34 @@ else if (acl == ResourceAccessControlList.PublicReadWrite) {
209208
return accessControl;
210209
}
211210

212-
public String upload(String externalFileName, InputStream input, ResourceAccessControlList acl) {
213-
byte[] bytes;
214-
try {
215-
bytes = IOUtils.toByteArray(input);
216-
ObjectMetadata metadata = new ObjectMetadata();
217-
metadata.setContentLength(bytes.length);
218-
if (externalFileName.endsWith(".tmp")) {
219-
metadata.setContentType("image/jpeg");
220-
}
221-
String upload = "";
222-
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes)) {
223-
client.putObject(new PutObjectRequest(bucket, externalFileName, byteArrayInputStream, metadata).withCannedAcl(internalToAWSACL(acl)));
224-
upload = getResourceUrl(externalFileName, acl, defaultExpirationMinutes);
211+
public String upload(String externalFileName, InputStream input, ResourceAccessControlList acl) {
212+
ExternalProviderHelper.InputStreamWithLength streamInfo = null;
213+
try {
214+
streamInfo = ExternalProviderHelper.getInputStreamContentLength(input);
215+
216+
ObjectMetadata metadata = new ObjectMetadata();
217+
metadata.setContentLength(streamInfo.contentLength);
218+
219+
if (externalFileName.endsWith(".tmp")) {
220+
metadata.setContentType("image/jpeg");
225221
}
222+
String upload = "";
223+
client.putObject(new PutObjectRequest(bucket, externalFileName, streamInfo.inputStream, metadata).withCannedAcl(internalToAWSACL(acl)));
224+
upload = getResourceUrl(externalFileName, acl, defaultExpirationMinutes);
226225
return upload;
227-
} catch (IOException ex) {
228-
logger.error("Error while uploading file to the external provider.", ex);
229-
return "";
230-
}
231-
}
226+
} catch (IOException ex) {
227+
logger.error("Error while uploading file to the external provider.", ex);
228+
return "";
229+
} finally {
230+
if (streamInfo != null && streamInfo.tempFile != null && streamInfo.tempFile.exists()) {
231+
try {
232+
streamInfo.tempFile.delete();
233+
} catch (Exception e) {
234+
logger.warn("Could not delete temporary file: " + streamInfo.tempFile.getAbsolutePath(), e);
235+
}
236+
}
237+
}
238+
}
232239

233240
public String get(String externalFileName, ResourceAccessControlList acl, int expirationMinutes) {
234241
client.getObjectMetadata(bucket, externalFileName);

gxcloudstorage-common/src/main/java/com/genexus/db/driver/ExternalProviderHelper.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.genexus.util.Encryption;
44
import com.genexus.util.GXService;
55

6+
import java.io.*;
7+
68
public class ExternalProviderHelper {
79

810
public static String getServicePropertyValue(GXService s, String propName, boolean isSecure){
@@ -23,4 +25,30 @@ public static String getEnvironmentVariable(String name, boolean required) throw
2325
}
2426
return value;
2527
}
28+
29+
public static InputStreamWithLength getInputStreamContentLength(InputStream input) throws IOException {
30+
File tempFile = File.createTempFile("upload-", ".tmp");
31+
try (OutputStream out = new FileOutputStream(tempFile)) {
32+
byte[] buffer = new byte[8192];
33+
int bytesRead;
34+
while ((bytesRead = input.read(buffer)) != -1) {
35+
out.write(buffer, 0, bytesRead);
36+
}
37+
}
38+
long size = tempFile.length();
39+
InputStream newInput = new FileInputStream(tempFile);
40+
return new InputStreamWithLength(newInput, size, tempFile);
41+
}
42+
43+
public static class InputStreamWithLength {
44+
public final InputStream inputStream;
45+
public final long contentLength;
46+
public final File tempFile; // nullable
47+
48+
public InputStreamWithLength(InputStream inputStream, long contentLength, File tempFile) {
49+
this.inputStream = inputStream;
50+
this.contentLength = contentLength;
51+
this.tempFile = tempFile;
52+
}
53+
}
2654
}

0 commit comments

Comments
 (0)