Skip to content

Commit 4de007a

Browse files
committed
Close network stream in ParseRESTCommand after we consume it
1 parent c85a1ea commit 4de007a

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

Parse/src/main/java/com/parse/ParseRESTCommand.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,14 @@ public Task<JSONObject> executeAsync(
250250
protected Task<JSONObject> onResponseAsync(ParseHttpResponse response,
251251
ProgressCallback downloadProgressCallback) {
252252
String content;
253+
InputStream responseStream = null;
253254
try {
254-
InputStream responseStream = response.getContent();
255+
responseStream = response.getContent();
255256
content = new String(ParseIOUtils.toByteArray(responseStream));
256257
} catch (IOException e) {
257258
return Task.forError(e);
259+
} finally {
260+
ParseIOUtils.closeQuietly(responseStream);
258261
}
259262

260263
// We need to check for errors differently in /1/ than /2/ since object data in /2/ was

Parse/src/test/java/com/parse/ParseRESTCommandTest.java

+63
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.skyscreamer.jsonassert.JSONCompareMode;
2222

2323
import java.io.ByteArrayInputStream;
24+
import java.io.IOException;
25+
import java.io.InputStream;
2426

2527
import bolts.Task;
2628

@@ -29,7 +31,10 @@
2931
import static org.junit.Assert.assertNull;
3032
import static org.junit.Assert.assertTrue;
3133
import static org.mockito.Matchers.any;
34+
import static org.mockito.Mockito.doNothing;
35+
import static org.mockito.Mockito.doThrow;
3236
import static org.mockito.Mockito.mock;
37+
import static org.mockito.Mockito.spy;
3338
import static org.mockito.Mockito.times;
3439
import static org.mockito.Mockito.verify;
3540
import static org.mockito.Mockito.when;
@@ -449,4 +454,62 @@ public void testFromJSONObject() throws Exception {
449454
assertEquals(localId, command.getLocalId());
450455
assertEquals(jsonParameters, command.jsonParameters, JSONCompareMode.NON_EXTENSIBLE);
451456
}
457+
458+
@Test
459+
public void testOnResponseCloseNetworkStreamWithNormalResponse() throws Exception {
460+
// Mock response stream
461+
int statusCode = 200;
462+
JSONObject bodyJson = new JSONObject();
463+
bodyJson.put("key", "value");
464+
String bodyStr = bodyJson.toString();
465+
ByteArrayInputStream bodyStream = new ByteArrayInputStream(bodyStr.getBytes());
466+
InputStream mockResponseStream = spy(bodyStream);
467+
doNothing()
468+
.when(mockResponseStream)
469+
.close();
470+
// Mock response
471+
ParseHttpResponse response = mock(ParseHttpResponse.class);
472+
when(response.getStatusCode()).thenReturn(statusCode);
473+
when(response.getContent()).thenReturn(mockResponseStream);
474+
when(response.getTotalSize()).thenReturn(bodyStr.length());
475+
476+
477+
ParseRESTCommand command = new ParseRESTCommand.Builder().build();
478+
JSONObject json = ParseTaskUtils.wait(command.onResponseAsync(response, null));
479+
480+
verify(mockResponseStream, times(1)).close();
481+
assertEquals(bodyJson, json, JSONCompareMode.NON_EXTENSIBLE);
482+
}
483+
484+
@Test
485+
public void testOnResposneCloseNetworkStreamWithIOException() throws Exception {
486+
// Mock response stream
487+
int statusCode = 200;
488+
InputStream mockResponseStream = mock(InputStream.class);
489+
doNothing()
490+
.when(mockResponseStream)
491+
.close();
492+
IOException readException = new IOException("Error");
493+
doThrow(readException)
494+
.when(mockResponseStream)
495+
.read();
496+
doThrow(readException)
497+
.when(mockResponseStream)
498+
.read(any(byte[].class));
499+
// Mock response
500+
ParseHttpResponse response = mock(ParseHttpResponse.class);
501+
when(response.getStatusCode()).thenReturn(statusCode);
502+
when(response.getContent()).thenReturn(mockResponseStream);
503+
504+
ParseRESTCommand command = new ParseRESTCommand.Builder().build();
505+
// We can not use ParseTaskUtils here since it will replace the original exception with runtime
506+
// exception
507+
Task<JSONObject> responseTask = command.onResponseAsync(response, null);
508+
responseTask.waitForCompletion();
509+
510+
assertTrue(responseTask.isFaulted());
511+
assertTrue(responseTask.getError() instanceof IOException);
512+
assertEquals("Error", responseTask.getError().getMessage());
513+
verify(mockResponseStream, times(1)).close();
514+
}
452515
}

0 commit comments

Comments
 (0)