[ 
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
(v6.1#6144)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to