Skip to content

Commit 2c21249

Browse files
SUPERCILEXchingor13
authored andcommitted
Close InputStream on error during resumable upload (#1324)
* Close streams on error * Add a test
1 parent 15f6916 commit 2c21249

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

google-api-client/src/main/java/com/google/api/client/googleapis/media/MediaHttpUploader.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,9 @@ private HttpResponse resumableUpload(GenericUrl initiationRequestUrl) throws IOE
434434
}
435435

436436
if (response.getStatusCode() != 308) {
437+
if (mediaContent.getCloseInputStream()) {
438+
contentInputStream.close();
439+
}
437440
returningResponse = true;
438441
return response;
439442
}

google-api-client/src/test/java/com/google/api/client/googleapis/media/MediaHttpUploaderTest.java

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ public void subtestUpload_ResumableWithError(ErrorType error, int contentLength,
763763
fakeTransport.force308OnRangeQueryResponse = force308OnRangeQueryResponse;
764764
byte[] testedData = new byte[contentLength];
765765
new Random().nextBytes(testedData);
766-
InputStream is = new ByteArrayInputStream(testedData);
766+
TestingInputStream is = new TestingInputStream(testedData);
767767
InputStreamContent mediaContent = new InputStreamContent(TEST_CONTENT_TYPE, is);
768768
if (contentLengthKnown) {
769769
mediaContent.setLength(contentLength);
@@ -782,6 +782,7 @@ public void subtestUpload_ResumableWithError(ErrorType error, int contentLength,
782782
assertEquals(calls, fakeTransport.lowLevelExecCalls);
783783

784784
assertTrue(Arrays.equals(testedData, fakeTransport.bytesReceived));
785+
assertTrue(is.isClosed);
785786
}
786787

787788
public void testUploadIOException_WithoutIOExceptionHandler() throws Exception {
@@ -1169,4 +1170,80 @@ public void testResumableSlowUpload() throws Exception {
11691170
uploader.setDirectUploadEnabled(false);
11701171
uploader.upload(new GenericUrl(TEST_RESUMABLE_REQUEST_URL));
11711172
}
1173+
1174+
1175+
static class ResumableErrorMediaTransport extends MockHttpTransport {
1176+
1177+
ResumableErrorMediaTransport() {}
1178+
1179+
@Override
1180+
public boolean supportsMethod(String method) throws IOException {
1181+
return true;
1182+
}
1183+
1184+
@Override
1185+
public LowLevelHttpRequest buildRequest(final String method, String url) {
1186+
// First request should be to the resumable request url
1187+
if (method.equals("POST")) {
1188+
assertEquals(TEST_RESUMABLE_REQUEST_URL, url);
1189+
1190+
return new MockLowLevelHttpRequest() {
1191+
@Override
1192+
public LowLevelHttpResponse execute() {
1193+
assertEquals(TEST_CONTENT_TYPE, getFirstHeaderValue("x-upload-content-type"));
1194+
1195+
// This is the initiation call.
1196+
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
1197+
// Return 200 with the upload URI.
1198+
response.setStatusCode(200);
1199+
response.addHeader("Location", TEST_UPLOAD_URL);
1200+
return response;
1201+
}
1202+
};
1203+
}
1204+
1205+
// Fake an error when uploading chunks
1206+
return new MockLowLevelHttpRequest() {
1207+
@Override
1208+
public LowLevelHttpResponse execute() throws IOException {
1209+
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
1210+
response.setStatusCode(500);
1211+
return response;
1212+
}
1213+
};
1214+
}
1215+
}
1216+
1217+
class TestingInputStream extends ByteArrayInputStream {
1218+
boolean isClosed;
1219+
1220+
TestingInputStream(byte[] testData) {
1221+
super(testData);
1222+
}
1223+
1224+
@Override
1225+
public void close() throws IOException {
1226+
isClosed = true;
1227+
super.close();
1228+
}
1229+
}
1230+
1231+
public void testResumable_BadResponse() throws IOException {
1232+
int contentLength = 3;
1233+
ResumableErrorMediaTransport fakeTransport = new ResumableErrorMediaTransport();
1234+
byte[] testedData = new byte[contentLength];
1235+
new Random().nextBytes(testedData);
1236+
TestingInputStream is = new TestingInputStream(testedData);
1237+
InputStreamContent mediaContent = new InputStreamContent(TEST_CONTENT_TYPE, is);
1238+
mediaContent.setLength(contentLength);
1239+
MediaHttpUploader uploader =
1240+
new MediaHttpUploader(mediaContent, fakeTransport, new ZeroBackOffRequestInitializer());
1241+
1242+
// disable GZip - so we would be able to test byte received by server.
1243+
uploader.setDisableGZipContent(true);
1244+
HttpResponse response = uploader.upload(new GenericUrl(TEST_RESUMABLE_REQUEST_URL));
1245+
assertEquals(500, response.getStatusCode());
1246+
1247+
assertTrue("input stream should be closed", is.isClosed);
1248+
}
11721249
}

0 commit comments

Comments
 (0)