Skip to content

Commit c17bede

Browse files
committed
Implement InputStream based FileUpload creation
This commit adds in suppor for calling FileUpload.create(Map<String, Object>) with the parameter "file" set to an InputStream, instead of only allowing Files. You can see an example of this in src/test/java/com/stripe/functional/FileUploadTest.java. Furthermore, this commit changes the addFileField method to no longer accept a file argument, and only allows for InputStream arguments in addition to a string containing the name of the file to upload.
1 parent cc48c6b commit c17bede

File tree

3 files changed

+55
-16
lines changed

3 files changed

+55
-16
lines changed

Diff for: src/main/java/com/stripe/net/LiveStripeResponseGetter.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.stripe.model.StripeObject;
1818

1919
import java.io.File;
20+
import java.io.FileInputStream;
2021
import java.io.IOException;
2122
import java.io.InputStream;
2223
import java.io.OutputStream;
@@ -642,7 +643,16 @@ private static StripeResponse getMultipartStripeResponse(
642643
"Must have read permissions on file for key "
643644
+ key + ".", null, null, null, 0, null);
644645
}
645-
multipartProcessor.addFileField(key, currentFile);
646+
multipartProcessor.addFileField(key, currentFile.getName(), new FileInputStream(currentFile));
647+
} else if (value instanceof InputStream) {
648+
InputStream inputStream = (InputStream) value;
649+
if (inputStream.available() == 0) {
650+
throw new InvalidRequestException(
651+
"Must have available bytes to read on InputStream for key "
652+
+ key + ".", null, null, null, 0, null
653+
);
654+
}
655+
multipartProcessor.addFileField(key, "blob", inputStream);
646656
} else {
647657
// We only allow a single level of nesting for params
648658
// for multipart

Diff for: src/main/java/com/stripe/net/MultipartProcessor.java

+25-15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.File;
44
import java.io.FileInputStream;
55
import java.io.IOException;
6+
import java.io.InputStream;
67
import java.io.OutputStream;
78
import java.io.OutputStreamWriter;
89
import java.io.PrintWriter;
@@ -53,26 +54,38 @@ public void addFormField(String name, String value) {
5354
}
5455

5556
/**
56-
* Adds a file field to the multipart message.
57+
* Adds a file field to the multipart message, but takes in an InputStream instead of
58+
* just a file to read bytes from.
5759
*
58-
* @param name field name
59-
* @param file File instance
60+
* @param name Field name
61+
* @param fileName Name of the "file" being uploaded.
62+
* @param inputStream Stream of bytes to use in place of a file.
63+
* @throws IOException Thrown when writing / reading from streams fails.
6064
*/
61-
public void addFileField(String name, File file) throws IOException {
62-
String fileName = file.getName();
63-
writer.append("--" + boundary).append(LINE_BREAK);
64-
writer.append(
65-
"Content-Disposition: form-data; name=\"" + name
66-
+ "\"; filename=\"" + fileName + "\"").append(
67-
LINE_BREAK);
65+
public void addFileField(String name, String fileName, InputStream inputStream)
66+
throws IOException {
67+
writer.append("--").append(boundary).append(LINE_BREAK);
68+
writer.append("Content-Disposition: form-data; name=\"").append(name)
69+
.append("\"; filename=\"").append(fileName).append("\"").append(LINE_BREAK);
6870

6971
String probableContentType = URLConnection.guessContentTypeFromName(fileName);
70-
writer.append("Content-Type: " + probableContentType).append(LINE_BREAK);
72+
writer.append("Content-Type: ").append(probableContentType).append(LINE_BREAK);
7173
writer.append("Content-Transfer-Encoding: binary").append(LINE_BREAK);
7274
writer.append(LINE_BREAK);
7375
writer.flush();
7476

75-
FileInputStream inputStream = new FileInputStream(file);
77+
streamToOutput(inputStream);
78+
79+
writer.append(LINE_BREAK);
80+
writer.flush();
81+
}
82+
83+
/**
84+
* Utility method to read all the bytes from an InputStream into the outputStream.
85+
* @param inputStream Stream of bytes to read from.
86+
* @throws IOException Thrown on errors reading / writing.
87+
*/
88+
private void streamToOutput(InputStream inputStream) throws IOException {
7689
try {
7790
byte[] buffer = new byte[4096];
7891
int bytesRead = -1;
@@ -83,9 +96,6 @@ public void addFileField(String name, File file) throws IOException {
8396
} finally {
8497
inputStream.close();
8598
}
86-
87-
writer.append(LINE_BREAK);
88-
writer.flush();
8999
}
90100

91101
/**

Diff for: src/test/java/com/stripe/functional/FileUploadTest.java

+19
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.stripe.net.APIResource;
1010

1111
import java.io.File;
12+
import java.io.FileInputStream;
1213
import java.io.IOException;
1314
import java.util.HashMap;
1415
import java.util.Map;
@@ -36,6 +37,24 @@ public void testCreate() throws IOException, StripeException {
3637
);
3738
}
3839

40+
@Test
41+
public void testStreamCreate() throws IOException, StripeException {
42+
final Map<String, Object> params = new HashMap<>();
43+
params.put("purpose", "dispute_evidence");
44+
params.put("file", new FileInputStream(getClass().getResource("/test.png").getFile()));
45+
46+
final FileUpload fileUpload = FileUpload.create(params);
47+
48+
assertNotNull(fileUpload);
49+
verifyRequest(
50+
APIResource.RequestMethod.POST,
51+
"/v1/files",
52+
params,
53+
APIResource.RequestType.MULTIPART,
54+
null
55+
);
56+
}
57+
3958
@Test
4059
public void testRetrieve() throws IOException, StripeException {
4160
final FileUpload fileUpload = FileUpload.retrieve(FILE_UPLOAD_ID);

0 commit comments

Comments
 (0)