diff options
-rw-r--r-- | local.properties | 11 | ||||
-rw-r--r-- | src/main/java/com/android/volley/toolbox/HttpHeaderParser.java | 7 | ||||
-rw-r--r-- | src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java | 44 |
3 files changed, 54 insertions, 8 deletions
diff --git a/local.properties b/local.properties new file mode 100644 index 0000000..4de71c4 --- /dev/null +++ b/local.properties @@ -0,0 +1,11 @@ +## This file is automatically generated by Android Studio. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Wed Jan 28 16:21:52 PST 2015 +sdk.dir=/usr/local/google/clients/android/gcore-orla/prebuilts/fullsdk/linux diff --git a/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java b/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java index 7306052..c3b48d8 100644 --- a/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java +++ b/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java @@ -49,6 +49,7 @@ public class HttpHeaderParser { long maxAge = 0; long staleWhileRevalidate = 0; boolean hasCacheControl = false; + boolean mustRevalidate = false; String serverEtag = null; String headerValue; @@ -77,7 +78,7 @@ public class HttpHeaderParser { } catch (Exception e) { } } else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) { - maxAge = 0; + mustRevalidate = true; } } } @@ -98,7 +99,9 @@ public class HttpHeaderParser { // is more restrictive. if (hasCacheControl) { softExpire = now + maxAge * 1000; - finalExpire = softExpire + staleWhileRevalidate * 1000; + finalExpire = mustRevalidate + ? softExpire + : softExpire + staleWhileRevalidate * 1000; } else if (serverDate > 0 && serverExpires >= serverDate) { // Default semantic for Expire header in HTTP specification is softExpire. softExpire = now + (serverExpires - serverDate); diff --git a/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java b/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java index f9230c6..fd8cf51 100644 --- a/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java +++ b/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java @@ -41,6 +41,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 static long ONE_WEEK_MILLIS = ONE_DAY_MILLIS * 7; private NetworkResponse response; private Map<String, String> headers; @@ -135,7 +136,7 @@ public class HttpHeaderParserTest { assertNotNull(entry); assertNull(entry.etag); - assertEqualsWithin(now + 24 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); + assertEqualsWithin(now + ONE_DAY_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); assertEquals(entry.softTtl, entry.ttl); } @@ -153,8 +154,8 @@ public class HttpHeaderParserTest { assertNotNull(entry); assertNull(entry.etag); - assertEqualsWithin(now + 24 * ONE_HOUR_MILLIS, entry.softTtl, ONE_MINUTE_MILLIS); - assertEqualsWithin(now + 8 * 24 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); + assertEqualsWithin(now + ONE_DAY_MILLIS, entry.softTtl, ONE_MINUTE_MILLIS); + assertEqualsWithin(now + ONE_DAY_MILLIS + ONE_WEEK_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); } @Test public void parseCacheHeaders_cacheControlNoCache() { @@ -168,20 +169,51 @@ public class HttpHeaderParserTest { assertNull(entry); } - @Test public void parseCacheHeaders_cacheControlMustRevalidate() { + @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); + } + + @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); + } + private void assertEqualsWithin(long expected, long value, long fudgeFactor) { long diff = Math.abs(expected - value); assertTrue(diff < fudgeFactor); @@ -253,7 +285,7 @@ public class HttpHeaderParserTest { assertNotNull(entry); assertEquals("Yow!", entry.etag); - assertEqualsWithin(now + 24 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); + assertEqualsWithin(now + ONE_DAY_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); assertEquals(entry.softTtl, entry.ttl); assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); } |