Skip to content

Commit 75bb636

Browse files
committed
Close dangling snapshots and streams in ResponseCacheMiddleware.
Change-Id: Ibf3ba8e1e35b6a2926ec55c6781debda949c29ae
1 parent e240d15 commit 75bb636

File tree

3 files changed

+73
-18
lines changed

3 files changed

+73
-18
lines changed

AndroidAsync/src/com/koushikdutta/async/Util.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,13 @@ public static void writeAll(DataSink sink, byte[] bytes, CompletedCallback callb
183183
writeAll(sink, bbl, callback);
184184
}
185185

186-
public static AsyncSocket getWrappedSocket(AsyncSocket socket, Class wrappedClass) {
186+
public static <T extends AsyncSocket> T getWrappedSocket(AsyncSocket socket, Class<T> wrappedClass) {
187187
if (wrappedClass.isInstance(socket))
188-
return socket;
188+
return (T)socket;
189189
while (socket instanceof AsyncSocketWrapper) {
190190
socket = ((AsyncSocketWrapper)socket).getSocket();
191191
if (wrappedClass.isInstance(socket))
192-
return socket;
192+
return (T)socket;
193193
}
194194
return null;
195195
}

AndroidAsync/src/com/koushikdutta/async/http/ResponseCacheMiddleware.java

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ public AsyncServer getServer() {
251251
}
252252

253253
public static class CacheData implements Parcelable {
254+
DiskLruCache.Snapshot snapshot;
254255
CacheResponse candidate;
255256
long contentLength;
256257
ResponseHeaders cachedResponseHeaders;
@@ -278,7 +279,7 @@ public Cancellable getSocket(final GetSocketData data) {
278279
}
279280

280281
String key = uriToKey(data.request.getUri());
281-
DiskLruCache.Snapshot snapshot;
282+
DiskLruCache.Snapshot snapshot = null;
282283
Entry entry;
283284
try {
284285
snapshot = cache.get(key);
@@ -299,7 +300,7 @@ public Cancellable getSocket(final GetSocketData data) {
299300
snapshot.close();
300301
return null;
301302
}
302-
303+
303304
CacheResponse candidate = entry.isHttps() ? new EntrySecureCacheResponse(entry, snapshot) : new EntryCacheResponse(entry, snapshot);
304305

305306
Map<String, List<String>> responseHeadersMap;
@@ -310,6 +311,7 @@ public Cancellable getSocket(final GetSocketData data) {
310311
}
311312
catch (Exception e) {
312313
networkCount++;
314+
snapshot.close();
313315
return null;
314316
}
315317
if (responseHeadersMap == null || cachedResponseBody == null) {
@@ -319,6 +321,7 @@ public Cancellable getSocket(final GetSocketData data) {
319321
catch (Exception e) {
320322
}
321323
networkCount++;
324+
snapshot.close();
322325
return null;
323326
}
324327

@@ -351,6 +354,7 @@ public void run() {
351354
else if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
352355
data.request.logi("Response may be served from conditional cache");
353356
CacheData cacheData = new CacheData();
357+
cacheData.snapshot = snapshot;
354358
cacheData.contentLength = contentLength;
355359
cacheData.cachedResponseHeaders = cachedResponseHeaders;
356360
cacheData.candidate = candidate;
@@ -367,6 +371,7 @@ else if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
367371
catch (Exception e) {
368372
}
369373
networkCount++;
374+
snapshot.close();
370375
return null;
371376
}
372377
}
@@ -567,9 +572,10 @@ public void onBodyDecoder(OnBodyData data) {
567572
bodySpewer.spew();
568573
return;
569574
}
570-
575+
571576
// did not validate, so fall through and cache the response
572577
data.state.remove("cache-data");
578+
cacheData.snapshot.close();
573579
}
574580

575581
if (!caching)
@@ -623,17 +629,24 @@ public void onBodyDecoder(OnBodyData data) {
623629

624630
@Override
625631
public void onRequestComplete(OnRequestCompleteData data) {
626-
BodyCacher cacher = data.state.getParcelable("body-cacher");
627-
if (cacher == null)
628-
return;
632+
CacheData cacheData = data.state.getParcelable("cache-data");
633+
if (cacheData != null && cacheData.snapshot != null)
634+
cacheData.snapshot.close();
629635

630-
try {
631-
if (data.exception != null)
632-
cacher.abort();
633-
else
634-
cacher.commit();
635-
}
636-
catch (Exception e) {
636+
CachedSocket cachedSocket = Util.getWrappedSocket(data.socket, CachedSocket.class);
637+
if (cachedSocket != null)
638+
((SnapshotCacheResponse)cachedSocket.cacheResponse).getSnapshot().close();
639+
640+
BodyCacher cacher = data.state.getParcelable("body-cacher");
641+
if (cacher != null) {
642+
try {
643+
if (data.exception != null)
644+
cacher.abort();
645+
else
646+
cacher.commit();
647+
}
648+
catch (Exception e) {
649+
}
637650
}
638651
}
639652

@@ -901,11 +914,20 @@ private static InputStream newBodyInputStream(final DiskLruCache.Snapshot snapsh
901914
};
902915
}
903916

904-
static class EntryCacheResponse extends CacheResponse {
917+
static interface SnapshotCacheResponse {
918+
public DiskLruCache.Snapshot getSnapshot();
919+
}
920+
921+
static class EntryCacheResponse extends CacheResponse implements SnapshotCacheResponse {
905922
private final Entry entry;
906923
private final DiskLruCache.Snapshot snapshot;
907924
private final InputStream in;
908925

926+
@Override
927+
public DiskLruCache.Snapshot getSnapshot() {
928+
return snapshot;
929+
}
930+
909931
public EntryCacheResponse(Entry entry, DiskLruCache.Snapshot snapshot) {
910932
this.entry = entry;
911933
this.snapshot = snapshot;
@@ -921,11 +943,17 @@ public EntryCacheResponse(Entry entry, DiskLruCache.Snapshot snapshot) {
921943
}
922944
}
923945

924-
static class EntrySecureCacheResponse extends SecureCacheResponse {
946+
static class EntrySecureCacheResponse extends SecureCacheResponse implements SnapshotCacheResponse {
925947
private final Entry entry;
926948
private final DiskLruCache.Snapshot snapshot;
927949
private final InputStream in;
928950

951+
@Override
952+
public DiskLruCache.Snapshot getSnapshot() {
953+
return snapshot;
954+
}
955+
956+
929957
public EntrySecureCacheResponse(Entry entry, DiskLruCache.Snapshot snapshot) {
930958
this.entry = entry;
931959
this.snapshot = snapshot;

AndroidAsyncTest/src/com/koushikdutta/async/test/CacheTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.koushikdutta.async.AsyncServer;
66
import com.koushikdutta.async.http.AsyncHttpClient;
77
import com.koushikdutta.async.http.ResponseCacheMiddleware;
8+
import com.koushikdutta.async.http.libcore.DiskLruCache;
89
import com.koushikdutta.async.http.libcore.HttpDate;
910
import com.koushikdutta.async.http.server.AsyncHttpServer;
1011
import com.koushikdutta.async.http.server.AsyncHttpServerRequest;
@@ -51,4 +52,30 @@ public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse re
5152
client.getMiddleware().remove(cache);
5253
}
5354
}
55+
56+
// static public boolean deleteDirectory(File path) {
57+
// if (path.exists()) {
58+
// File[] files = path.listFiles();
59+
// if (files != null) {
60+
// for (int i = 0; i < files.length; i++) {
61+
// if (files[i].isDirectory()) {
62+
// deleteDirectory(files[i]);
63+
// } else {
64+
// files[i].delete();
65+
// }
66+
// }
67+
// }
68+
// }
69+
// return (path.delete());
70+
// }
71+
72+
// public void testDiskLruCache() throws Exception {
73+
// File dir = new File(Environment.getExternalStorageDirectory(), "AndroidAsyncTest/cache-test");
74+
// deleteDirectory(dir);
75+
// DiskLruCache cache = DiskLruCache.open(dir, 0, 1000, 10000000);
76+
// DiskLruCache.Editor editor = cache.edit("stuff");
77+
//
78+
// DiskLruCache cache2 = DiskLruCache.open(dir, 0, 2, 10000000);
79+
// DiskLruCache.Snapshot snapshot = cache2.get("stuff");
80+
// }
5481
}

0 commit comments

Comments
 (0)