HTTPCLIENT-1202: ResponseCachingPolicy had a bug that was making it too
draconian in refusing to cache certain responses. git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1347627 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e8bc96c549
commit
2748f2748a
|
@ -1,5 +1,8 @@
|
|||
Changes since 4.2
|
||||
-------------------
|
||||
* [HTTPCLIENT-1202] ResponseCachingPolicy should honor explicit cache-control
|
||||
directives for other status codes
|
||||
Contributed by Jon Moore <jonm at apache.org>
|
||||
|
||||
* [HTTPCLIENT-1199] DecompressingHttpClient strips content from entity enclosing requests
|
||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||
|
|
|
@ -26,7 +26,10 @@
|
|||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
@ -54,7 +57,16 @@ class ResponseCachingPolicy {
|
|||
private final long maxObjectSizeBytes;
|
||||
private final boolean sharedCache;
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private static final Set<Integer> cacheableStatuses =
|
||||
new HashSet<Integer>(Arrays.asList(HttpStatus.SC_OK,
|
||||
HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION,
|
||||
HttpStatus.SC_MULTIPLE_CHOICES,
|
||||
HttpStatus.SC_MOVED_PERMANENTLY,
|
||||
HttpStatus.SC_GONE));
|
||||
private static final Set<Integer> uncacheableStatuses =
|
||||
new HashSet<Integer>(Arrays.asList(HttpStatus.SC_PARTIAL_CONTENT,
|
||||
HttpStatus.SC_SEE_OTHER));
|
||||
|
||||
/**
|
||||
* Define a cache policy that limits the size of things that should be stored
|
||||
* in the cache to a maximum of {@link HttpResponse} bytes in size.
|
||||
|
@ -82,30 +94,19 @@ class ResponseCachingPolicy {
|
|||
log.debug("Response was not cacheable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (response.getStatusLine().getStatusCode()) {
|
||||
case HttpStatus.SC_OK:
|
||||
case HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION:
|
||||
case HttpStatus.SC_MULTIPLE_CHOICES:
|
||||
case HttpStatus.SC_MOVED_PERMANENTLY:
|
||||
case HttpStatus.SC_GONE:
|
||||
// these response codes MAY be cached
|
||||
cacheable = true;
|
||||
log.debug("Response was cacheable");
|
||||
break;
|
||||
case HttpStatus.SC_PARTIAL_CONTENT:
|
||||
// we don't implement Range requests and hence are not
|
||||
// allowed to cache partial content
|
||||
log.debug("Response was not cacheable (Partial Content)");
|
||||
return cacheable;
|
||||
|
||||
default:
|
||||
// If the status code is not one of the recognized
|
||||
// available codes in HttpStatus Don't Cache
|
||||
log.debug("Response was not cacheable (Unknown Status code)");
|
||||
return cacheable;
|
||||
|
||||
int status = response.getStatusLine().getStatusCode();
|
||||
if (cacheableStatuses.contains(status)) {
|
||||
// these response codes MAY be cached
|
||||
cacheable = true;
|
||||
} else if (uncacheableStatuses.contains(status)) {
|
||||
return false;
|
||||
} else if (unknownStatusCode(status)) {
|
||||
// a response with an unknown status code MUST NOT be
|
||||
// cached
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Header contentLength = response.getFirstHeader(HTTP.CONTENT_LEN);
|
||||
if (contentLength != null) {
|
||||
int contentLengthValue = Integer.parseInt(contentLength.getValue());
|
||||
|
@ -148,7 +149,16 @@ class ResponseCachingPolicy {
|
|||
return (cacheable || isExplicitlyCacheable(response));
|
||||
}
|
||||
|
||||
protected boolean isExplicitlyNonCacheable(HttpResponse response) {
|
||||
private boolean unknownStatusCode(int status) {
|
||||
if (status >= 100 && status <= 101) return false;
|
||||
if (status >= 200 && status <= 206) return false;
|
||||
if (status >= 300 && status <= 307) return false;
|
||||
if (status >= 400 && status <= 417) return false;
|
||||
if (status >= 500 && status <= 505) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isExplicitlyNonCacheable(HttpResponse response) {
|
||||
Header[] cacheControlHeaders = response.getHeaders(HeaderConstants.CACHE_CONTROL);
|
||||
for (Header header : cacheControlHeaders) {
|
||||
for (HeaderElement elem : header.getElements()) {
|
||||
|
|
|
@ -459,6 +459,14 @@ public class TestResponseCachingPolicy {
|
|||
response.removeHeaders("Cache-Control");
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void otherStatusCodesAreCacheableWithExplicitCachingHeaders() {
|
||||
response.setStatusCode(HttpStatus.SC_NOT_FOUND);
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Cache-Control","max-age=300");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
private int getRandomStatus() {
|
||||
int rnd = (new Random()).nextInt(acceptableCodes.length);
|
||||
|
|
Loading…
Reference in New Issue