@Test public void publicMethods() throws Exception { // Catch-all test to find API-breaking changes. assertNotNull(Response.class.getMethod("success", Object.class, Cache.Entry.class)); assertNotNull(Response.class.getMethod("error", VolleyError.class)); assertNotNull(Response.class.getMethod("isSuccess")); assertNotNull(Response.Listener.class.getDeclaredMethod("onResponse", Object.class)); assertNotNull(Response.ErrorListener.class.getDeclaredMethod("onErrorResponse", VolleyError.class)); assertNotNull(NetworkResponse.class.getConstructor(int.class, byte[].class, Map.class, boolean.class, long.class)); assertNotNull(NetworkResponse.class.getConstructor(int.class, byte[].class, Map.class, boolean.class)); assertNotNull(NetworkResponse.class.getConstructor(byte[].class)); assertNotNull(NetworkResponse.class.getConstructor(byte[].class, Map.class)); }
@Test public void parseCacheHeaders_cacheControlMustRevalidateWithMaxAgeAndStale() { long now = System.currentTimeMillis(); headers.put("Date", rfc1123Date(now)); headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); // - max-age (entry.softTtl) indicates that the asset is fresh for 1 day // - stale-while-revalidate (entry.ttl) indicates that the asset may // continue to be served stale for up to additional 7 days, but this is // ignored in this case because of the must-revalidate header. headers.put("Cache-Control", "must-revalidate, max-age=86400, stale-while-revalidate=604800"); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNull(entry.etag); assertEqualsWithin(now + ONE_DAY_MILLIS, entry.softTtl, ONE_MINUTE_MILLIS); assertEquals(entry.softTtl, entry.ttl); }
@Test public void parseCaseInsensitive() { long now = System.currentTimeMillis(); Header[] headersArray = new Header[5]; headersArray[0] = new BasicHeader("eTAG", "Yow!"); headersArray[1] = new BasicHeader("DATE", rfc1123Date(now)); headersArray[2] = new BasicHeader("expires", rfc1123Date(now + ONE_HOUR_MILLIS)); headersArray[3] = new BasicHeader("cache-control", "public, max-age=86400"); headersArray[4] = new BasicHeader("content-type", "text/plain"); Map<String, String> headers = BasicNetwork.convertHeaders(headersArray); NetworkResponse response = new NetworkResponse(0, null, headers, false); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertEquals("Yow!", entry.etag); assertEqualsWithin(now + ONE_DAY_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); assertEquals(entry.softTtl, entry.ttl); assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); }
@Test public void cacheHeaderSerialization() throws Exception { Cache.Entry e = new Cache.Entry(); e.data = new byte[8]; e.serverDate = 1234567L; e.lastModified = 13572468L; e.ttl = 9876543L; e.softTtl = 8765432L; e.etag = "etag"; e.responseHeaders = new HashMap<String, String>(); e.responseHeaders.put("fruit", "banana"); CacheHeader first = new CacheHeader("my-magical-key", e); ByteArrayOutputStream baos = new ByteArrayOutputStream(); first.writeHeader(baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); CacheHeader second = CacheHeader.readHeader(bais); assertEquals(first.key, second.key); assertEquals(first.serverDate, second.serverDate); assertEquals(first.lastModified, second.lastModified); assertEquals(first.ttl, second.ttl); assertEquals(first.softTtl, second.softTtl); assertEquals(first.etag, second.etag); assertEquals(first.responseHeaders, second.responseHeaders); }
/** * Makes a random cache entry. * @param data Data to use, or null to use random data * @param isExpired Whether the TTLs should be set such that this entry is expired * @param needsRefresh Whether the TTLs should be set such that this entry needs refresh */ public static Cache.Entry makeRandomCacheEntry( byte[] data, boolean isExpired, boolean needsRefresh) { Random random = new Random(); Cache.Entry entry = new Cache.Entry(); if (data != null) { entry.data = data; } else { entry.data = new byte[random.nextInt(1024)]; } entry.etag = String.valueOf(random.nextLong()); entry.lastModified = random.nextLong(); entry.ttl = isExpired ? 0 : Long.MAX_VALUE; entry.softTtl = needsRefresh ? 0 : Long.MAX_VALUE; return entry; }
@Test public void testParseCacheHeaders_staleWhileRevalidate() { long now = System.currentTimeMillis(); headers.put("Date", rfc1123Date(now)); headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); // - max-age (entry.softTtl) indicates that the asset is fresh for 1 day // - stale-while-revalidate (entry.ttl) indicates that the asset may // continue to be served stale for up to additional 7 days headers.put("Cache-Control", "max-age=86400, stale-while-revalidate=604800"); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNull(entry.etag); assertEqualsWithin(now + ONE_DAY_MILLIS, entry.softTtl, ONE_MINUTE_MILLIS); assertEqualsWithin(now + ONE_DAY_MILLIS + ONE_WEEK_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); }
/** * 缓存 */ private void requestOkHttp() { new OkHttpClient.Builder().addInterceptor(new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { okhttp3.Request request = chain.request(); // chain.request().newBuilder().addHeader().build() okhttp3.Response response = chain.proceed(request); return response; } }).cache(new okhttp3.Cache(getCacheDir(), 5 * 1024 * 1024)).build(); okhttp3.Request request_forceNocache = new okhttp3.Request.Builder().cacheControl(new CacheControl.Builder().noCache().build()).url("").build(); okhttp3.Request request_forceCache = new okhttp3.Request.Builder().cacheControl(new CacheControl.Builder().maxAge(0, TimeUnit.SECONDS).build()).url("").build(); }
public void testCacheHeaderSerialization() throws Exception { Cache.Entry e = new Cache.Entry(); e.data = new byte[8]; e.serverDate = 1234567L; e.ttl = 9876543L; e.softTtl = 8765432L; e.etag = "etag"; e.responseHeaders = new HashMap<String, String>(); e.responseHeaders.put("fruit", "banana"); CacheHeader first = new CacheHeader("my-magical-key", e); ByteArrayOutputStream baos = new ByteArrayOutputStream(); first.writeHeader(baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); CacheHeader second = CacheHeader.readHeader(bais); assertEquals(first.key, second.key); assertEquals(first.serverDate, second.serverDate); assertEquals(first.ttl, second.ttl); assertEquals(first.softTtl, second.softTtl); assertEquals(first.etag, second.etag); assertEquals(first.responseHeaders, second.responseHeaders); }
/** * Makes a random cache entry. * @param data Data to use, or null to use random data * @param isExpired Whether the TTLs should be set such that this entry is expired * @param needsRefresh Whether the TTLs should be set such that this entry needs refresh */ public static Cache.Entry makeRandomCacheEntry( byte[] data, boolean isExpired, boolean needsRefresh) { Random random = new Random(); Cache.Entry entry = new Cache.Entry(); if (data != null) { entry.data = data; } else { entry.data = new byte[random.nextInt(1024)]; } entry.etag = String.valueOf(random.nextLong()); entry.serverDate = random.nextLong(); entry.ttl = isExpired ? 0 : Long.MAX_VALUE; entry.softTtl = needsRefresh ? 0 : Long.MAX_VALUE; return entry; }
private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry) { // If there's no cache entry, we're done. if (entry == null) { return; } if (entry.etag != null) { headers.put("If-None-Match", entry.etag); } if (entry.lastModified > 0) { Date refTime = new Date(entry.lastModified); headers.put("If-Modified-Since", DateUtils.formatDate(refTime)); } }
@Test public void parseCacheHeaders_noHeaders() { Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNull(entry.etag); assertEquals(0, entry.serverDate); assertEquals(0, entry.lastModified); assertEquals(0, entry.ttl); assertEquals(0, entry.softTtl); }
@Test public void parseCacheHeaders_headersSet() { headers.put("MyCustomHeader", "42"); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNotNull(entry.responseHeaders); assertEquals(1, entry.responseHeaders.size()); assertEquals("42", entry.responseHeaders.get("MyCustomHeader")); }
@Test public void parseCacheHeaders_etag() { headers.put("ETag", "Yow!"); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertEquals("Yow!", entry.etag); }
@Test public void parseCacheHeaders_normalExpire() { long now = System.currentTimeMillis(); headers.put("Date", rfc1123Date(now)); headers.put("Last-Modified", rfc1123Date(now - ONE_DAY_MILLIS)); headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNull(entry.etag); assertEqualsWithin(entry.serverDate, now, ONE_MINUTE_MILLIS); assertEqualsWithin(entry.lastModified, (now - ONE_DAY_MILLIS), ONE_MINUTE_MILLIS); assertTrue(entry.softTtl >= (now + ONE_HOUR_MILLIS)); assertTrue(entry.ttl == entry.softTtl); }
@Test public void parseCacheHeaders_expiresInPast() { long now = System.currentTimeMillis(); headers.put("Date", rfc1123Date(now)); headers.put("Expires", rfc1123Date(now - ONE_HOUR_MILLIS)); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNull(entry.etag); assertEqualsWithin(entry.serverDate, now, ONE_MINUTE_MILLIS); assertEquals(0, entry.ttl); assertEquals(0, entry.softTtl); }
@Test public void parseCacheHeaders_serverRelative() { long now = System.currentTimeMillis(); // Set "current" date as one hour in the future headers.put("Date", rfc1123Date(now + ONE_HOUR_MILLIS)); // TTL four hours in the future, so should be three hours from now headers.put("Expires", rfc1123Date(now + 4 * ONE_HOUR_MILLIS)); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertEqualsWithin(now + 3 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); assertEquals(entry.softTtl, entry.ttl); }
@Test public void parseCacheHeaders_cacheControlOverridesExpires() { long now = System.currentTimeMillis(); headers.put("Date", rfc1123Date(now)); headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); headers.put("Cache-Control", "public, max-age=86400"); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNull(entry.etag); assertEqualsWithin(now + ONE_DAY_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); assertEquals(entry.softTtl, entry.ttl); }
@Test public void parseCacheHeaders_cacheControlNoCache() { long now = System.currentTimeMillis(); headers.put("Date", rfc1123Date(now)); headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); headers.put("Cache-Control", "no-cache"); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNull(entry); }
@Test public void parseCacheHeaders_cacheControlMustRevalidateNoMaxAge() { long now = System.currentTimeMillis(); headers.put("Date", rfc1123Date(now)); headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); headers.put("Cache-Control", "must-revalidate"); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNull(entry.etag); assertEqualsWithin(now, entry.ttl, ONE_MINUTE_MILLIS); assertEquals(entry.softTtl, entry.ttl); }
@Test public void parseCacheHeaders_cacheControlMustRevalidateWithMaxAge() { long now = System.currentTimeMillis(); headers.put("Date", rfc1123Date(now)); headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); headers.put("Cache-Control", "must-revalidate, max-age=3600"); Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); assertNotNull(entry); assertNull(entry.etag); assertEqualsWithin(now + ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); assertEquals(entry.softTtl, entry.ttl); }