/** * Returns an input stream that reads the body of a snapshot, closing the snapshot when the stream * is closed. */ private static InputStream newBodyInputStream(final DiskLruCache.Snapshot snapshot) { return new FilterInputStream(snapshot.getInputStream(ENTRY_BODY)) { @Override public void close() throws IOException { snapshot.close(); super.close(); } }; }
// step 1) see if we can serve request from the cache directly. // also see if this can be turned into a conditional cache request. @Override public Cancellable getSocket(final GetSocketData data) { if (cache == null) return null; if (!caching) return null; if (data.request.getHeaders().isNoCache()) return null; // Log.i(LOGTAG, "getting cache socket: " + request.getUri().toString()); String key = uriToKey(data.request.getUri()); DiskLruCache.Snapshot snapshot; Entry entry; try { snapshot = cache.get(key); if (snapshot == null) { // Log.i(LOGTAG, "snapshot fail"); return null; } entry = new Entry(snapshot.getInputStream(ENTRY_METADATA)); } catch (IOException e) { // Give up because the cache cannot be read. return null; } if (!entry.matches( data.request.getUri(), data.request.getMethod(), data.request.getHeaders().getHeaders().toMultimap())) { snapshot.close(); return null; } ResponseSource responseSource = ResponseSource.NETWORK; CacheResponse candidate = entry.isHttps() ? new EntrySecureCacheResponse(entry, snapshot) : new EntryCacheResponse(entry, snapshot); Map<String, List<String>> responseHeadersMap; InputStream cachedResponseBody; try { responseHeadersMap = candidate.getHeaders(); cachedResponseBody = candidate.getBody(); } catch (Exception e) { return null; } if (responseHeadersMap == null || cachedResponseBody == null) { try { cachedResponseBody.close(); } catch (Exception e) { } return null; } RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(responseHeadersMap); ResponseHeaders cachedResponseHeaders = new ResponseHeaders(data.request.getUri(), rawResponseHeaders); long now = System.currentTimeMillis(); responseSource = cachedResponseHeaders.chooseResponseSource(now, data.request.getHeaders()); if (responseSource == ResponseSource.CACHE) { cacheStoreCount++; final CachedSocket socket = entry.isHttps() ? new CachedSSLSocket((EntrySecureCacheResponse) candidate) : new CachedSocket((EntryCacheResponse) candidate); client .getServer() .post( new Runnable() { @Override public void run() { data.connectCallback.onConnectCompleted(null, socket); socket.spewInternal(); } }); } else if (responseSource == ResponseSource.CONDITIONAL_CACHE) { CacheData cacheData = new CacheData(); cacheData.cachedResponseHeaders = cachedResponseHeaders; cacheData.candidate = candidate; data.state.putParcelable("cache-data", cacheData); return null; } else { // NETWORK or other try { cachedResponseBody.close(); } catch (Exception e) { } return null; } return new SimpleCancelable(); }