diff options
author | Ralph Bergmann <ralph@the4thfloor.eu> | 2014-09-21 22:09:33 +0200 |
---|---|---|
committer | Ficus Kirkpatrick <ficus@android.com> | 2015-02-15 09:09:05 -0800 |
commit | 9324df1b8046548587ffec89ec755264f6fbb097 (patch) | |
tree | 0f0cb0b835925767038340745b0faf82bce15996 | |
parent | 3ac982d9455cb18d1c9ca10e695770d72fe21c90 (diff) | |
download | volley-9324df1b8046548587ffec89ec755264f6fbb097.tar.gz |
Uses the "Last-Modified" header for "If-Modified-Since"
Uses the "Last-Modified" header for "If-Modified-Since"
see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4
Change-Id: I0f5e9b45f4f79d7c1b286e465f9750dcd71b6bfd
Signed-off-by: Ralph Bergmann <ralph@the4thfloor.eu>
7 files changed, 71 insertions, 3 deletions
diff --git a/src/main/java/com/android/volley/Cache.java b/src/main/java/com/android/volley/Cache.java index eafd118..f1ec757 100644 --- a/src/main/java/com/android/volley/Cache.java +++ b/src/main/java/com/android/volley/Cache.java @@ -74,6 +74,9 @@ public interface Cache { /** Date of this response as reported by the server. */ public long serverDate; + /** The last modified date for the requested object. */ + public long lastModified; + /** TTL for this record. */ public long ttl; diff --git a/src/main/java/com/android/volley/toolbox/BasicNetwork.java b/src/main/java/com/android/volley/toolbox/BasicNetwork.java index bc1cfdb..4b1603b 100644 --- a/src/main/java/com/android/volley/toolbox/BasicNetwork.java +++ b/src/main/java/com/android/volley/toolbox/BasicNetwork.java @@ -212,8 +212,8 @@ public class BasicNetwork implements Network { headers.put("If-None-Match", entry.etag); } - if (entry.serverDate > 0) { - Date refTime = new Date(entry.serverDate); + if (entry.lastModified > 0) { + Date refTime = new Date(entry.lastModified); headers.put("If-Modified-Since", DateUtils.formatDate(refTime)); } } diff --git a/src/main/java/com/android/volley/toolbox/DiskBasedCache.java b/src/main/java/com/android/volley/toolbox/DiskBasedCache.java index b283788..036b55a 100644 --- a/src/main/java/com/android/volley/toolbox/DiskBasedCache.java +++ b/src/main/java/com/android/volley/toolbox/DiskBasedCache.java @@ -349,6 +349,9 @@ public class DiskBasedCache implements Cache { /** Date of this response as reported by the server. */ public long serverDate; + /** The last modified date for the requested object. */ + public long lastModified; + /** TTL for this record. */ public long ttl; @@ -370,6 +373,7 @@ public class DiskBasedCache implements Cache { this.size = entry.data.length; this.etag = entry.etag; this.serverDate = entry.serverDate; + this.lastModified = entry.lastModified; this.ttl = entry.ttl; this.softTtl = entry.softTtl; this.responseHeaders = entry.responseHeaders; @@ -396,6 +400,13 @@ public class DiskBasedCache implements Cache { entry.ttl = readLong(is); entry.softTtl = readLong(is); entry.responseHeaders = readStringStringMap(is); + + try { + entry.lastModified = readLong(is); + } catch (EOFException e) { + // the old cache entry format doesn't know lastModified + } + return entry; } @@ -407,6 +418,7 @@ public class DiskBasedCache implements Cache { e.data = data; e.etag = etag; e.serverDate = serverDate; + e.lastModified = lastModified; e.ttl = ttl; e.softTtl = softTtl; e.responseHeaders = responseHeaders; @@ -426,6 +438,7 @@ public class DiskBasedCache implements Cache { writeLong(os, ttl); writeLong(os, softTtl); writeStringStringMap(responseHeaders, os); + writeLong(os, lastModified); os.flush(); return true; } catch (IOException e) { diff --git a/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java b/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java index cb08432..e342c9e 100644 --- a/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java +++ b/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java @@ -42,6 +42,7 @@ public class HttpHeaderParser { Map<String, String> headers = response.headers; long serverDate = 0; + long lastModified = 0; long serverExpires = 0; long softExpire = 0; long maxAge = 0; @@ -79,6 +80,11 @@ public class HttpHeaderParser { serverExpires = parseDateAsEpoch(headerValue); } + headerValue = headers.get("Last-Modified"); + if (headerValue != null) { + lastModified = parseDateAsEpoch(headerValue); + } + serverEtag = headers.get("ETag"); // Cache-Control takes precedence over an Expires header, even if both exist and Expires @@ -96,6 +102,7 @@ public class HttpHeaderParser { entry.softTtl = softExpire; entry.ttl = entry.softTtl; entry.serverDate = serverDate; + entry.lastModified = lastModified; entry.responseHeaders = headers; return entry; diff --git a/src/test/java/com/android/volley/toolbox/DiskBasedCacheTest.java b/src/test/java/com/android/volley/toolbox/DiskBasedCacheTest.java index 4b2955d..d9d49e9 100644 --- a/src/test/java/com/android/volley/toolbox/DiskBasedCacheTest.java +++ b/src/test/java/com/android/volley/toolbox/DiskBasedCacheTest.java @@ -34,6 +34,7 @@ public class DiskBasedCacheTest { 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"; @@ -48,6 +49,7 @@ public class DiskBasedCacheTest { 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); @@ -121,4 +123,43 @@ public class DiskBasedCacheTest { assertEquals(DiskBasedCache.readStringStringMap(bais), emptyKey); assertEquals(DiskBasedCache.readStringStringMap(bais), emptyValue); } + + // Test deserializing the old format into the new one. + public void testCacheHeaderSerializationOldToNewFormat() throws Exception { + + final int CACHE_MAGIC = 0x20140623; + final String key = "key"; + final String etag = "etag"; + final long serverDate = 1234567890l; + final long ttl = 1357924680l; + final long softTtl = 2468013579l; + + Map<String, String> responseHeaders = new HashMap<String, String>(); + responseHeaders.put("first", "thing"); + responseHeaders.put("second", "item"); + + // write old sytle header (without lastModified) + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DiskBasedCache.writeInt(baos, CACHE_MAGIC); + DiskBasedCache.writeString(baos, key); + DiskBasedCache.writeString(baos, etag == null ? "" : etag); + DiskBasedCache.writeLong(baos, serverDate); + DiskBasedCache.writeLong(baos, ttl); + DiskBasedCache.writeLong(baos, softTtl); + DiskBasedCache.writeStringStringMap(responseHeaders, baos); + + // read / test new style header (with lastModified) + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + CacheHeader cacheHeader = CacheHeader.readHeader(bais); + + assertEquals(cacheHeader.key, key); + assertEquals(cacheHeader.etag, etag); + assertEquals(cacheHeader.serverDate, serverDate); + assertEquals(cacheHeader.ttl, ttl); + assertEquals(cacheHeader.softTtl, softTtl); + assertEquals(cacheHeader.responseHeaders, responseHeaders); + + // the old format doesn't know lastModified + assertEquals(cacheHeader.lastModified, 0); + } } diff --git a/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java b/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java index b8c4847..01ff2c2 100644 --- a/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java +++ b/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java @@ -40,6 +40,7 @@ public class HttpHeaderParserTest { private static long ONE_MINUTE_MILLIS = 1000L * 60; private static long ONE_HOUR_MILLIS = 1000L * 60 * 60; + private static long ONE_DAY_MILLIS = ONE_HOUR_MILLIS * 24; private NetworkResponse response; private Map<String, String> headers; @@ -55,6 +56,7 @@ public class HttpHeaderParserTest { assertNotNull(entry); assertNull(entry.etag); assertEquals(0, entry.serverDate); + assertEquals(0, entry.lastModified); assertEquals(0, entry.ttl); assertEquals(0, entry.softTtl); } @@ -82,6 +84,7 @@ public class HttpHeaderParserTest { @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); @@ -89,6 +92,7 @@ public class HttpHeaderParserTest { 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); } diff --git a/src/test/java/com/android/volley/utils/CacheTestUtils.java b/src/test/java/com/android/volley/utils/CacheTestUtils.java index cd2b8e7..898d055 100644 --- a/src/test/java/com/android/volley/utils/CacheTestUtils.java +++ b/src/test/java/com/android/volley/utils/CacheTestUtils.java @@ -24,7 +24,7 @@ public class CacheTestUtils { entry.data = new byte[random.nextInt(1024)]; } entry.etag = String.valueOf(random.nextLong()); - entry.serverDate = random.nextLong(); + entry.lastModified = random.nextLong(); entry.ttl = isExpired ? 0 : Long.MAX_VALUE; entry.softTtl = needsRefresh ? 0 : Long.MAX_VALUE; return entry; |