diff --git a/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java b/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java index 4956608..e5c1c5e 100644 --- a/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java +++ b/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java @@ -36,7 +36,10 @@ import org.apache.http.HttpResponse; import org.apache.http.ProtocolVersion; import org.apache.http.StatusLine; import org.apache.http.annotation.Immutable; +import org.apache.http.impl.cookie.DateParseException; +import org.apache.http.impl.cookie.DateUtils; import org.apache.http.message.HeaderGroup; +import org.apache.http.protocol.HTTP; /** * Structure used to store an {@link HttpResponse} in a cache. Some entries @@ -58,6 +61,7 @@ public class HttpCacheEntry implements Serializable { private final HeaderGroup responseHeaders; private final Resource resource; private final Map variantMap; + private final Date dateHeaderValue; /** * Create a new {@link HttpCacheEntry} with variants. @@ -109,6 +113,7 @@ public class HttpCacheEntry implements Serializable { this.variantMap = variantMap != null ? new HashMap(variantMap) : null; + this.dateHeaderValue = parseDate(); } /** @@ -202,6 +207,13 @@ public class HttpCacheEntry implements Serializable { } /** + * Gets the Date value of the "Date" header or null if the header is missing or cannot be parsed + */ + public Date getDateHeaderValue() { + return dateHeaderValue; + } + + /** * Returns the {@link Resource} containing the origin response body. */ public Resource getResource() { @@ -240,4 +252,21 @@ public class HttpCacheEntry implements Serializable { return "[request date=" + this.requestDate + "; response date=" + this.responseDate + "; statusLine=" + this.statusLine + "]"; } + + /** + * Find the "Date" response header and parse it into a java.util.Date + * @return the Date value of the header or null if the header is not present + */ + private Date parseDate() { + Header dateHdr = getFirstHeader(HTTP.DATE_HEADER); + if (dateHdr == null) + return null; + try { + return DateUtils.parseDate(dateHdr.getValue()); + } catch (DateParseException dpe) { + // ignore malformed date + } + return null; + } + } diff --git a/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java b/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java index c87c7df..877062b 100644 --- a/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java +++ b/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java @@ -59,7 +59,7 @@ class CacheValidityPolicy { if (maxage > -1) return maxage; - Date dateValue = getDateValue(entry); + Date dateValue = entry.getDateHeaderValue(); if (dateValue == null) return 0L; @@ -94,7 +94,7 @@ class CacheValidityPolicy { public long getHeuristicFreshnessLifetimeSecs(HttpCacheEntry entry, float coefficient, long defaultLifetime) { - Date dateValue = getDateValue(entry); + Date dateValue = entry.getDateHeaderValue(); Date lastModifiedValue = getLastModifiedValue(entry); if (dateValue != null && lastModifiedValue != null) { @@ -168,16 +168,12 @@ class CacheValidityPolicy { return result; } + /** + * This method has been deprecated in favor of HttpCacheEntry.getDateHeaderValue() + */ + @Deprecated protected Date getDateValue(final HttpCacheEntry entry) { - Header dateHdr = entry.getFirstHeader(HTTP.DATE_HEADER); - if (dateHdr == null) - return null; - try { - return DateUtils.parseDate(dateHdr.getValue()); - } catch (DateParseException dpe) { - // ignore malformed date - } - return null; + return entry.getDateHeaderValue(); } protected Date getLastModifiedValue(final HttpCacheEntry entry) { @@ -220,7 +216,7 @@ class CacheValidityPolicy { } protected long getApparentAgeSecs(final HttpCacheEntry entry) { - Date dateValue = getDateValue(entry); + Date dateValue = entry.getDateHeaderValue(); if (dateValue == null) return MAX_AGE; long diff = entry.getResponseDate().getTime() - dateValue.getTime(); diff --git a/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java b/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java index 1d6dce3..6925042 100644 --- a/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java +++ b/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java @@ -309,4 +309,34 @@ public class TestHttpCacheEntry { assertNotNull(entry.toString()); assertFalse("".equals(entry.toString())); } + + @Test + public void testMissingDateHeaderIsIgnored() { + Header[] headers = new Header[] {}; + entry = new HttpCacheEntry(new Date(), new Date(), statusLine, + headers, mockResource); + assertNull(entry.getDateHeaderValue()); + } + + @Test + public void testMalformedDateHeaderIsIgnored() { + Header[] headers = new Header[] { new BasicHeader("Date", "asdf") }; + entry = new HttpCacheEntry(new Date(), new Date(), statusLine, + headers, mockResource); + assertNull(entry.getDateHeaderValue()); + } + + @Test + public void testValidDateHeaderIsParsed() { + long now = System.currentTimeMillis(); + // round down to nearest second to make comparison easier + Date date = new Date(now - (now % 1000L)); + Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(date)) }; + entry = new HttpCacheEntry(new Date(), new Date(), statusLine, + headers, mockResource); + Date dateHeaderValue = entry.getDateHeaderValue(); + assertNotNull(dateHeaderValue); + assertEquals(date.getTime(), dateHeaderValue.getTime()); + } + } diff --git a/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java b/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java index 3085643..ccfded4 100644 --- a/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java +++ b/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java @@ -352,13 +352,6 @@ public class TestCacheValidityPolicy { } @Test - public void testMalformedDateHeaderIsIgnored() { - Header[] headers = new Header[] { new BasicHeader("Date", "asdf") }; - HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); - assertNull(impl.getDateValue(entry)); - } - - @Test public void testMalformedContentLengthReturnsNegativeOne() { Header[] headers = new Header[] { new BasicHeader("Content-Length", "asdf") }; HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);