Skip to content

Commit 69595d2

Browse files
committed
Fix MultipartUtility - Verify inner stream is closed if an exception is thrown somewhere along the way.
1 parent 2e96f05 commit 69595d2

File tree

2 files changed

+42
-41
lines changed

2 files changed

+42
-41
lines changed

cloudinary-android/src/main/java/com/cloudinary/android/MultipartUtility.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,9 @@ public HttpURLConnection execute() throws IOException {
136136
return httpConn;
137137
}
138138

139+
public void close(){
140+
if (writer != null){
141+
writer.close();
142+
}
143+
}
139144
}

cloudinary-android/src/main/java/com/cloudinary/android/UploaderStrategy.java

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.io.File;
66
import java.io.IOException;
77
import java.io.InputStream;
8-
import java.io.OutputStream;
98
import java.net.HttpURLConnection;
109
import java.util.Collection;
1110
import java.util.Map;
@@ -48,66 +47,63 @@ public Map callApi(String action, Map<String, Object> params, Map options, Objec
4847
}
4948
}
5049
String apiUrl = this.cloudinary().cloudinaryApiUrl(action, options);
51-
MultipartUtility multipart = new MultipartUtility(apiUrl, "UTF-8", this.cloudinary().randomPublicId(), (Map<String, String>) options.get("extra_headers"));
5250

53-
// Remove blank parameters
54-
for (Map.Entry<String, Object> param : params.entrySet()) {
55-
if (param.getValue() instanceof Collection) {
56-
for (Object value : (Collection) param.getValue()) {
57-
multipart.addFormField(param.getKey() + "[]", ObjectUtils.asString(value));
58-
}
59-
} else {
60-
if (StringUtils.isNotBlank(param.getValue())) {
61-
multipart.addFormField(param.getKey(), param.getValue().toString());
51+
MultipartUtility multipart = null;
52+
HttpURLConnection connection;
53+
54+
try {
55+
multipart = new MultipartUtility(apiUrl, "UTF-8", this.cloudinary().randomPublicId(), (Map<String, String>) options.get("extra_headers"));
56+
57+
// Remove blank parameters
58+
for (Map.Entry<String, Object> param : params.entrySet()) {
59+
if (param.getValue() instanceof Collection) {
60+
for (Object value : (Collection) param.getValue()) {
61+
multipart.addFormField(param.getKey() + "[]", ObjectUtils.asString(value));
62+
}
63+
} else {
64+
if (StringUtils.isNotBlank(param.getValue())) {
65+
multipart.addFormField(param.getKey(), param.getValue().toString());
66+
}
6267
}
6368
}
64-
}
6569

66-
if (file instanceof String && !((String) file).matches("(?s)ftp:.*|https?:.*|s3:.*|data:[^;]*;base64,([a-zA-Z0-9/+\n=]+)")) {
67-
file = new File((String) file);
68-
}
69-
String filename = (String) options.get("filename");
70-
if (file instanceof File) {
71-
multipart.addFilePart("file", (File) file, filename);
72-
} else if (file instanceof String) {
73-
multipart.addFormField("file", (String) file);
74-
} else if (file instanceof InputStream) {
75-
multipart.addFilePart("file", (InputStream) file, filename);
76-
} else if (file instanceof byte[]) {
77-
multipart.addFilePart("file", new ByteArrayInputStream((byte[]) file), filename);
70+
if (file instanceof String && !((String) file).matches("(?s)ftp:.*|https?:.*|s3:.*|data:[^;]*;base64,([a-zA-Z0-9/+\n=]+)")) {
71+
file = new File((String) file);
72+
}
73+
String filename = (String) options.get("filename");
74+
if (file instanceof File) {
75+
multipart.addFilePart("file", (File) file, filename);
76+
} else if (file instanceof String) {
77+
multipart.addFormField("file", (String) file);
78+
} else if (file instanceof InputStream) {
79+
multipart.addFilePart("file", (InputStream) file, filename);
80+
} else if (file instanceof byte[]) {
81+
multipart.addFilePart("file", new ByteArrayInputStream((byte[]) file), filename);
82+
}
83+
84+
connection = multipart.execute();
85+
} finally {
86+
if (multipart != null){
87+
// Closing more than once has no effect so we can call it safely without having to check state
88+
multipart.close();
89+
}
7890
}
7991

80-
HttpURLConnection connection = multipart.execute();
8192
int code;
82-
83-
OutputStream outputStream = null;
84-
8593
try {
8694
code = connection.getResponseCode();
87-
outputStream = connection.getOutputStream();
88-
} catch (Exception e) {
95+
} catch (IOException e) {
8996
if (e.getMessage().equals("No authentication challenges found")) {
9097
// Android trying to be clever...
9198
code = 401;
9299
} else {
93100
throw e;
94101
}
95-
} finally {
96-
if (outputStream != null) {
97-
try {
98-
outputStream.close();
99-
} catch (Exception e) {}
100-
}
101102
}
102-
103103
InputStream responseStream = code >= 400 ? connection.getErrorStream() : connection.getInputStream();
104104
String responseData = readFully(responseStream);
105105
connection.disconnect();
106106

107-
try {
108-
responseStream.close();
109-
} catch (Exception e) {}
110-
111107
if (code != 200 && code != 400 && code != 404 && code != 500) {
112108
throw new RuntimeException("Server returned unexpected status code - " + code + " - " + responseData);
113109
}

0 commit comments

Comments
 (0)