hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jon Moore (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (HTTPCLIENT-1415) Cached entry is not flushed when a response contains a content-location header without an ETag header field
Date Tue, 08 Oct 2013 10:09:42 GMT

    [ https://issues.apache.org/jira/browse/HTTPCLIENT-1415?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13789081#comment-13789081

Jon Moore commented on HTTPCLIENT-1415:

Hi Kyle,

The way the existing invalidation works is intentional, and standards-compliant. Remember
that HTTP caching is designed to work best with cache entries that do not require validation,
and in the absence of other cache headers, such as 'Cache-Control: max-age=0', does not guarantee
strong consistency with the origin. You can also see this sentiment in the protocol design
in heuristic caching. At any rate, caches generally will want to preserve cache entries for
as long as possible, so the various invalidation cases in the spec are set up to only flush
cache entries when the cache can definitively tell they are stale; otherwise, the cache relies
on the cache-related headers on the entry itself.

In this particular case, the semantics of the Content-Location header don't mean "go invalidate
an entry for this" per se; rather it indicates a URL for the response body, which may or may
not be identical to an existing cache entry. In this case, if the secondary response (the
one with the Content-Location header) has an explicitly different ETag from the cache entry,
then we know that the two entities (bodies) are different; if we also see that the secondary
response has a later Date, then we also know that the cache entry is stale, and we revalidate
it. In the absence of ETags though, we can't tell if the bodies are different or not, so we
have to make a choice. In this case, we err on the side of avoiding the invalidation of a
valid cache entry, relying instead on the cache semantics of the cache entry's headers.

So, long story short, this is not a bug, and we won't apply your patch as-is. However, I recognize
that this is an engineering choice: the spec would permit either behavior, and the current
behavior is my interpretation of the protocol designers' intent. However, I can understand
preferring instead in some use cases to have the more aggressive invalidation you're proposing.
I believe we just opened the API to allow for alternative CacheInvalidators--there's a related
JIRA issue for that which I will look up and post here shortly.

> Cached entry is not flushed when a response contains a content-location header without
an ETag header field
> -----------------------------------------------------------------------------------------------------------
>                 Key: HTTPCLIENT-1415
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1415
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>          Components: HttpCache
>    Affects Versions: 4.3.1
>         Environment: Windows 7, Tomcat
>            Reporter: kyle leonhard
>             Fix For: 4.3.2
>         Attachments: CacheInvalidator.java.patch
> When a response returns a content-location header, flushLocationCacheEntry is invoked
on the content-location's URL.  flushLocationCacheEntry causes the cached entry to be flushed
if the entry is older than the response and the etags differ.
> However, the response and entry ETags are not considered different if either ETag header
values are null(see:CacheInvalidator.responseAndEntryEtagsDiffer).  This causes the resource
referenced by the response's content-location header to remain cached.
> I'm not familiar with the HTTP spec, but the responseAndEntryEtagsDiffer, ETag null checks
seem iffy.
> The same problem effects 4.2.5 as well.
> **Relevant code
> ***From CacheInvalidator.flushInvalidatedCacheEntries:
> final URL contentLocation = getContentLocationURL(reqURL, response);
> if (contentLocation != null) {
>     flushLocationCacheEntry(reqURL, response, contentLocation);
> }
> ***From CacheInvalidator.flushLocationCacheEntry
> if (responseDateOlderThanEntryDate(response, entry)) {
>    return;
> }
> if (!responseAndEntryEtagsDiffer(response, entry)) {
>     return;
> }
> ***From CacheInvalidator.responseAndEntryEtagsDiffer:
> if (entryEtag == null || responseEtag == null) {
>     return false;
> }

This message was sent by Atlassian JIRA

To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org

View raw message