1e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller/* 2e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Copyright (C) 2011 The Android Open Source Project 3e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * 4e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License"); 5e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * you may not use this file except in compliance with the License. 6e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * You may obtain a copy of the License at 7e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * 8e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * http://www.apache.org/licenses/LICENSE-2.0 9e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * 10e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Unless required by applicable law or agreed to in writing, software 11e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS, 12e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * See the License for the specific language governing permissions and 14e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * limitations under the License. 15e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 16e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 17e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpackage com.squareup.okhttp.android; 18e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 19e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport com.squareup.okhttp.Cache; 20e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport com.squareup.okhttp.AndroidShimResponseCache; 21e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport com.squareup.okhttp.OkCacheContainer; 22e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 23e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.Closeable; 24e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.File; 25e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.IOException; 26e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.CacheRequest; 27e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.CacheResponse; 28e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.ResponseCache; 29e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.URI; 30e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.URLConnection; 31e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.List; 32e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.Map; 33e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 34e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller/** 35e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * A copy of android.net.http.HttpResponseCache taken from AOSP. Android need to keep this code 36e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * working somehow. Dependencies on com.squareup.okhttp are com.android.okhttp on Android. 37e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 38e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller/* <p>This class exists in okhttp-android-support to help keep the API as it always has been on 39e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Android. The public API cannot be changed. This class delegates to 40e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * {@link com.squareup.okhttp.AndroidShimResponseCache}, a class that exists in a package that 41e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * enables it to interact with non-public OkHttp classes. 42e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 43e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpublic final class HttpResponseCache extends ResponseCache implements Closeable, OkCacheContainer { 44e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 45e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private AndroidShimResponseCache shimResponseCache; 46e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 47e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private HttpResponseCache(AndroidShimResponseCache shimResponseCache) { 48e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.shimResponseCache = shimResponseCache; 49e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 50e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 51e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 52e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the currently-installed {@code HttpResponseCache}, or null if 53e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * there is no cache installed or it is not a {@code HttpResponseCache}. 54e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 55e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public static HttpResponseCache getInstalled() { 56e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller ResponseCache installed = ResponseCache.getDefault(); 57e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (installed instanceof HttpResponseCache) { 58e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return (HttpResponseCache) installed; 59e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 60e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return null; 61e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 62e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 63e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 64e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Creates a new HTTP response cache and sets it as the system default cache. 65e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * 66e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * @param directory the directory to hold cache data. 67e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * @param maxSize the maximum size of the cache in bytes. 68e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * @return the newly-installed cache 69e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * @throws java.io.IOException if {@code directory} cannot be used for this cache. 70e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Most applications should respond to this exception by logging a 71e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * warning. 72e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 73e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public static synchronized HttpResponseCache install(File directory, long maxSize) throws 74e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller IOException { 75e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller ResponseCache installed = ResponseCache.getDefault(); 76e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 77e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (installed instanceof HttpResponseCache) { 78e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller HttpResponseCache installedResponseCache = (HttpResponseCache) installed; 79e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller // don't close and reopen if an equivalent cache is already installed 80e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller AndroidShimResponseCache trueResponseCache = installedResponseCache.shimResponseCache; 81e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (trueResponseCache.isEquivalent(directory, maxSize)) { 82e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return installedResponseCache; 83e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } else { 84e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller // The HttpResponseCache that owns this object is about to be replaced. 85e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller trueResponseCache.close(); 86e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 87e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 88e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 89e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller AndroidShimResponseCache trueResponseCache = 90e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller AndroidShimResponseCache.create(directory, maxSize); 91e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller HttpResponseCache newResponseCache = new HttpResponseCache(trueResponseCache); 92e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller ResponseCache.setDefault(newResponseCache); 93e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return newResponseCache; 94e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 95e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 96e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public CacheResponse get(URI uri, String requestMethod, 97e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Map<String, List<String>> requestHeaders) throws IOException { 98e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return shimResponseCache.get(uri, requestMethod, requestHeaders); 99e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 100e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 101e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException { 102e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return shimResponseCache.put(uri, urlConnection); 103e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 104e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 105e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 106e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the number of bytes currently being used to store the values in 107e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * this cache. This may be greater than the {@link #maxSize} if a background 108e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * deletion is pending. 109e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 110e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public long size() { 111e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 112e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return shimResponseCache.size(); 113e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (IOException e) { 114e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller // This can occur if the cache failed to lazily initialize. Return -1 to mean "unknown". 115e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return -1; 116e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 117e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 118e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 119e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 120e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the maximum number of bytes that this cache should use to store 121e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * its data. 122e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 123e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public long maxSize() { 124e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return shimResponseCache.maxSize(); 125e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 126e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 127e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 128e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Force buffered operations to the filesystem. This ensures that responses 129e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * written to the cache will be available the next time the cache is opened, 130e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * even if this process is killed. 131e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 132e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public void flush() { 133e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 134e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller shimResponseCache.flush(); 135e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (IOException ignored) { 136e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 137e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 138e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 139e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 140e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the number of HTTP requests that required the network to either 141e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * supply a response or validate a locally cached response. 142e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 143e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public int getNetworkCount() { 144e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return shimResponseCache.getNetworkCount(); 145e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 146e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 147e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 148e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the number of HTTP requests whose response was provided by the 149e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * cache. This may include conditional {@code GET} requests that were 150e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * validated over the network. 151e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 152e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public int getHitCount() { 153e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return shimResponseCache.getHitCount(); 154e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 155e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 156e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 157e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the total number of HTTP requests that were made. This includes 158e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * both client requests and requests that were made on the client's behalf 159e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * to handle a redirects and retries. 160e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 161e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public int getRequestCount() { 162e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return shimResponseCache.getRequestCount(); 163e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 164e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 165e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 166e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Uninstalls the cache and releases any active resources. Stored contents 167e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * will remain on the filesystem. 168e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 169e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public void close() throws IOException { 170e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (ResponseCache.getDefault() == this) { 171e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller ResponseCache.setDefault(null); 172e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 173e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller shimResponseCache.close(); 174e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 175e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 176e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 177e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Uninstalls the cache and deletes all of its stored contents. 178e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 179e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public void delete() throws IOException { 180e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (ResponseCache.getDefault() == this) { 181e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller ResponseCache.setDefault(null); 182e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 183e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller shimResponseCache.delete(); 184e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 185e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 186e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override 187e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public Cache getCache() { 188e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return shimResponseCache.getCache(); 189e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 190e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 191e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller} 192