Reduced visibility of non-essential classes and methods to default (package private). Visibility can be increased on a case by case basis as the Cache API evolves and matures
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@964565 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c10d235ed2
commit
5a54675818
|
@ -106,23 +106,22 @@ public class CacheEntry implements Serializable {
|
|||
/**
|
||||
* Constructor used to create a copy of an existing entry, while adding another variant URI to it.
|
||||
*
|
||||
* @param toCopy CacheEntry to be duplicated
|
||||
* @param entry CacheEntry to be duplicated
|
||||
* @param variantURI URI to add
|
||||
*/
|
||||
private CacheEntry(CacheEntry toCopy, String variantURI){
|
||||
this(toCopy.getRequestDate(),
|
||||
toCopy.getResponseDate(),
|
||||
toCopy.getProtocolVersion(),
|
||||
toCopy.getAllHeaders(),
|
||||
toCopy.body,
|
||||
toCopy.getStatusCode(),
|
||||
toCopy.getReasonPhrase());
|
||||
|
||||
this.variantURIs.addAll(toCopy.getVariantURIs());
|
||||
private CacheEntry(CacheEntry entry, String variantURI){
|
||||
this(entry.getRequestDate(),
|
||||
entry.getResponseDate(),
|
||||
entry.getProtocolVersion(),
|
||||
entry.getAllHeaders(),
|
||||
entry.body,
|
||||
entry.getStatusCode(),
|
||||
entry.getReasonPhrase());
|
||||
this.variantURIs.addAll(entry.getVariantURIs());
|
||||
this.variantURIs.add(variantURI);
|
||||
}
|
||||
|
||||
public CacheEntry addVariantURI(String variantURI){
|
||||
public CacheEntry copyWithVariant(String variantURI){
|
||||
return new CacheEntry(this,variantURI);
|
||||
}
|
||||
|
||||
|
@ -162,128 +161,10 @@ public class CacheEntry implements Serializable {
|
|||
return responseHeaders.getHeaders(name);
|
||||
}
|
||||
|
||||
protected Date getDateValue() {
|
||||
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;
|
||||
}
|
||||
|
||||
protected long getContentLengthValue() {
|
||||
Header cl = getFirstHeader(HTTP.CONTENT_LEN);
|
||||
if (cl == null)
|
||||
return -1;
|
||||
|
||||
try {
|
||||
return Long.parseLong(cl.getValue());
|
||||
} catch (NumberFormatException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This matters for deciding whether the cache entry is valid to serve as a
|
||||
* response. If these values do not match, we might have a partial response
|
||||
*
|
||||
* @return boolean indicating whether actual length matches Content-Length
|
||||
*/
|
||||
protected boolean contentLengthHeaderMatchesActualLength() {
|
||||
return getContentLengthValue() == body.getContentLength();
|
||||
}
|
||||
|
||||
protected long getApparentAgeSecs() {
|
||||
Date dateValue = getDateValue();
|
||||
if (dateValue == null)
|
||||
return MAX_AGE;
|
||||
long diff = responseDate.getTime() - dateValue.getTime();
|
||||
if (diff < 0L)
|
||||
return 0;
|
||||
return (diff / 1000);
|
||||
}
|
||||
|
||||
protected long getAgeValue() {
|
||||
long ageValue = 0;
|
||||
for (Header hdr : getHeaders(HeaderConstants.AGE)) {
|
||||
long hdrAge;
|
||||
try {
|
||||
hdrAge = Long.parseLong(hdr.getValue());
|
||||
if (hdrAge < 0) {
|
||||
hdrAge = MAX_AGE;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
hdrAge = MAX_AGE;
|
||||
}
|
||||
ageValue = (hdrAge > ageValue) ? hdrAge : ageValue;
|
||||
}
|
||||
return ageValue;
|
||||
}
|
||||
|
||||
protected long getCorrectedReceivedAgeSecs() {
|
||||
long apparentAge = getApparentAgeSecs();
|
||||
long ageValue = getAgeValue();
|
||||
return (apparentAge > ageValue) ? apparentAge : ageValue;
|
||||
}
|
||||
|
||||
protected long getResponseDelaySecs() {
|
||||
long diff = responseDate.getTime() - requestDate.getTime();
|
||||
return (diff / 1000L);
|
||||
}
|
||||
|
||||
protected long getCorrectedInitialAgeSecs() {
|
||||
return getCorrectedReceivedAgeSecs() + getResponseDelaySecs();
|
||||
}
|
||||
|
||||
protected Date getCurrentDate() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
protected long getResidentTimeSecs() {
|
||||
long diff = getCurrentDate().getTime() - responseDate.getTime();
|
||||
return (diff / 1000L);
|
||||
}
|
||||
|
||||
public long getCurrentAgeSecs() {
|
||||
return getCorrectedInitialAgeSecs() + getResidentTimeSecs();
|
||||
}
|
||||
|
||||
protected long getMaxAge() {
|
||||
long maxage = -1;
|
||||
for (Header hdr : getHeaders(HeaderConstants.CACHE_CONTROL)) {
|
||||
for (HeaderElement elt : hdr.getElements()) {
|
||||
if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())
|
||||
|| "s-maxage".equals(elt.getName())) {
|
||||
try {
|
||||
long currMaxAge = Long.parseLong(elt.getValue());
|
||||
if (maxage == -1 || currMaxAge < maxage) {
|
||||
maxage = currMaxAge;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
// be conservative if can't parse
|
||||
maxage = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxage;
|
||||
}
|
||||
|
||||
protected Date getExpirationDate() {
|
||||
Header expiresHeader = getFirstHeader(HeaderConstants.EXPIRES);
|
||||
if (expiresHeader == null)
|
||||
return null;
|
||||
try {
|
||||
return DateUtils.parseDate(expiresHeader.getValue());
|
||||
} catch (DateParseException dpe) {
|
||||
// malformed expires header
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getFreshnessLifetimeSecs() {
|
||||
long maxage = getMaxAge();
|
||||
if (maxage > -1)
|
||||
|
@ -345,6 +226,146 @@ public class CacheEntry implements Serializable {
|
|||
return (getFirstHeader(HeaderConstants.VARY) != null);
|
||||
}
|
||||
|
||||
public Set<String> getVariantURIs() {
|
||||
return Collections.unmodifiableSet(this.variantURIs);
|
||||
}
|
||||
|
||||
public boolean mustRevalidate() {
|
||||
return hasCacheControlDirective("must-revalidate");
|
||||
}
|
||||
public boolean proxyRevalidate() {
|
||||
return hasCacheControlDirective("proxy-revalidate");
|
||||
}
|
||||
|
||||
Date getDateValue() {
|
||||
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;
|
||||
}
|
||||
|
||||
long getContentLengthValue() {
|
||||
Header cl = getFirstHeader(HTTP.CONTENT_LEN);
|
||||
if (cl == null)
|
||||
return -1;
|
||||
|
||||
try {
|
||||
return Long.parseLong(cl.getValue());
|
||||
} catch (NumberFormatException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This matters for deciding whether the cache entry is valid to serve as a
|
||||
* response. If these values do not match, we might have a partial response
|
||||
*
|
||||
* @return boolean indicating whether actual length matches Content-Length
|
||||
*/
|
||||
boolean contentLengthHeaderMatchesActualLength() {
|
||||
return getContentLengthValue() == body.getContentLength();
|
||||
}
|
||||
|
||||
long getApparentAgeSecs() {
|
||||
Date dateValue = getDateValue();
|
||||
if (dateValue == null)
|
||||
return MAX_AGE;
|
||||
long diff = responseDate.getTime() - dateValue.getTime();
|
||||
if (diff < 0L)
|
||||
return 0;
|
||||
return (diff / 1000);
|
||||
}
|
||||
|
||||
long getAgeValue() {
|
||||
long ageValue = 0;
|
||||
for (Header hdr : getHeaders(HeaderConstants.AGE)) {
|
||||
long hdrAge;
|
||||
try {
|
||||
hdrAge = Long.parseLong(hdr.getValue());
|
||||
if (hdrAge < 0) {
|
||||
hdrAge = MAX_AGE;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
hdrAge = MAX_AGE;
|
||||
}
|
||||
ageValue = (hdrAge > ageValue) ? hdrAge : ageValue;
|
||||
}
|
||||
return ageValue;
|
||||
}
|
||||
|
||||
long getCorrectedReceivedAgeSecs() {
|
||||
long apparentAge = getApparentAgeSecs();
|
||||
long ageValue = getAgeValue();
|
||||
return (apparentAge > ageValue) ? apparentAge : ageValue;
|
||||
}
|
||||
|
||||
long getResponseDelaySecs() {
|
||||
long diff = responseDate.getTime() - requestDate.getTime();
|
||||
return (diff / 1000L);
|
||||
}
|
||||
|
||||
long getCorrectedInitialAgeSecs() {
|
||||
return getCorrectedReceivedAgeSecs() + getResponseDelaySecs();
|
||||
}
|
||||
|
||||
Date getCurrentDate() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
long getResidentTimeSecs() {
|
||||
long diff = getCurrentDate().getTime() - responseDate.getTime();
|
||||
return (diff / 1000L);
|
||||
}
|
||||
|
||||
long getMaxAge() {
|
||||
long maxage = -1;
|
||||
for (Header hdr : getHeaders(HeaderConstants.CACHE_CONTROL)) {
|
||||
for (HeaderElement elt : hdr.getElements()) {
|
||||
if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())
|
||||
|| "s-maxage".equals(elt.getName())) {
|
||||
try {
|
||||
long currMaxAge = Long.parseLong(elt.getValue());
|
||||
if (maxage == -1 || currMaxAge < maxage) {
|
||||
maxage = currMaxAge;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
// be conservative if can't parse
|
||||
maxage = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxage;
|
||||
}
|
||||
|
||||
Date getExpirationDate() {
|
||||
Header expiresHeader = getFirstHeader(HeaderConstants.EXPIRES);
|
||||
if (expiresHeader == null)
|
||||
return null;
|
||||
try {
|
||||
return DateUtils.parseDate(expiresHeader.getValue());
|
||||
} catch (DateParseException dpe) {
|
||||
// malformed expires header
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean hasCacheControlDirective(String directive) {
|
||||
for(Header h : responseHeaders.getHeaders("Cache-Control")) {
|
||||
for(HeaderElement elt : h.getElements()) {
|
||||
if (directive.equalsIgnoreCase(elt.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
|
||||
// write CacheEntry
|
||||
|
@ -382,32 +403,10 @@ public class CacheEntry implements Serializable {
|
|||
this.responseHeaders.setHeaders(headers);
|
||||
}
|
||||
|
||||
public Set<String> getVariantURIs() {
|
||||
return Collections.unmodifiableSet(this.variantURIs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[request date=" + requestDate + "; response date=" + responseDate
|
||||
+ "; status=" + status + "]";
|
||||
}
|
||||
|
||||
protected boolean hasCacheControlDirective(String directive) {
|
||||
for(Header h : responseHeaders.getHeaders("Cache-Control")) {
|
||||
for(HeaderElement elt : h.getElements()) {
|
||||
if (directive.equalsIgnoreCase(elt.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean mustRevalidate() {
|
||||
return hasCacheControlDirective("must-revalidate");
|
||||
}
|
||||
public boolean proxyRevalidate() {
|
||||
return hasCacheControlDirective("proxy-revalidate");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,13 +37,14 @@ import org.apache.http.annotation.Immutable;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class CacheEntryGenerator {
|
||||
class CacheEntryGenerator {
|
||||
|
||||
public CacheEntry generateEntry(Date requestDate, Date responseDate, HttpResponse response,
|
||||
public CacheEntry generateEntry(
|
||||
Date requestDate,
|
||||
Date responseDate,
|
||||
HttpResponse response,
|
||||
byte[] body) {
|
||||
|
||||
CacheEntity entity = new CacheEntity(body, response);
|
||||
|
||||
return new CacheEntry(requestDate,
|
||||
responseDate,
|
||||
response.getProtocolVersion(),
|
||||
|
|
|
@ -48,7 +48,7 @@ import org.apache.http.protocol.HTTP;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class CacheEntryUpdater {
|
||||
class CacheEntryUpdater {
|
||||
|
||||
/**
|
||||
* Update the entry with the new information from the response.
|
||||
|
|
|
@ -46,7 +46,7 @@ import org.apache.http.client.cache.HttpCacheOperationException;
|
|||
* @since 4.1
|
||||
*/
|
||||
@ThreadSafe // so long as the cache implementation is thread-safe
|
||||
public class CacheInvalidator {
|
||||
class CacheInvalidator {
|
||||
|
||||
private final HttpCache<String, CacheEntry> cache;
|
||||
private final URIExtractor uriExtractor;
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
import org.apache.http.Header;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
|
||||
|
@ -40,7 +41,7 @@ import org.apache.http.annotation.Immutable;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class CacheableRequestPolicy {
|
||||
class CacheableRequestPolicy {
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
|
@ -55,7 +56,7 @@ public class CacheableRequestPolicy {
|
|||
String method = request.getRequestLine().getMethod();
|
||||
|
||||
ProtocolVersion pv = request.getRequestLine().getProtocolVersion();
|
||||
if (CachingHttpClient.HTTP_1_1.compareToVersion(pv) != 0) {
|
||||
if (HttpVersion.HTTP_1_1.compareToVersion(pv) != 0) {
|
||||
log.debug("Request was not serveable from cache");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ import java.io.Serializable;
|
|||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.message.HeaderGroup;
|
||||
|
||||
/**
|
||||
*/
|
||||
@NotThreadSafe // because HeaderGroup is @NotThreadSafe
|
||||
public class CachedHeaderGroup extends HeaderGroup implements Serializable {
|
||||
class CachedHeaderGroup extends HeaderGroup implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4572663568087431896L;
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.http.Header;
|
|||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
|
@ -41,7 +42,7 @@ import org.apache.http.protocol.HTTP;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class CachedHttpResponseGenerator {
|
||||
class CachedHttpResponseGenerator {
|
||||
|
||||
/**
|
||||
* If I was able to use a {@link CacheEntry} to response to the {@link org.apache.http.HttpRequest} then
|
||||
|
@ -52,7 +53,7 @@ public class CachedHttpResponseGenerator {
|
|||
*/
|
||||
HttpResponse generateResponse(CacheEntry entry) {
|
||||
|
||||
HttpResponse response = new BasicHttpResponse(CachingHttpClient.HTTP_1_1, entry
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, entry
|
||||
.getStatusCode(), entry.getReasonPhrase());
|
||||
|
||||
if (entry.getStatusCode() != HttpStatus.SC_NOT_MODIFIED) {
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.apache.http.annotation.Immutable;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class CachedResponseSuitabilityChecker {
|
||||
class CachedResponseSuitabilityChecker {
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ import org.apache.http.HttpHost;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolException;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.RequestLine;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.annotation.ThreadSafe;
|
||||
|
@ -68,10 +68,12 @@ public class CachingHttpClient implements HttpClient {
|
|||
private final static int MAX_CACHE_ENTRIES = 1000;
|
||||
private final static int DEFAULT_MAX_OBJECT_SIZE_BYTES = 8192;
|
||||
|
||||
public static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1);
|
||||
|
||||
private final static boolean SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS = false;
|
||||
|
||||
private final AtomicLong cacheHits = new AtomicLong();
|
||||
private final AtomicLong cacheMisses = new AtomicLong();
|
||||
private final AtomicLong cacheUpdates = new AtomicLong();
|
||||
|
||||
private final HttpClient backend;
|
||||
private final ResponseCachingPolicy responseCachingPolicy;
|
||||
private final CacheEntryGenerator cacheEntryGenerator;
|
||||
|
@ -86,53 +88,14 @@ public class CachingHttpClient implements HttpClient {
|
|||
private final int maxObjectSizeBytes;
|
||||
private final CacheEntryUpdater cacheEntryUpdater;
|
||||
|
||||
private AtomicLong cacheHits = new AtomicLong();
|
||||
private AtomicLong cacheMisses = new AtomicLong();
|
||||
private AtomicLong cacheUpdates = new AtomicLong();
|
||||
|
||||
private final ResponseProtocolCompliance responseCompliance;
|
||||
private final RequestProtocolCompliance requestCompliance;
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
public CachingHttpClient() {
|
||||
this.backend = new DefaultHttpClient();
|
||||
this.maxObjectSizeBytes = DEFAULT_MAX_OBJECT_SIZE_BYTES;
|
||||
this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes);
|
||||
this.cacheEntryGenerator = new CacheEntryGenerator();
|
||||
this.uriExtractor = new URIExtractor();
|
||||
this.responseCache = new BasicHttpCache(MAX_CACHE_ENTRIES);
|
||||
this.responseGenerator = new CachedHttpResponseGenerator();
|
||||
this.cacheInvalidator = new CacheInvalidator(this.uriExtractor, this.responseCache);
|
||||
this.cacheableRequestPolicy = new CacheableRequestPolicy();
|
||||
this.suitabilityChecker = new CachedResponseSuitabilityChecker();
|
||||
this.conditionalRequestBuilder = new ConditionalRequestBuilder();
|
||||
this.cacheEntryUpdater = new CacheEntryUpdater();
|
||||
this.responseCompliance = new ResponseProtocolCompliance();
|
||||
this.requestCompliance = new RequestProtocolCompliance();
|
||||
}
|
||||
|
||||
public CachingHttpClient(HttpCache<String, CacheEntry> cache, int maxObjectSizeBytes) {
|
||||
this.responseCache = cache;
|
||||
|
||||
this.backend = new DefaultHttpClient();
|
||||
this.maxObjectSizeBytes = maxObjectSizeBytes;
|
||||
this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes);
|
||||
this.cacheEntryGenerator = new CacheEntryGenerator();
|
||||
this.uriExtractor = new URIExtractor();
|
||||
this.responseGenerator = new CachedHttpResponseGenerator();
|
||||
this.cacheInvalidator = new CacheInvalidator(this.uriExtractor, this.responseCache);
|
||||
this.cacheableRequestPolicy = new CacheableRequestPolicy();
|
||||
this.suitabilityChecker = new CachedResponseSuitabilityChecker();
|
||||
this.conditionalRequestBuilder = new ConditionalRequestBuilder();
|
||||
this.cacheEntryUpdater = new CacheEntryUpdater();
|
||||
this.responseCompliance = new ResponseProtocolCompliance();
|
||||
this.requestCompliance = new RequestProtocolCompliance();
|
||||
}
|
||||
|
||||
public CachingHttpClient(HttpClient client, HttpCache<String, CacheEntry> cache, int maxObjectSizeBytes) {
|
||||
super();
|
||||
this.responseCache = cache;
|
||||
|
||||
this.backend = client;
|
||||
this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes);
|
||||
this.cacheEntryGenerator = new CacheEntryGenerator();
|
||||
|
@ -148,7 +111,15 @@ public class CachingHttpClient implements HttpClient {
|
|||
this.requestCompliance = new RequestProtocolCompliance();
|
||||
}
|
||||
|
||||
public CachingHttpClient(HttpClient backend, ResponseCachingPolicy responseCachingPolicy,
|
||||
public CachingHttpClient() {
|
||||
this(new DefaultHttpClient(), new BasicHttpCache(MAX_CACHE_ENTRIES), DEFAULT_MAX_OBJECT_SIZE_BYTES);
|
||||
}
|
||||
|
||||
public CachingHttpClient(HttpCache<String, CacheEntry> cache, int maxObjectSizeBytes) {
|
||||
this(new DefaultHttpClient(), cache, maxObjectSizeBytes);
|
||||
}
|
||||
|
||||
CachingHttpClient(HttpClient backend, ResponseCachingPolicy responseCachingPolicy,
|
||||
CacheEntryGenerator cacheEntryGenerator, URIExtractor uriExtractor,
|
||||
HttpCache<String, CacheEntry> responseCache, CachedHttpResponseGenerator responseGenerator,
|
||||
CacheInvalidator cacheInvalidator, CacheableRequestPolicy cacheableRequestPolicy,
|
||||
|
@ -323,30 +294,6 @@ public class CachingHttpClient implements HttpClient {
|
|||
return backend.getParams();
|
||||
}
|
||||
|
||||
protected Date getCurrentDate() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
protected CacheEntry getCacheEntry(HttpHost target, HttpRequest request) {
|
||||
String uri = uriExtractor.getURI(target, request);
|
||||
CacheEntry entry = null;
|
||||
try {
|
||||
entry = responseCache.getEntry(uri);
|
||||
} catch (HttpCacheOperationException ex) {
|
||||
log.debug("Was unable to get an entry from the cache based on the uri provided", ex);
|
||||
}
|
||||
|
||||
if (entry == null || !entry.hasVariants())
|
||||
return entry;
|
||||
|
||||
String variantUri = uriExtractor.getVariantURI(target, request, entry);
|
||||
try {
|
||||
return responseCache.getEntry(variantUri);
|
||||
} catch (HttpCacheOperationException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target the target host for the request.
|
||||
* Implementations may accept <code>null</code>
|
||||
|
@ -413,7 +360,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
} catch (IOException ioex) {
|
||||
if (entry.mustRevalidate()
|
||||
|| (isSharedCache() && entry.proxyRevalidate())) {
|
||||
return new BasicHttpResponse(HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout");
|
||||
return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout");
|
||||
} else {
|
||||
HttpResponse response = responseGenerator.generateResponse(entry);
|
||||
response.addHeader(HeaderConstants.WARNING, "111 Revalidation Failed - " + ioex.getMessage());
|
||||
|
@ -427,7 +374,39 @@ public class CachingHttpClient implements HttpClient {
|
|||
return callBackend(target, request, context);
|
||||
}
|
||||
|
||||
private boolean clientRequestsOurOptions(HttpRequest request) {
|
||||
public boolean supportsRangeAndContentRangeHeaders() {
|
||||
return SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS;
|
||||
}
|
||||
|
||||
public boolean isSharedCache() {
|
||||
return true;
|
||||
}
|
||||
|
||||
Date getCurrentDate() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
CacheEntry getCacheEntry(HttpHost target, HttpRequest request) {
|
||||
String uri = uriExtractor.getURI(target, request);
|
||||
CacheEntry entry = null;
|
||||
try {
|
||||
entry = responseCache.getEntry(uri);
|
||||
} catch (HttpCacheOperationException ex) {
|
||||
log.debug("Was unable to get an entry from the cache based on the uri provided", ex);
|
||||
}
|
||||
|
||||
if (entry == null || !entry.hasVariants())
|
||||
return entry;
|
||||
|
||||
String variantUri = uriExtractor.getVariantURI(target, request, entry);
|
||||
try {
|
||||
return responseCache.getEntry(variantUri);
|
||||
} catch (HttpCacheOperationException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean clientRequestsOurOptions(HttpRequest request) {
|
||||
RequestLine line = request.getRequestLine();
|
||||
|
||||
if (!HeaderConstants.OPTIONS_METHOD.equals(line.getMethod()))
|
||||
|
@ -442,7 +421,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected HttpResponse callBackend(HttpHost target, HttpRequest request, HttpContext context)
|
||||
HttpResponse callBackend(HttpHost target, HttpRequest request, HttpContext context)
|
||||
throws IOException {
|
||||
|
||||
Date requestDate = getCurrentDate();
|
||||
|
@ -455,14 +434,14 @@ public class CachingHttpClient implements HttpClient {
|
|||
} catch (ClientProtocolException cpex) {
|
||||
throw cpex;
|
||||
} catch (IOException ex) {
|
||||
StatusLine status = new BasicStatusLine(HTTP_1_1, HttpStatus.SC_SERVICE_UNAVAILABLE, ex
|
||||
StatusLine status = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_SERVICE_UNAVAILABLE, ex
|
||||
.getMessage());
|
||||
return new BasicHttpResponse(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected HttpResponse revalidateCacheEntry(
|
||||
HttpResponse revalidateCacheEntry(
|
||||
HttpHost target,
|
||||
HttpRequest request,
|
||||
HttpContext context,
|
||||
|
@ -486,7 +465,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
backendResponse);
|
||||
}
|
||||
|
||||
protected void storeInCache(HttpHost target, HttpRequest request, CacheEntry entry) {
|
||||
void storeInCache(HttpHost target, HttpRequest request, CacheEntry entry) {
|
||||
if (entry.hasVariants()) {
|
||||
storeVariantEntry(target, request, entry);
|
||||
} else {
|
||||
|
@ -494,7 +473,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
private void storeNonVariantEntry(HttpHost target, HttpRequest req, CacheEntry entry) {
|
||||
void storeNonVariantEntry(HttpHost target, HttpRequest req, CacheEntry entry) {
|
||||
String uri = uriExtractor.getURI(target, req);
|
||||
try {
|
||||
responseCache.putEntry(uri, entry);
|
||||
|
@ -503,7 +482,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
protected void storeVariantEntry(
|
||||
void storeVariantEntry(
|
||||
final HttpHost target,
|
||||
final HttpRequest req,
|
||||
final CacheEntry entry) {
|
||||
|
@ -529,17 +508,17 @@ public class CachingHttpClient implements HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
protected CacheEntry doGetUpdatedParentEntry(
|
||||
CacheEntry doGetUpdatedParentEntry(
|
||||
CacheEntry existing,
|
||||
CacheEntry entry, String variantURI) throws HttpCacheOperationException {
|
||||
if (existing != null) {
|
||||
return existing.addVariantURI(variantURI);
|
||||
return existing.copyWithVariant(variantURI);
|
||||
} else {
|
||||
return entry.addVariantURI(variantURI);
|
||||
return entry.copyWithVariant(variantURI);
|
||||
}
|
||||
}
|
||||
|
||||
protected HttpResponse correctIncompleteResponse(HttpResponse resp,
|
||||
HttpResponse correctIncompleteResponse(HttpResponse resp,
|
||||
byte[] bodyBytes) {
|
||||
int status = resp.getStatusLine().getStatusCode();
|
||||
if (status != HttpStatus.SC_OK
|
||||
|
@ -556,7 +535,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
}
|
||||
if (bodyBytes.length >= contentLength) return resp;
|
||||
HttpResponse error =
|
||||
new BasicHttpResponse(HTTP_1_1, HttpStatus.SC_BAD_GATEWAY, "Bad Gateway");
|
||||
new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_BAD_GATEWAY, "Bad Gateway");
|
||||
error.setHeader("Content-Type","text/plain;charset=UTF-8");
|
||||
String msg = String.format("Received incomplete response with Content-Length %d but actual body length %d", contentLength, bodyBytes.length);
|
||||
byte[] msgBytes = msg.getBytes();
|
||||
|
@ -565,7 +544,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
return error;
|
||||
}
|
||||
|
||||
protected HttpResponse handleBackendResponse(
|
||||
HttpResponse handleBackendResponse(
|
||||
HttpHost target,
|
||||
HttpRequest request,
|
||||
Date requestDate,
|
||||
|
@ -608,16 +587,8 @@ public class CachingHttpClient implements HttpClient {
|
|||
return corrected;
|
||||
}
|
||||
|
||||
protected SizeLimitedResponseReader getResponseReader(HttpResponse backEndResponse) {
|
||||
SizeLimitedResponseReader getResponseReader(HttpResponse backEndResponse) {
|
||||
return new SizeLimitedResponseReader(maxObjectSizeBytes, backEndResponse);
|
||||
}
|
||||
|
||||
public boolean supportsRangeAndContentRangeHeaders() {
|
||||
return SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS;
|
||||
}
|
||||
|
||||
public boolean isSharedCache() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import org.apache.http.impl.client.RequestWrapper;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class ConditionalRequestBuilder {
|
||||
class ConditionalRequestBuilder {
|
||||
|
||||
/**
|
||||
* When a {@link CacheEntry} is stale but 'might' be used as a response
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.apache.http.annotation.Immutable;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class HeaderConstants {
|
||||
class HeaderConstants {
|
||||
|
||||
public static final String GET_METHOD = "GET";
|
||||
public static final String HEAD_METHOD = "HEAD";
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.http.HeaderIterator;
|
|||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
|
@ -45,11 +46,11 @@ import org.apache.http.params.HttpParams;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public final class OptionsHttp11Response extends AbstractHttpMessage implements HttpResponse {
|
||||
final class OptionsHttp11Response extends AbstractHttpMessage implements HttpResponse {
|
||||
|
||||
private final StatusLine statusLine = new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
private final StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1,
|
||||
HttpStatus.SC_NOT_IMPLEMENTED, "");
|
||||
private final ProtocolVersion version = CachingHttpClient.HTTP_1_1;
|
||||
private final ProtocolVersion version = HttpVersion.HTTP_1_1;
|
||||
|
||||
public StatusLine getStatusLine() {
|
||||
return statusLine;
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.http.HttpEntityEnclosingRequest;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolException;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
|
@ -49,7 +50,7 @@ import org.apache.http.protocol.HTTP;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class RequestProtocolCompliance {
|
||||
class RequestProtocolCompliance {
|
||||
|
||||
/**
|
||||
* Test to see if the {@link HttpRequest} is HTTP1.1 compliant or not
|
||||
|
@ -102,11 +103,11 @@ public class RequestProtocolCompliance {
|
|||
decrementOPTIONSMaxForwardsIfGreaterThen0(request);
|
||||
|
||||
if (requestVersionIsTooLow(request)) {
|
||||
return upgradeRequestTo(request, CachingHttpClient.HTTP_1_1);
|
||||
return upgradeRequestTo(request, HttpVersion.HTTP_1_1);
|
||||
}
|
||||
|
||||
if (requestMinorVersionIsTooHighMajorVersionsMatch(request)) {
|
||||
return downgradeRequestTo(request, CachingHttpClient.HTTP_1_1);
|
||||
return downgradeRequestTo(request, HttpVersion.HTTP_1_1);
|
||||
}
|
||||
|
||||
return request;
|
||||
|
@ -227,11 +228,11 @@ public class RequestProtocolCompliance {
|
|||
|
||||
protected boolean requestMinorVersionIsTooHighMajorVersionsMatch(HttpRequest request) {
|
||||
ProtocolVersion requestProtocol = request.getProtocolVersion();
|
||||
if (requestProtocol.getMajor() != CachingHttpClient.HTTP_1_1.getMajor()) {
|
||||
if (requestProtocol.getMajor() != HttpVersion.HTTP_1_1.getMajor()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (requestProtocol.getMinor() > CachingHttpClient.HTTP_1_1.getMinor()) {
|
||||
if (requestProtocol.getMinor() > HttpVersion.HTTP_1_1.getMinor()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -239,7 +240,7 @@ public class RequestProtocolCompliance {
|
|||
}
|
||||
|
||||
protected boolean requestVersionIsTooLow(HttpRequest request) {
|
||||
return request.getProtocolVersion().compareToVersion(CachingHttpClient.HTTP_1_1) < 0;
|
||||
return request.getProtocolVersion().compareToVersion(HttpVersion.HTTP_1_1) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -252,20 +253,20 @@ public class RequestProtocolCompliance {
|
|||
public HttpResponse getErrorForRequest(RequestProtocolError errorCheck) {
|
||||
switch (errorCheck) {
|
||||
case BODY_BUT_NO_LENGTH_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1,
|
||||
HttpStatus.SC_LENGTH_REQUIRED, ""));
|
||||
|
||||
case WEAK_ETAG_AND_RANGE_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1,
|
||||
HttpStatus.SC_BAD_REQUEST, "Weak eTag not compatible with byte range"));
|
||||
|
||||
case WEAK_ETAG_ON_PUTDELETE_METHOD_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1,
|
||||
HttpStatus.SC_BAD_REQUEST,
|
||||
"Weak eTag not compatible with PUT or DELETE requests"));
|
||||
|
||||
case NO_CACHE_DIRECTIVE_WITH_FIELD_NAME:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1,
|
||||
HttpStatus.SC_BAD_REQUEST,
|
||||
"No-Cache directive MUST NOT include a field name"));
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.http.HttpMessage;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.impl.cookie.DateParseException;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
|
@ -45,7 +46,7 @@ import org.apache.http.protocol.HTTP;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class ResponseCachingPolicy {
|
||||
class ResponseCachingPolicy {
|
||||
|
||||
private final int maxObjectSizeBytes;
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
@ -213,7 +214,7 @@ public class ResponseCachingPolicy {
|
|||
}
|
||||
|
||||
private boolean requestProtocolGreaterThanAccepted(HttpRequest req) {
|
||||
return req.getProtocolVersion().compareToVersion(CachingHttpClient.HTTP_1_1) > 0;
|
||||
return req.getProtocolVersion().compareToVersion(HttpVersion.HTTP_1_1) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.http.HttpEntityEnclosingRequest;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
|
@ -43,7 +44,7 @@ import org.apache.http.protocol.HTTP;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class ResponseProtocolCompliance {
|
||||
class ResponseProtocolCompliance {
|
||||
|
||||
/**
|
||||
* When we get a response from a down stream server (Origin Server)
|
||||
|
@ -160,7 +161,7 @@ public class ResponseProtocolCompliance {
|
|||
|
||||
ProtocolVersion originalProtocol = getOriginalRequestProtocol((RequestWrapper) request);
|
||||
|
||||
if (originalProtocol.compareToVersion(CachingHttpClient.HTTP_1_1) >= 0) {
|
||||
if (originalProtocol.compareToVersion(HttpVersion.HTTP_1_1) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -178,7 +179,7 @@ public class ResponseProtocolCompliance {
|
|||
|
||||
ProtocolVersion originalProtocol = getOriginalRequestProtocol((RequestWrapper) request);
|
||||
|
||||
if (originalProtocol.compareToVersion(CachingHttpClient.HTTP_1_1) >= 0) {
|
||||
if (originalProtocol.compareToVersion(HttpVersion.HTTP_1_1) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ import org.apache.http.message.BasicHttpResponse;
|
|||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public class SizeLimitedResponseReader {
|
||||
class SizeLimitedResponseReader {
|
||||
|
||||
private final int maxResponseSizeBytes;
|
||||
private final HttpResponse response;
|
||||
|
|
|
@ -43,7 +43,7 @@ import org.apache.http.protocol.HTTP;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class URIExtractor {
|
||||
class URIExtractor {
|
||||
|
||||
/**
|
||||
* For a given {@link HttpHost} and {@link HttpRequest} get a URI from the
|
||||
|
|
|
@ -429,8 +429,8 @@ public class TestCacheEntry {
|
|||
Header[] headers = new Header[]{};
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
CacheEntry addedOne = entry.addVariantURI("foo");
|
||||
CacheEntry addedTwo = addedOne.addVariantURI("bar");
|
||||
CacheEntry addedOne = entry.copyWithVariant("foo");
|
||||
CacheEntry addedTwo = addedOne.copyWithVariant("bar");
|
||||
|
||||
Set<String> variants = addedTwo.getVariantURIs();
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.http.Header;
|
|||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolException;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
|
@ -123,7 +124,7 @@ public class TestConditionalRequestBuilder {
|
|||
|
||||
@Test
|
||||
public void testCacheEntryWithMustRevalidateDoesEndToEndRevalidation() throws Exception {
|
||||
HttpRequest request = new BasicHttpRequest("GET","/",CachingHttpClient.HTTP_1_1);
|
||||
HttpRequest request = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
|
||||
Date now = new Date();
|
||||
Date elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
|
@ -134,7 +135,7 @@ public class TestConditionalRequestBuilder {
|
|||
new BasicHeader("ETag", "\"etag\""),
|
||||
new BasicHeader("Cache-Control","max-age=5, must-revalidate") };
|
||||
CacheEntry cacheEntry = new CacheEntry(elevenSecondsAgo, nineSecondsAgo,
|
||||
CachingHttpClient.HTTP_1_1, cacheEntryHeaders, new ByteArrayEntity(new byte[0]),
|
||||
HttpVersion.HTTP_1_1, cacheEntryHeaders, new ByteArrayEntity(new byte[0]),
|
||||
HttpStatus.SC_OK, "OK");
|
||||
|
||||
HttpRequest result = impl.buildConditionalRequest(request, cacheEntry);
|
||||
|
@ -153,7 +154,7 @@ public class TestConditionalRequestBuilder {
|
|||
|
||||
@Test
|
||||
public void testCacheEntryWithProxyRevalidateDoesEndToEndRevalidation() throws Exception {
|
||||
HttpRequest request = new BasicHttpRequest("GET","/",CachingHttpClient.HTTP_1_1);
|
||||
HttpRequest request = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
|
||||
Date now = new Date();
|
||||
Date elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
|
@ -164,7 +165,7 @@ public class TestConditionalRequestBuilder {
|
|||
new BasicHeader("ETag", "\"etag\""),
|
||||
new BasicHeader("Cache-Control","max-age=5, proxy-revalidate") };
|
||||
CacheEntry cacheEntry = new CacheEntry(elevenSecondsAgo, nineSecondsAgo,
|
||||
CachingHttpClient.HTTP_1_1, cacheEntryHeaders, new ByteArrayEntity(new byte[0]),
|
||||
HttpVersion.HTTP_1_1, cacheEntryHeaders, new ByteArrayEntity(new byte[0]),
|
||||
HttpStatus.SC_OK, "OK");
|
||||
|
||||
HttpRequest result = impl.buildConditionalRequest(request, cacheEntry);
|
||||
|
|
Loading…
Reference in New Issue