diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java --- httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java 2010-09-11 08:32:14.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java 2010-09-11 17:10:28.000000000 -0400 @@ -36,12 +36,16 @@ import java.util.Set; import org.apache.http.Header; +import org.apache.http.HeaderElement; 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.BasicHeader; import org.apache.http.message.HeaderGroup; +import org.apache.http.protocol.HTTP; /** * Structure used to store an {@link HttpResponse} in a cache. Some entries can optionally depend @@ -63,6 +67,8 @@ private final Resource resource; private final Set variantURIs; + public static final long MAX_AGE = 2147483648L; + /** * Create a new {@link HttpCacheEntry} * @@ -200,4 +206,199 @@ + "; statusLine=" + this.statusLine + "]"; } + private long getMinDeltaSeconds(String directive) { + long min = -1; + for(Header hdr : getHeaders(HeaderConstants.CACHE_CONTROL)) { + for(HeaderElement elt : hdr.getElements()) { + if (directive.equals(elt.getName())) { + String val = elt.getValue(); + if (val != null && !"".equals(val.trim())) { + try { + long l = Long.parseLong(val); + if (l >= 0 && (min == -1 || l < min)) { + min = l; + } + } catch (NumberFormatException nfe) { + // ignore what we can't understand + } + } + } + } + } + return min; + } + + long getMaxAge(boolean sharedCache) { + if (sharedCache) { + long smaxage = getMinDeltaSeconds("s-maxage"); + if (smaxage >= 0) return smaxage; + } + return getMinDeltaSeconds("max-age"); + } + + Date getExpirationDate() { + Header expiresHeader = getFirstHeader(HeaderConstants.EXPIRES); + if (expiresHeader == null) + return null; + try { + return DateUtils.parseDate(expiresHeader.getValue()); + } catch (DateParseException dpe) { + // malformed expires header; must treat as stale + return getDateValue(); + } + } + + public boolean isRevalidatable() { + return getFirstHeader(HeaderConstants.ETAG) != null + || getFirstHeader(HeaderConstants.LAST_MODIFIED) != null; + } + + 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; + } + + private boolean hasCacheControlDirective(final String directive) { + for (Header h : getHeaders("Cache-Control")) { + for(HeaderElement elt : h.getElements()) { + if (directive.equalsIgnoreCase(elt.getName())) { + return true; + } + } + } + return false; + } + + boolean mustRevalidate() { + return hasCacheControlDirective("must-revalidate"); + } + + 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; + } + } + + public long getApparentAgeSecs() { + Date dateValue = getDateValue(); + if (dateValue == null) + return HttpCacheEntry.MAX_AGE; + long diff = responseDate.getTime() - dateValue.getTime(); + if (diff < 0L) + return 0; + return (diff / 1000); + } + + /** + * 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 + */ + public boolean contentLengthHeaderMatchesActualLength() { + return (getContentLengthValue() == resource.length()); + } + + public long getCorrectedReceivedAgeSecs() { + long apparentAge = getApparentAgeSecs(); + long ageValue = getAgeValue(); + return (apparentAge > ageValue) ? apparentAge : ageValue; + } + + public long getResponseDelaySecs() { + long diff = getResponseDate().getTime() - getRequestDate().getTime(); + return (diff / 1000L); + } + + public long getCorrectedInitialAgeSecs() { + return getCorrectedReceivedAgeSecs() + getResponseDelaySecs(); + } + + public long getResidentTimeSecs(Date currentDate) { + long diff = currentDate.getTime() - responseDate.getTime(); + return (diff / 1000L); + } + + public long getCurrentAgeSecs(Date currentDate) { + return getCorrectedInitialAgeSecs() + getResidentTimeSecs(currentDate); + } + + public long getFreshnessLifetimeSecs(boolean sharedCache) { + long maxage = getMaxAge(sharedCache); + if (maxage > -1) return maxage; + + Date dateValue = getDateValue(); + if (dateValue == null) return 0L; + + Date expiry = getExpirationDate(); + if (expiry == null) return 0L; + + long diff = expiry.getTime() - dateValue.getTime(); + if (diff < 0L) return 0L; + return (diff / 1000); + } + + public boolean isStale(Date now, boolean sharedCache) { + return (getCurrentAgeSecs(now) >= getFreshnessLifetimeSecs(sharedCache)); + } + + public long getRemainingFreshnessSecs(Date now, boolean sharedCache) { + long freshness = (getFreshnessLifetimeSecs(sharedCache) - getCurrentAgeSecs(now)); + return (freshness >= 0L) ? freshness : 0L; + } + + public long getStalenessSecs(Date now, boolean sharedCache) { + final long staleness = getCurrentAgeSecs(now) - getFreshnessLifetimeSecs(sharedCache); + return (staleness >= 0L) ? staleness : 0L; + } + + public boolean originInsistsOnFreshness(boolean sharedCache) { + return (mustRevalidate() + || (sharedCache && proxyRevalidate()) + || (sharedCache && getMinDeltaSeconds("s-maxage") != -1)); + } + + public Date getLastModified() { + Header lastModified = getFirstHeader("Last-Modified"); + if (lastModified == null) return null; + try { + return DateUtils.parseDate(lastModified.getValue()); + } catch (DateParseException dpe) { + return null; + } + } } diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java --- httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java 2010-09-11 08:32:16.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java 1969-12-31 19:00:00.000000000 -0500 @@ -1,241 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ -package org.apache.http.impl.client.cache; - -import java.util.Date; - -import org.apache.http.Header; -import org.apache.http.HeaderElement; -import org.apache.http.HttpRequest; -import org.apache.http.annotation.Immutable; -import org.apache.http.client.cache.HeaderConstants; -import org.apache.http.client.cache.HttpCacheEntry; -import org.apache.http.impl.cookie.DateParseException; -import org.apache.http.impl.cookie.DateUtils; -import org.apache.http.protocol.HTTP; - -/** - * @since 4.1 - */ -@Immutable -class CacheValidityPolicy { - - public static final long MAX_AGE = 2147483648L; - - CacheValidityPolicy() { - super(); - } - - public long getCurrentAgeSecs(final HttpCacheEntry entry) { - return getCorrectedInitialAgeSecs(entry) + getResidentTimeSecs(entry); - } - - public long getFreshnessLifetimeSecs(final HttpCacheEntry entry) { - long maxage = getMaxAge(entry); - if (maxage > -1) - return maxage; - - Date dateValue = getDateValue(entry); - if (dateValue == null) - return 0L; - - Date expiry = getExpirationDate(entry); - if (expiry == null) - return 0; - long diff = expiry.getTime() - dateValue.getTime(); - return (diff / 1000); - } - - public boolean isResponseFresh(final HttpCacheEntry entry) { - return (getCurrentAgeSecs(entry) < getFreshnessLifetimeSecs(entry)); - } - - public boolean isRevalidatable(final HttpCacheEntry entry) { - return entry.getFirstHeader(HeaderConstants.ETAG) != null - || entry.getFirstHeader(HeaderConstants.LAST_MODIFIED) != null; - } - - public boolean modifiedSince(final HttpCacheEntry entry, final HttpRequest request) { - Header unmodHeader = request.getFirstHeader(HeaderConstants.IF_UNMODIFIED_SINCE); - - if (unmodHeader == null) { - return false; - } - - try { - Date unmodifiedSinceDate = DateUtils.parseDate(unmodHeader.getValue()); - Date lastModifiedDate = DateUtils.parseDate(entry.getFirstHeader( - HeaderConstants.LAST_MODIFIED).getValue()); - - if (unmodifiedSinceDate.before(lastModifiedDate)) { - return true; - } - } catch (DateParseException e) { - return false; - } - - return false; - } - - public boolean mustRevalidate(final HttpCacheEntry entry) { - return hasCacheControlDirective(entry, "must-revalidate"); - } - - public boolean proxyRevalidate(final HttpCacheEntry entry) { - return hasCacheControlDirective(entry, "proxy-revalidate"); - } - - 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; - } - - protected long getContentLengthValue(final HttpCacheEntry entry) { - Header cl = entry.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(final HttpCacheEntry entry) { - return getContentLengthValue(entry) == entry.getResource().length(); - } - - protected long getApparentAgeSecs(final HttpCacheEntry entry) { - Date dateValue = getDateValue(entry); - if (dateValue == null) - return MAX_AGE; - long diff = entry.getResponseDate().getTime() - dateValue.getTime(); - if (diff < 0L) - return 0; - return (diff / 1000); - } - - protected long getAgeValue(final HttpCacheEntry entry) { - long ageValue = 0; - for (Header hdr : entry.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(final HttpCacheEntry entry) { - long apparentAge = getApparentAgeSecs(entry); - long ageValue = getAgeValue(entry); - return (apparentAge > ageValue) ? apparentAge : ageValue; - } - - protected long getResponseDelaySecs(final HttpCacheEntry entry) { - long diff = entry.getResponseDate().getTime() - entry.getRequestDate().getTime(); - return (diff / 1000L); - } - - protected long getCorrectedInitialAgeSecs(final HttpCacheEntry entry) { - return getCorrectedReceivedAgeSecs(entry) + getResponseDelaySecs(entry); - } - - protected Date getCurrentDate() { - return new Date(); - } - - protected long getResidentTimeSecs(final HttpCacheEntry entry) { - long diff = getCurrentDate().getTime() - entry.getResponseDate().getTime(); - return (diff / 1000L); - } - - protected long getMaxAge(final HttpCacheEntry entry) { - long maxage = -1; - for (Header hdr : entry.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(final HttpCacheEntry entry) { - Header expiresHeader = entry.getFirstHeader(HeaderConstants.EXPIRES); - if (expiresHeader == null) - return null; - try { - return DateUtils.parseDate(expiresHeader.getValue()); - } catch (DateParseException dpe) { - // malformed expires header - } - return null; - } - - protected boolean hasCacheControlDirective(final HttpCacheEntry entry, final String directive) { - for (Header h : entry.getHeaders("Cache-Control")) { - for(HeaderElement elt : h.getElements()) { - if (directive.equalsIgnoreCase(elt.getName())) { - return true; - } - } - } - return false; - } - -} diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java --- httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java 2010-09-11 08:32:16.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java 2010-09-11 17:10:28.000000000 -0400 @@ -26,6 +26,8 @@ */ package org.apache.http.impl.client.cache; +import java.util.Date; + import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -46,17 +48,14 @@ @Immutable class CachedHttpResponseGenerator { - private final CacheValidityPolicy validityStrategy; - - CachedHttpResponseGenerator(final CacheValidityPolicy validityStrategy) { + CachedHttpResponseGenerator() { super(); - this.validityStrategy = validityStrategy; } - CachedHttpResponseGenerator() { - this(new CacheValidityPolicy()); + protected Date getCurrentDate() { + return new Date(); } - + /** * If I was able to use a {@link CacheEntry} to response to the {@link org.apache.http.HttpRequest} then * generate an {@link HttpResponse} based on the cache entry. @@ -76,7 +75,7 @@ response.setEntity(entity); } - long age = this.validityStrategy.getCurrentAgeSecs(entry); + long age = entry.getCurrentAgeSecs(getCurrentDate()); if (age > 0) { if (age >= Integer.MAX_VALUE) { response.setHeader(HeaderConstants.AGE, "2147483648"); @@ -84,7 +83,7 @@ response.setHeader(HeaderConstants.AGE, "" + ((int) age)); } } - + return response; } diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java --- httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java 2010-09-11 08:32:16.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java 2010-09-11 17:10:28.000000000 -0400 @@ -26,6 +26,8 @@ */ package org.apache.http.impl.client.cache; +import java.util.Date; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; @@ -35,6 +37,8 @@ import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; +import org.apache.http.impl.cookie.DateParseException; +import org.apache.http.impl.cookie.DateUtils; /** * Determines whether a given {@link HttpCacheEntry} is suitable to be @@ -47,17 +51,44 @@ private final Log log = LogFactory.getLog(getClass()); - private final CacheValidityPolicy validityStrategy; - - CachedResponseSuitabilityChecker(final CacheValidityPolicy validityStrategy) { + private final boolean sharedCache; + + CachedResponseSuitabilityChecker(boolean sharedCache) { super(); - this.validityStrategy = validityStrategy; + this.sharedCache = sharedCache; } - CachedResponseSuitabilityChecker() { - this(new CacheValidityPolicy()); + protected Date getCurrentDate() { + return new Date(); } - + + private long getMaxStale(HttpRequest req) { + long maxstale = -1; + for(Header h : req.getHeaders("Cache-Control")) { + for(HeaderElement elt : h.getElements()) { + if ("max-stale".equals(elt.getName())) { + try { + int val = Integer.parseInt(elt.getValue()); + if (val >= 0 && (maxstale == -1 || val < maxstale)) { + maxstale = val; + } + } catch (NumberFormatException nfe) { + // ignore what we cannot understand + } + } + } + } + return maxstale; + } + + private boolean isResponseFreshEnough(final HttpCacheEntry entry, HttpRequest req, Date now) { + if (!entry.isStale(now, sharedCache)) return true; + if (entry.originInsistsOnFreshness(sharedCache)) return false; + long maxstale = getMaxStale(req); + if (maxstale == -1) return false; + return (entry.getStalenessSecs(now, sharedCache) < maxstale); + } + /** * Determine if I can utilize a {@link HttpCacheEntry} to respond to the given * {@link HttpRequest} @@ -71,73 +102,61 @@ * @return boolean yes/no answer */ public boolean canCachedResponseBeUsed(HttpHost host, HttpRequest request, HttpCacheEntry entry) { - if (!validityStrategy.isResponseFresh(entry)) { + Date now = getCurrentDate(); + if (!isResponseFreshEnough(entry, request, now)) { log.debug("Cache entry was not fresh enough"); return false; } - if (!validityStrategy.contentLengthHeaderMatchesActualLength(entry)) { + if (!entry.contentLengthHeaderMatchesActualLength()) { log.debug("Cache entry Content-Length and header information do not match"); return false; } - if (validityStrategy.modifiedSince(entry, request)) { - log.debug("Cache entry modified times didn't line up. Cache Entry should not be used"); - return false; + Header[] ifModifiedSinceHeaders = request.getHeaders("If-Modified-Since"); + Header[] ifNoneMatchHeaders = request.getHeaders("If-None-Match"); + if (ifModifiedSinceHeaders != null && ifModifiedSinceHeaders.length > 0 + && ifNoneMatchHeaders != null && ifNoneMatchHeaders.length > 0) { + Boolean matchedLastModified = matchedLastModified(entry, + ifModifiedSinceHeaders); + boolean foundEtagMatch = foundMatchingEtag(entry, + ifNoneMatchHeaders); + if (Boolean.FALSE.equals(matchedLastModified) + || (Boolean.TRUE.equals(matchedLastModified) + && !foundEtagMatch)) return false; } for (Header ccHdr : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for (HeaderElement elt : ccHdr.getElements()) { if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equals(elt.getName())) { - log.debug("Response contained NO CACHE directive, cache was not suitable"); - return false; - } - - if (HeaderConstants.CACHE_CONTROL_NO_STORE.equals(elt.getName())) { - log.debug("Response contained NO SORE directive, cache was not suitable"); + log.debug("Request contained no-cache directive, cache was not suitable"); return false; } if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())) { try { int maxage = Integer.parseInt(elt.getValue()); - if (validityStrategy.getCurrentAgeSecs(entry) > maxage) { - log.debug("Response from cache was NOT suitable due to max age"); - return false; - } - } catch (NumberFormatException ex) { - // err conservatively - log.debug("Response from cache was malformed: " + ex.getMessage()); - return false; - } - } - - if (HeaderConstants.CACHE_CONTROL_MAX_STALE.equals(elt.getName())) { - try { - int maxstale = Integer.parseInt(elt.getValue()); - if (validityStrategy.getFreshnessLifetimeSecs(entry) > maxstale) { - log.debug("Response from cache was not suitable due to Max stale freshness"); + if (entry.getCurrentAgeSecs(now) >= maxage) { + log.debug("Response from cache was NOT suitable due to request max-age"); return false; } } catch (NumberFormatException ex) { - // err conservatively - log.debug("Response from cache was malformed: " + ex.getMessage()); - return false; + // ignore what we cannot understand + log.debug("Request had unparseable max-age directive: " + ex.getMessage()); } } if (HeaderConstants.CACHE_CONTROL_MIN_FRESH.equals(elt.getName())) { try { int minfresh = Integer.parseInt(elt.getValue()); - if (validityStrategy.getFreshnessLifetimeSecs(entry) < minfresh) { + if (entry.getRemainingFreshnessSecs(now, sharedCache) < minfresh) { log.debug("Response from cache was not suitable due to min fresh " + "freshness requirement"); return false; } } catch (NumberFormatException ex) { - // err conservatively - log.debug("Response from cache was malformed: " + ex.getMessage()); - return false; + // ignore what we cannot understand + log.debug("Request had malformed min-fresh directive: " + ex.getMessage()); } } } @@ -146,4 +165,47 @@ log.debug("Response from cache was suitable"); return true; } + + /** + * @return null if there are no well-formed If-Modified-Since + * headers, true if all If-Modified-Since headers are + * compatible with the Last-Modified date in the entry, + * and false if one of the If-Modified-Since headers + * specifies a date that pre-dates the Last-Modified date + * of the entry + */ + private Boolean matchedLastModified(HttpCacheEntry entry, + Header[] ifModifiedSinceHeaders) { + Date lastModifiedDate = entry.getLastModified(); + if (lastModifiedDate == null) return false; + Boolean out = null; + for(Header h : ifModifiedSinceHeaders) { + try { + Date validator = DateUtils.parseDate(h.getValue()); + if (lastModifiedDate.after(validator)) { + return false; + } + out = true; + } catch (DateParseException dpe) { + // ignore malformed If-Modified-Since header + } + } + return out; + } + + private boolean foundMatchingEtag(HttpCacheEntry entry, + Header[] ifNoneMatchHeaders) { + Header etag = entry.getFirstHeader("ETag"); + if (etag == null) return false; + for(Header h : ifNoneMatchHeaders) { + for(HeaderElement elt : h.getElements()) { + if ("*".equals(elt.toString()) + || etag.equals(elt.toString())) { + return true; + } + } + } + return false; + } + } diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java --- httpcomponents-client-trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java 2010-09-11 08:32:16.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java 2010-09-11 17:10:28.000000000 -0400 @@ -77,7 +77,6 @@ private final HttpClient backend; private final HttpCache responseCache; - private final CacheValidityPolicy validityPolicy; private final ResponseCachingPolicy responseCachingPolicy; private final CachedHttpResponseGenerator responseGenerator; private final CacheableRequestPolicy cacheableRequestPolicy; @@ -111,11 +110,10 @@ this.sharedCache = config.isSharedCache(); this.backend = client; this.responseCache = cache; - this.validityPolicy = new CacheValidityPolicy(); this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes, sharedCache); - this.responseGenerator = new CachedHttpResponseGenerator(this.validityPolicy); + this.responseGenerator = new CachedHttpResponseGenerator(); this.cacheableRequestPolicy = new CacheableRequestPolicy(); - this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy); + this.suitabilityChecker = new CachedResponseSuitabilityChecker(sharedCache); this.conditionalRequestBuilder = new ConditionalRequestBuilder(); this.responseCompliance = new ResponseProtocolCompliance(); @@ -171,7 +169,6 @@ CachingHttpClient( HttpClient backend, - CacheValidityPolicy validityPolicy, ResponseCachingPolicy responseCachingPolicy, HttpCache responseCache, CachedHttpResponseGenerator responseGenerator, @@ -184,7 +181,6 @@ this.maxObjectSizeBytes = config.getMaxObjectSizeBytes(); this.sharedCache = config.isSharedCache(); this.backend = backend; - this.validityPolicy = validityPolicy; this.responseCachingPolicy = responseCachingPolicy; this.responseCache = responseCache; this.responseGenerator = responseGenerator; @@ -410,17 +406,20 @@ if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry)) { setResponseStatus(context, CacheResponseStatus.CACHE_HIT); - return responseGenerator.generateResponse(entry); + HttpResponse cachedResponse = responseGenerator.generateResponse(entry); + if (entry.isStale(getCurrentDate(), sharedCache)) { + cachedResponse.addHeader("Warning","110 localhost \"Response is stale\""); + } + return cachedResponse; } - if (validityPolicy.isRevalidatable(entry)) { + if (entry.isRevalidatable()) { log.debug("Revalidating the cache entry"); try { return revalidateCacheEntry(target, request, context, entry); } catch (IOException ioex) { - if (validityPolicy.mustRevalidate(entry) - || (isSharedCache() && validityPolicy.proxyRevalidate(entry)) + if (entry.originInsistsOnFreshness(isSharedCache()) || explicitFreshnessRequest(request, entry)) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout"); @@ -444,8 +443,8 @@ if ("max-stale".equals(elt.getName())) { try { int maxstale = Integer.parseInt(elt.getValue()); - long age = validityPolicy.getCurrentAgeSecs(entry); - long lifetime = validityPolicy.getFreshnessLifetimeSecs(entry); + long age = entry.getCurrentAgeSecs(new Date()); + long lifetime = entry.getFreshnessLifetimeSecs(sharedCache); if (age - lifetime > maxstale) return true; } catch (NumberFormatException nfe) { return true; diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java 1969-12-31 19:00:00.000000000 -0500 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java 2010-09-11 17:10:29.000000000 -0400 @@ -0,0 +1,672 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.client.cache; + +import java.util.Date; + +import static org.easymock.classextension.EasyMock.*; + import org.apache.http.Header; + import org.apache.http.HttpStatus; + import org.apache.http.HttpVersion; + import org.apache.http.impl.cookie.DateUtils; + import org.apache.http.message.BasicHeader; + import org.apache.http.message.BasicStatusLine; + import org.junit.Assert; + import org.junit.Before; + import org.junit.Test; + + public class TestHttpCacheEntry { + + private HttpCacheEntry impl; + private Resource mockResource; + private Date now; + private Date tenSecondsAgo; + private Date sixSecondsAgo; + private final BasicStatusLine statusLine = + new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); + + @Before + public void setUp() { + mockResource = createMock(Resource.class); + now = new Date(); + tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); + sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); + } + + private HttpCacheEntry makeEntry(Header[] headers) { + return new HttpCacheEntry(new Date(), new Date(), statusLine, headers, mockResource, null); + } + + @Test + public void testGetHeadersReturnsCorrectHeaders() { + Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"), + new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; + impl = makeEntry(headers); + Assert.assertEquals(2, impl.getHeaders("bar").length); + } + + @Test + public void testGetFirstHeaderReturnsCorrectHeader() { + Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"), + new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; + impl = makeEntry(headers); + Assert.assertEquals("barValue1", impl.getFirstHeader("bar").getValue()); + } + + @Test + public void testGetHeadersReturnsEmptyArrayIfNoneMatch() { + Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"), + new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; + impl = makeEntry(headers); + Assert.assertEquals(0, impl.getHeaders("baz").length); + } + + @Test + public void testGetFirstHeaderReturnsNullIfNoneMatch() { + Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"), + new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; + impl = makeEntry(headers); + + Assert.assertNull(impl.getFirstHeader("quux")); + } + + @Test + public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() { + Header[] headers = new Header[0]; + impl = makeEntry(headers); + Assert.assertFalse(impl.hasVariants()); + } + + @Test + public void testCacheEntryWithOneVaryHeaderHasVariants() { + Header[] headers = { new BasicHeader("Vary", "User-Agent") }; + impl = makeEntry(headers); + Assert.assertTrue(impl.hasVariants()); + } + + @Test + public void testCacheEntryWithMultipleVaryHeadersHasVariants() { + Header[] headers = { new BasicHeader("Vary", "User-Agent"), + new BasicHeader("Vary", "Accept-Encoding") }; + impl = makeEntry(headers); + Assert.assertTrue(impl.hasVariants()); + } + + @Test + public void testCacheEntryWithVaryStarHasVariants(){ + Header[] headers = { new BasicHeader("Vary", "*") }; + impl = makeEntry(headers); + Assert.assertTrue(impl.hasVariants()); + } + + @Test + public void testMalformedCacheControlMaxAgeHeaderReturnsZero() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control", "max-age=asdf") }; + impl = makeEntry(headers); + Assert.assertEquals(-1, impl.getMaxAge(true)); + } + + @Test + public void testMultipleCacheControlMaxAgeHeaderReturnsMinimum() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control", "max-age=10,max-age=15") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getMaxAge(true)); + } + + @Test + public void testMultipleCacheControlSMaxAgeHeaderReturnsMinimumForSharedCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control", "s-maxage=10,s-maxage=15") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getMaxAge(true)); + } + + @Test + public void testMultipleCacheControlMaxAgeAndSMaxAgeHeaderReturnsMinimumForSharedCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control", "max-age=5,max-age=7,s-maxage=10,s-maxage=15") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getMaxAge(true)); + } + + @Test + public void testMultipleCacheControlMaxAgeAndSMaxAgeHeaderIgnoresSMaxAgeForPrivateCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control", "max-age=5,max-age=7,s-maxage=10,s-maxage=15") }; + impl = makeEntry(headers); + Assert.assertEquals(5, impl.getMaxAge(false)); + } + + @Test + public void testMalformedExpirationDateIsTreatedAsExpiresInThePast() + throws Exception { + Header[] headers = { new BasicHeader("Expires", "asdf"), + new BasicHeader("Date", DateUtils.formatDate(now)) + }; + impl = makeEntry(headers); + Assert.assertTrue(!impl.getExpirationDate().after(now)); + } + + @Test + public void testCacheEntryIsRevalidatableIfHeadersIncludeETag() + throws Exception { + Header[] headers = { new BasicHeader("Expires", DateUtils.formatDate(new Date())), + new BasicHeader("ETag","\"etag\"") + }; + impl = makeEntry(headers); + Assert.assertTrue(impl.isRevalidatable()); + } + + @Test + public void testCacheEntryIsRevalidatableIfHeadersIncludeLastModifiedDate() + throws Exception { + Header[] headers = { new BasicHeader("Expires", DateUtils.formatDate(new Date())), + new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())) + }; + impl = makeEntry(headers); + Assert.assertTrue(impl.isRevalidatable()); + } + + @Test + public void testCacheEntryIsRevalidatableIfHasMultipleValidators() + throws Exception { + Header[] headers = { new BasicHeader("Expires", DateUtils.formatDate(new Date())), + new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())), + new BasicHeader("ETag", "\"etag\"") + }; + impl = makeEntry(headers); + Assert.assertTrue(impl.isRevalidatable()); + } + + @Test + public void testCacheEntryIsNotRevalidatableIfNoAppropriateHeaders() + throws Exception { + Header[] headers = { new BasicHeader("Expires", DateUtils.formatDate(new Date())), + new BasicHeader("Cache-Control","public") + }; + impl = makeEntry(headers); + Assert.assertFalse(impl.isRevalidatable()); + } + + @Test + public void testNegativeAgeHeaderValueReturnsMaxAge() + throws Exception { + Header[] headers = { new BasicHeader("Age","-100") }; + impl = makeEntry(headers); + Assert.assertEquals(HttpCacheEntry.MAX_AGE, + impl.getAgeValue()); + } + + @Test + public void testMalformedAgeHeaderValueReturnsMaxAge() + throws Exception { + Header[] headers = { new BasicHeader("Age","asdf") }; + impl = makeEntry(headers); + Assert.assertEquals(HttpCacheEntry.MAX_AGE, + impl.getAgeValue()); + } + + @Test + public void testCorrectedReceivedAgeIsAgeHeaderIfLarger() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(sixSecondsAgo)), + new BasicHeader("Age","10") + }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getCorrectedReceivedAgeSecs()); + } + + @Test + public void testCorrectedReceivedAgeIsApparentAgeIfLarger() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Age","6") + }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getCorrectedReceivedAgeSecs()); + } + + @Test + public void testResidentTimeSecondsIsTimeSinceResponseTime() + throws Exception { + final Date d = now; + impl = new HttpCacheEntry(tenSecondsAgo, sixSecondsAgo, statusLine, new Header[]{}, mockResource, null); + Assert.assertEquals(6, impl.getResidentTimeSecs(d)); + } + + @Test + public void testFreshnessLifetimeIsSMaxAgeIfPresentForSharedCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","s-maxage=10") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(true)); + } + + @Test + public void testPrivateCacheIgnoresSMaxAge() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","s-maxage=10") }; + impl = makeEntry(headers); + Assert.assertEquals(0, impl.getFreshnessLifetimeSecs(false)); + } + + @Test + public void testFreshnessLifetimeIsMaxAgeIfPresentForSharedCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","max-age=10") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(true)); + } + + @Test + public void testFreshnessLifetimeIsMaxAgeIfPresentForPrivateCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","max-age=10") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(false)); + } + + @Test + public void testFreshnessLifetimeIsSMaxAgeIfMoreRestrictiveThanMaxAgeForSharedCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","max-age=20,s-maxage=10") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(true)); + } + + @Test + public void testFreshnessLifetimeIsSMaxAgeForSharedCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","max-age=10,s-maxage=20") }; + impl = makeEntry(headers); + Assert.assertEquals(20, impl.getFreshnessLifetimeSecs(true)); + } + + @Test + public void testFreshnessLifetimeIsJustMaxAgeAndNotSMaxAgeIfMoreRestrictiveForPrivateCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","max-age=10,s-maxage=20") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(false)); + } + + @Test + public void testFreshnessLifetimeIsJustMaxAgeAndNotSMaxAgeEvenIfLessRestrictiveForPrivateCache() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","max-age=20,s-maxage=10") }; + impl = makeEntry(headers); + Assert.assertEquals(20, impl.getFreshnessLifetimeSecs(false)); + } + + @Test + public void testFreshnessLifetimeIsMaxAgeEvenIfExpiresIsPresent() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)), + new BasicHeader("Cache-Control","max-age=10") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(true)); + } + + @Test + public void testFreshnessLifetimeIsSMaxAgeForSharedCacheEvenIfExpiresIsPresent() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)), + new BasicHeader("Cache-Control","s-maxage=10") }; + impl = makeEntry(headers); + Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(true)); + } + + @Test + public void testFreshnessLifetimeExpiresForPrivateCacheEvenIfSMaxAgeIsPresent() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)), + new BasicHeader("Cache-Control","s-maxage=10") }; + impl = makeEntry(headers); + Assert.assertEquals(4, impl.getFreshnessLifetimeSecs(false)); + } + + @Test + public void testFreshnessLifetimeIsFromExpiresHeaderIfNoMaxAge() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) }; + impl = makeEntry(headers); + Assert.assertEquals(4, impl.getFreshnessLifetimeSecs(true)); + } + + @Test + public void testApparentAgeIsMaxIntIfDateHeaderNotPresent() + throws Exception { + impl = makeEntry(new Header[]{}); + Assert.assertEquals(2147483648L, impl.getApparentAgeSecs()); + } + + @Test + public void testApparentAgeIsResponseReceivedTimeLessDateHeader() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)) }; + impl = new HttpCacheEntry(tenSecondsAgo, sixSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertEquals(4, impl.getApparentAgeSecs()); + } + + @Test + public void testNegativeApparentAgeIsBroughtUpToZero() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(sixSecondsAgo)) }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertEquals(0, impl.getApparentAgeSecs()); + } + + + @Test + public void testResponseDelayIsDifferenceBetweenResponseAndRequestTimes() + throws Exception { + impl = new HttpCacheEntry(tenSecondsAgo, sixSecondsAgo, statusLine, new Header[]{}, mockResource, null); + Assert.assertEquals(4, impl.getResponseDelaySecs()); + } + + @SuppressWarnings("serial") + @Test + public void testCorrectedInitialAgeIsCorrectedReceivedAgePlusResponseDelay() { + impl = new HttpCacheEntry(tenSecondsAgo, sixSecondsAgo, statusLine, new Header[]{}, mockResource, null) { + @Override + public long getCorrectedReceivedAgeSecs() { + return 7; + } + @Override + public long getResponseDelaySecs() { + return 13; + } + }; + Assert.assertEquals(20, impl.getCorrectedInitialAgeSecs()); + } + + + @SuppressWarnings("serial") + @Test + public void testCurrentAgeIsCorrectedInitialAgePlusResidentTime() { + impl = new HttpCacheEntry(tenSecondsAgo, sixSecondsAgo, statusLine, new Header[]{}, mockResource, null) { + @Override + public long getCorrectedInitialAgeSecs() { + return 11; + } + @Override + public long getResidentTimeSecs(Date d) { + return 17; + } + }; + Assert.assertEquals(28, impl.getCurrentAgeSecs(new Date())); + } + + + @SuppressWarnings("serial") + @Test + public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() { + impl = new HttpCacheEntry(tenSecondsAgo, sixSecondsAgo, statusLine, new Header[]{}, mockResource, null) { + @Override + public long getCurrentAgeSecs(Date d) { + return 6; + } + + @Override + public long getFreshnessLifetimeSecs(boolean b) { + return 10; + } + }; + Assert.assertFalse(impl.isStale(new Date(), true)); + } + + @SuppressWarnings("serial") + @Test + public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() { + impl = new HttpCacheEntry(tenSecondsAgo, sixSecondsAgo, statusLine, new Header[]{}, mockResource, null) { + @Override + public long getCurrentAgeSecs(Date d) { + return 6; + } + + @Override + public long getFreshnessLifetimeSecs(boolean b) { + return 6; + } + }; + Assert.assertTrue(impl.isStale(new Date(), true)); + } + + @SuppressWarnings("serial") + @Test + public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() { + impl = new HttpCacheEntry(tenSecondsAgo, sixSecondsAgo, statusLine, new Header[]{}, mockResource, null) { + @Override + public long getCurrentAgeSecs(Date d) { + return 10; + } + + @Override + public long getFreshnessLifetimeSecs(boolean b) { + return 6; + } + }; + Assert.assertTrue(impl.isStale(new Date(), true)); + } + + @Test + public void testMalformedDateHeaderIsIgnored() + throws Exception { + Header[] headers = { new BasicHeader("Date","asdf") }; + impl = makeEntry(headers); + Assert.assertNull(impl.getDateValue()); + } + + @Test + public void testMalformedContentLengthReturnsNegativeOne() + throws Exception { + Header[] headers = { new BasicHeader("Content-Length","asdf") }; + impl = makeEntry(headers); + Assert.assertEquals(-1, impl.getContentLengthValue()); + } + + @Test + public void testMustRevalidateIsFalseIfDirectiveNotPresent() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","public") }; + impl = makeEntry(headers); + Assert.assertFalse(impl.mustRevalidate()); + } + + @Test + public void testMustRevalidateIsTrueWhenDirectiveIsPresent() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","public, must-revalidate") }; + impl = makeEntry(headers); + Assert.assertTrue(impl.mustRevalidate()); + } + + @Test + public void testProxyRevalidateIsFalseIfDirectiveNotPresent() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","public") }; + impl = makeEntry(headers); + Assert.assertFalse(impl.proxyRevalidate()); + } + + @Test + public void testProxyRevalidateIsTrueWhenDirectiveIsPresent() + throws Exception { + Header[] headers = { new BasicHeader("Cache-Control","public, proxy-revalidate") }; + impl = makeEntry(headers); + Assert.assertTrue(impl.proxyRevalidate()); + } + + @SuppressWarnings("serial") + @Test + public void testRemainingFreshnessIsFreshnessLifetimeLessCurrentAge() + throws Exception { + final Date now = new Date(); + final boolean sharedCache = true; + impl = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource, null) { + @Override + public long getCurrentAgeSecs(Date d) { + Assert.assertSame(now, d); + return 6L; + } + @Override + public long getFreshnessLifetimeSecs(boolean b) { + Assert.assertEquals(sharedCache, b); + return 14L; + } + }; + Assert.assertEquals(8L, impl.getRemainingFreshnessSecs(now, sharedCache)); + } + + @Test + public void testRemainingFreshnessIsZeroIfStale() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=5") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertEquals(0L, impl.getRemainingFreshnessSecs(now, true)); + } + + @SuppressWarnings("serial") + @Test + public void testStalenessIsExcessAgeOverFreshnessLifetime() + throws Exception { + final Date now = new Date(); + final boolean sharedCache = true; + impl = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource, null) { + @Override + public long getCurrentAgeSecs(Date d) { + Assert.assertSame(now, d); + return 14L; + } + @Override + public long getFreshnessLifetimeSecs(boolean b) { + Assert.assertEquals(sharedCache, b); + return 6L; + } + }; + Assert.assertEquals(8L, impl.getStalenessSecs(now, sharedCache)); + } + + @Test + public void testStalenessIsZeroIfFresh() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=3600") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertEquals(0L, impl.getStalenessSecs(now, true)); + } + + @Test + public void testOriginInsistsOnFreshnessWithSharedCacheAndMustRevalidate() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","public,must-revalidate") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertTrue(impl.originInsistsOnFreshness(true)); + } + + @Test + public void testOriginInsistsOnFreshnessWithPrivateCacheAndMustRevalidate() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","public,must-revalidate") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertTrue(impl.originInsistsOnFreshness(false)); + } + + @Test + public void testOriginInsistsOnFreshnessWithSharedCacheAndSMaxAge() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","public,s-maxage=10") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertTrue(impl.originInsistsOnFreshness(true)); + } + + @Test + public void testOriginDoesNotInsistsOnFreshnessWithPrivateCacheAndSMaxAge() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","public,s-maxage=10") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertFalse(impl.originInsistsOnFreshness(false)); + } + + @Test + public void testOriginInsistsOnFreshnessWithSharedCacheAndProxyRevalidate() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","public,proxy-revalidate") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertTrue(impl.originInsistsOnFreshness(true)); + } + + @Test + public void testOriginDoesNotInsistOnFreshnessWithPrivateCacheAndProxyRevalidate() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","public,proxy-revalidate") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertFalse(impl.originInsistsOnFreshness(false)); + } + + @Test + public void testOriginDoesNotInsistOnFreshnessWithSharedCacheAndNoRevalidationDirective() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","public") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertFalse(impl.originInsistsOnFreshness(true)); + } + + @Test + public void testOriginDoesNotInsistOnFreshnessWithPrivateCacheAndNoRevalidationDirective() + throws Exception { + Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","public") + }; + impl = new HttpCacheEntry(tenSecondsAgo, tenSecondsAgo, statusLine, headers, mockResource, null); + Assert.assertFalse(impl.originInsistsOnFreshness(false)); + } + + } diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java 2010-09-11 08:32:18.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java 2010-09-11 17:10:29.000000000 -0400 @@ -1,18 +1,14 @@ package org.apache.http.impl.client.cache; -import java.util.Date; import org.apache.http.HttpEntity; 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.client.HttpClient; import org.apache.http.client.cache.HttpCache; -import org.apache.http.impl.cookie.DateUtils; import org.apache.http.message.BasicHttpRequest; -import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.HttpContext; import org.easymock.IExpectationSetters; import org.easymock.classextension.EasyMock; @@ -46,7 +42,7 @@ request = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1); - originResponse = make200Response(); + originResponse = HttpTestUtils.make200Response(); params = new CacheConfig(); params.setMaxCacheEntries(MAX_ENTRIES); @@ -67,19 +63,6 @@ EasyMock.verify(mockCache); } - protected HttpResponse make200Response() { - HttpResponse out = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - out.setHeader("Date", DateUtils.formatDate(new Date())); - out.setHeader("Server", "MockOrigin/1.0"); - out.setHeader("Content-Length", "128"); - out.setEntity(makeBody(128)); - return out; - } - - protected HttpEntity makeBody(int nbytes) { - return HttpTestUtils.makeBody(nbytes); - } - protected IExpectationSetters backendExpectsAnyRequest() throws Exception { HttpResponse resp = mockBackend.execute(EasyMock.isA(HttpHost.class), EasyMock .isA(HttpRequest.class), (HttpContext) EasyMock.isNull()); diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/CacheEntry.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/CacheEntry.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/CacheEntry.java 2010-09-11 08:32:18.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/CacheEntry.java 1969-12-31 19:00:00.000000000 -0500 @@ -1,86 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ -package org.apache.http.impl.client.cache; - -import java.util.Date; -import java.util.Set; - -import org.apache.http.Header; -import org.apache.http.client.cache.HttpCacheEntry; -import org.apache.http.client.cache.Resource; - -public class CacheEntry extends HttpCacheEntry { - - private static final long serialVersionUID = 7964121802841871079L; - - private static Resource BODY = new HeapResource(new byte[] {}); - public static final long MAX_AGE = CacheValidityPolicy.MAX_AGE; - - public CacheEntry( - Date requestDate, - Date responseDate) { - super(requestDate, responseDate, new OKStatus(), new Header[] {}, BODY, null); - } - - public CacheEntry( - Date requestDate, - Date responseDate, - Header[] headers) { - super(requestDate, responseDate, new OKStatus(), headers, BODY, null); - } - - public CacheEntry( - Date requestDate, - Date responseDate, - Header[] headers, - byte[] content) { - super(requestDate, responseDate, new OKStatus(), headers, new HeapResource(content), null); - } - - public CacheEntry( - Header[] headers, - byte[] content) { - super(new Date(), new Date(), new OKStatus(), headers, new HeapResource(content), null); - } - - public CacheEntry(Header[] headers) { - super(new Date(), new Date(), new OKStatus(), headers, BODY, null); - } - - public CacheEntry() { - this(new Date(), new Date()); - } - - public CacheEntry(byte[] content) { - super(new Date(), new Date(), new OKStatus(), new Header[] {}, new HeapResource(content), null); - } - - public CacheEntry(Set variants) { - super(new Date(), new Date(), new OKStatus(), new Header[] {}, BODY, variants); - } - -} diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java 2010-09-11 08:32:18.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java 2010-09-11 17:10:30.000000000 -0400 @@ -26,17 +26,28 @@ */ package org.apache.http.impl.client.cache; +import java.io.IOException; import java.io.InputStream; +import java.util.Date; import java.util.Random; +import java.util.Set; import org.apache.http.Header; import org.apache.http.HttpEntity; 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.RequestLine; import org.apache.http.StatusLine; +import org.apache.http.client.cache.HttpCacheEntry; +import org.apache.http.client.cache.Resource; import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.impl.cookie.DateParseException; +import org.apache.http.impl.cookie.DateUtils; +import org.apache.http.message.BasicHttpRequest; +import org.apache.http.message.BasicHttpResponse; public class HttpTestUtils { @@ -223,5 +234,79 @@ public static HttpEntity makeBody(int nbytes) { return new ByteArrayEntity(getRandomBytes(nbytes)); } + + /** Generates a 200 (OK) response with random body content. + * @return {@link HttpResponse} + */ + public static HttpResponse make200Response() { + HttpResponse out = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); + out.setHeader("Date", DateUtils.formatDate(new Date())); + out.setHeader("Server", "MockOrigin/1.0"); + out.setHeader("Content-Length", "128"); + out.setEntity(makeBody(128)); + return out; + } + + /** + * Constructs a suitable cache entry from the given response. + * @param resp original response + * @return {@link HttpCacheEntry} + * @throws IOException + * @throws Exception + */ + public static HttpCacheEntry makeCacheEntry(HttpResponse resp) + throws Exception { + Date responseDate = new Date(); + final Header dateHeader = resp.getFirstHeader("Date"); + if (dateHeader != null) { + try { + responseDate = DateUtils.parseDate(dateHeader.getValue()); + } catch (DateParseException dpe) { + } + } + return makeCacheEntry(responseDate, resp, responseDate); + } + + public static HttpCacheEntry makeCacheEntry() throws Exception { + return makeCacheEntry(make200Response()); + } + + public static HttpCacheEntry makeCacheEntry(Set variants) + throws Exception { + Date sent = new Date(); + HttpResponse resp = make200Response(); + Date recv = new Date(); + return makeCacheEntry(sent, resp, recv, variants); + } + + public static HttpCacheEntry makeCacheEntry(Date requestSent, + HttpResponse resp, Date responseReceived) throws Exception { + return makeCacheEntry(requestSent, resp, responseReceived, null); + } + + + + public static HttpCacheEntry makeCacheEntry(Date requestSent, + HttpResponse resp, Date responseReceived, Set variants) throws Exception { + HttpRequest req = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); + SizeLimitedResponseReader responseReader = + new SizeLimitedResponseReader(new HeapResourceFactory(), + CacheConfig.DEFAULT_MAX_OBJECT_SIZE_BYTES, req, resp); + responseReader.readResponse(); + + if (responseReader.isLimitReached()) { + throw new IllegalStateException("trying to cache a response that's too large in a test"); + } + + Resource resource = responseReader.getResource(); + + return new HttpCacheEntry( + requestSent, + responseReceived, + resp.getStatusLine(), + resp.getAllHeaders(), + resource, + variants); + } } \ No newline at end of file diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.java 2010-09-11 17:10:30.000000000 -0400 @@ -60,7 +60,7 @@ private BasicHttpCache impl; private SimpleHttpCacheStorage backing; - + @Before public void setUp() throws Exception { backing = new SimpleHttpCacheStorage(); @@ -72,7 +72,7 @@ HttpHost host = new HttpHost("foo.example.com"); HttpRequest req = new HttpDelete("/bar"); final String key = (new URIExtractor()).getURI(host, req); - HttpCacheEntry entry = new CacheEntry(); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(HttpTestUtils.make200Response()); backing.map.put(key, entry); @@ -200,8 +200,8 @@ final String existingVariantKey = "existingVariantKey"; final Set existingVariants = new HashSet(); existingVariants.add(existingVariantKey); - final CacheEntry parent = new CacheEntry(existingVariants); - final CacheEntry variant = new CacheEntry(); + final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants); + final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry(); HttpCacheEntry result = impl.doGetUpdatedParentEntry(parentKey, parent, variant, variantKey); assertEquals(2, result.getVariantURIs().size()); @@ -211,7 +211,7 @@ @Test public void testStoreInCachePutsNonVariantEntryInPlace() throws Exception { - CacheEntry entry = new CacheEntry(); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); assertFalse(entry.hasVariants()); HttpHost host = new HttpHost("foo.example.com"); HttpRequest req = new HttpGet("http://foo.example.com/bar"); @@ -275,7 +275,7 @@ @Test public void testGetCacheEntryFetchesFromCacheOnCacheHitIfNoVariants() throws Exception { - CacheEntry entry = new CacheEntry(); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); assertFalse(entry.hasVariants()); HttpHost host = new HttpHost("foo.example.com"); HttpRequest request = new HttpGet("http://foo.example.com/bar"); diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntry.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntry.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntry.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntry.java 1969-12-31 19:00:00.000000000 -0500 @@ -1,102 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ -package org.apache.http.impl.client.cache; - -import org.apache.http.Header; -import org.apache.http.message.BasicHeader; -import org.junit.Assert; -import org.junit.Test; - -public class TestCacheEntry { - - @Test - public void testGetHeadersReturnsCorrectHeaders() { - Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"), - new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; - CacheEntry entry = new CacheEntry(headers); - Assert.assertEquals(2, entry.getHeaders("bar").length); - } - - @Test - public void testGetFirstHeaderReturnsCorrectHeader() { - Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"), - new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; - CacheEntry entry = new CacheEntry(headers); - - Assert.assertEquals("barValue1", entry.getFirstHeader("bar").getValue()); - } - - @Test - public void testGetHeadersReturnsEmptyArrayIfNoneMatch() { - Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"), - new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; - - CacheEntry entry = new CacheEntry(headers); - - Assert.assertEquals(0, entry.getHeaders("baz").length); - } - - @Test - public void testGetFirstHeaderReturnsNullIfNoneMatch() { - Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"), - new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; - CacheEntry entry = new CacheEntry(headers); - - Assert.assertEquals(null, entry.getFirstHeader("quux")); - } - - @Test - public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() { - Header[] headers = new Header[0]; - - CacheEntry entry = new CacheEntry(headers); - Assert.assertFalse(entry.hasVariants()); - } - - @Test - public void testCacheEntryWithOneVaryHeaderHasVariants() { - Header[] headers = { new BasicHeader("Vary", "User-Agent") }; - CacheEntry entry = new CacheEntry(headers); - Assert.assertTrue(entry.hasVariants()); - } - - @Test - public void testCacheEntryWithMultipleVaryHeadersHasVariants() { - Header[] headers = { new BasicHeader("Vary", "User-Agent"), - new BasicHeader("Vary", "Accept-Encoding") }; - CacheEntry entry = new CacheEntry(headers); - Assert.assertTrue(entry.hasVariants()); - } - - @Test - public void testCacheEntryWithVaryStarHasVariants(){ - Header[] headers = { new BasicHeader("Vary", "*") }; - CacheEntry entry = new CacheEntry(headers); - Assert.assertTrue(entry.hasVariants()); - } - -} diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java 2010-09-11 17:10:30.000000000 -0400 @@ -52,10 +52,16 @@ private Date responseDate; private CacheEntryUpdater impl; + private HttpCacheEntry entry; + private HttpResponse origResp; @Before public void setUp() throws Exception { requestDate = new Date(System.currentTimeMillis() - 1000); + origResp = HttpTestUtils.make200Response(); + Date origDate = new Date(System.currentTimeMillis() - 10 * 1000L); + origResp.setHeader("Date", DateUtils.formatDate(origDate)); + entry = HttpTestUtils.makeCacheEntry(origResp); responseDate = new Date(); impl = new CacheEntryUpdater(); @@ -63,46 +69,39 @@ @Test public void testUpdateCacheEntryReturnsDifferentEntryInstance() throws IOException { - - CacheEntry entry = new CacheEntry(); BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); - - HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry, requestDate, responseDate, response); - - assertNotSame(newEntry, entry); + HttpCacheEntry result = impl.updateCacheEntry(null, entry, requestDate, responseDate, response); + assertNotSame(entry, result); } @Test - public void testHeadersAreMergedCorrectly() throws IOException { - - Header[] headers = { - new BasicHeader("Date", DateUtils.formatDate(responseDate)), - new BasicHeader("ETag", "\"etag\"")}; - - CacheEntry cacheEntry = new CacheEntry(headers); + public void testHeadersAreMergedCorrectly() throws Exception { + origResp.setHeaders(new Header[]{}); + origResp.setHeader("Date", DateUtils.formatDate(responseDate)); + origResp.setHeader("ETag", "\"etag\""); + entry = HttpTestUtils.makeCacheEntry(origResp); HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion( - "http", 1, 1), HttpStatus.SC_NOT_MODIFIED, "")); + "http", 1, 1), HttpStatus.SC_NOT_MODIFIED, "Not Modified")); response.setHeaders(new Header[]{}); - HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, cacheEntry, new Date(), new Date(), response); + HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, new Date(), new Date(), response); Assert.assertEquals(2, updatedEntry.getAllHeaders().length); - headersContain(updatedEntry.getAllHeaders(), "Date", DateUtils.formatDate(responseDate)); - headersContain(updatedEntry.getAllHeaders(), "ETag", "\"etag\""); - + assertHeadersContain(updatedEntry.getAllHeaders(), "Date", DateUtils.formatDate(responseDate)); + assertHeadersContain(updatedEntry.getAllHeaders(), "ETag", "\"etag\""); } @Test - public void testNewerHeadersReplaceExistingHeaders() throws IOException { - - Header[] headers = { - new BasicHeader("Date", DateUtils.formatDate(requestDate)), - new BasicHeader("Cache-Control", "private"), new BasicHeader("ETag", "\"etag\""), - new BasicHeader("Last-Modified", DateUtils.formatDate(requestDate)), - new BasicHeader("Cache-Control", "max-age=0"),}; - CacheEntry cacheEntry = new CacheEntry(headers); + public void testNewerHeadersReplaceExistingHeaders() throws Exception { + origResp.setHeaders(new Header[]{}); + origResp.setHeader("Date", DateUtils.formatDate(requestDate)); + origResp.setHeader("Cache-Control", "private"); + origResp.setHeader("ETag", "\"etag\""); + origResp.setHeader("Last-Modified", DateUtils.formatDate(requestDate)); + origResp.addHeader("Cache-Control", "max-age=0"); + entry = HttpTestUtils.makeCacheEntry(origResp); HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion( "http", 1, 1), HttpStatus.SC_NOT_MODIFIED, "")); @@ -110,47 +109,43 @@ new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)), new BasicHeader("Cache-Control", "public"),}); - HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, cacheEntry, new Date(), new Date(), response); - + HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, new Date(), new Date(), response); Assert.assertEquals(4, updatedEntry.getAllHeaders().length); - headersContain(updatedEntry.getAllHeaders(), "Date", DateUtils.formatDate(requestDate)); - headersContain(updatedEntry.getAllHeaders(), "ETag", "\"etag\""); - headersContain(updatedEntry.getAllHeaders(), "Last-Modified", DateUtils + assertHeadersContain(updatedEntry.getAllHeaders(), "Date", DateUtils.formatDate(requestDate)); + assertHeadersContain(updatedEntry.getAllHeaders(), "ETag", "\"etag\""); + assertHeadersContain(updatedEntry.getAllHeaders(), "Last-Modified", DateUtils .formatDate(responseDate)); - headersContain(updatedEntry.getAllHeaders(), "Cache-Control", "public"); + assertHeadersContain(updatedEntry.getAllHeaders(), "Cache-Control", "public"); } @Test - public void testNewHeadersAreAddedByMerge() throws IOException { - - Header[] headers = { - new BasicHeader("Date", DateUtils.formatDate(requestDate)), - new BasicHeader("ETag", "\"etag\"")}; + public void testNewHeadersAreAddedByMerge() throws Exception { + origResp.setHeaders(new Header[]{}); + origResp.setHeader("Date", DateUtils.formatDate(requestDate)); + origResp.setHeader("ETag", "\"etag\""); + entry = HttpTestUtils.makeCacheEntry(origResp); - CacheEntry cacheEntry = new CacheEntry(headers); HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion( "http", 1, 1), HttpStatus.SC_NOT_MODIFIED, "")); response.setHeaders(new Header[]{ new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)), new BasicHeader("Cache-Control", "public"),}); - HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, cacheEntry, new Date(), new Date(), response); - + HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, new Date(), new Date(), response); Assert.assertEquals(4, updatedEntry.getAllHeaders().length); - headersContain(updatedEntry.getAllHeaders(), "Date", DateUtils.formatDate(requestDate)); - headersContain(updatedEntry.getAllHeaders(), "ETag", "\"etag\""); - headersContain(updatedEntry.getAllHeaders(), "Last-Modified", DateUtils + assertHeadersContain(updatedEntry.getAllHeaders(), "Date", DateUtils.formatDate(requestDate)); + assertHeadersContain(updatedEntry.getAllHeaders(), "ETag", "\"etag\""); + assertHeadersContain(updatedEntry.getAllHeaders(), "Last-Modified", DateUtils .formatDate(responseDate)); - headersContain(updatedEntry.getAllHeaders(), "Cache-Control", "public"); - + assertHeadersContain(updatedEntry.getAllHeaders(), "Cache-Control", "public"); } @Test - public void testUpdatedEntryHasLatestRequestAndResponseDates() throws IOException { + public void testUpdatedEntryHasLatestRequestAndResponseDates() throws Exception { Date now = new Date(); @@ -160,7 +155,7 @@ Date twoSecondsAgo = new Date(now.getTime() - 2000L); Date oneSecondAgo = new Date(now.getTime() - 1000L); - CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo); + entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, origResp, eightSecondsAgo); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); @@ -168,10 +163,9 @@ assertEquals(twoSecondsAgo, updated.getRequestDate()); assertEquals(oneSecondAgo, updated.getResponseDate()); - } - private void headersContain(Header[] headers, String name, String value) { + private void assertHeadersContain(Header[] headers, String name, String value) { for (Header header : headers) { if (header.getName().equals(name)) { if (header.getValue().equals(value)) { diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java 2010-09-11 17:10:30.000000000 -0400 @@ -34,6 +34,7 @@ import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.ProtocolVersion; +import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; @@ -49,14 +50,14 @@ private HttpCacheStorage mockStorage; private HttpHost host; private URIExtractor extractor; - private CacheEntry mockEntry; + private HttpCacheEntry mockEntry; @Before public void setUp() { host = new HttpHost("foo.example.com"); mockStorage = EasyMock.createMock(HttpCacheStorage.class); extractor = new URIExtractor(); - mockEntry = EasyMock.createMock(CacheEntry.class); + mockEntry = EasyMock.createMock(HttpCacheEntry.class); impl = new CacheInvalidator(extractor, mockStorage); } diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java 1969-12-31 19:00:00.000000000 -0500 @@ -1,453 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ -package org.apache.http.impl.client.cache; - -import java.util.Date; - -import org.apache.http.Header; -import org.apache.http.client.cache.HttpCacheEntry; -import org.apache.http.impl.cookie.DateUtils; -import org.apache.http.message.BasicHeader; -import org.junit.Assert; -import org.junit.Test; - -public class TestCacheValidityPolicy { - - @Test - public void testApparentAgeIsMaxIntIfDateHeaderNotPresent() { - CacheEntry entry = new CacheEntry(); - CacheValidityPolicy impl = new CacheValidityPolicy(); - Assert.assertEquals(2147483648L, impl.getApparentAgeSecs(entry)); - } - - @Test - public void testApparentAgeIsResponseReceivedTimeLessDateHeader() { - Date now = new Date(); - Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); - Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - - Header[] headers = new Header[] { new BasicHeader("Date", DateUtils - .formatDate(tenSecondsAgo)) }; - - CacheEntry entry = new CacheEntry(now, sixSecondsAgo, headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertEquals(4, impl.getApparentAgeSecs(entry)); - } - - @Test - public void testNegativeApparentAgeIsBroughtUpToZero() { - Date now = new Date(); - Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); - Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - - Header[] headers = new Header[] { new BasicHeader("Date", DateUtils - .formatDate(sixSecondsAgo)) }; - - CacheEntry entry = new CacheEntry(now,tenSecondsAgo,headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - Assert.assertEquals(0, impl.getApparentAgeSecs(entry)); - } - - @Test - public void testCorrectedReceivedAgeIsAgeHeaderIfLarger() { - Header[] headers = new Header[] { new BasicHeader("Age", "10"), }; - CacheEntry entry = new CacheEntry(headers); - - CacheValidityPolicy impl = new CacheValidityPolicy() { - - @Override - protected long getApparentAgeSecs(HttpCacheEntry entry) { - return 6; - } - - }; - - Assert.assertEquals(10, impl.getCorrectedReceivedAgeSecs(entry)); - } - - @Test - public void testCorrectedReceivedAgeIsApparentAgeIfLarger() { - Header[] headers = new Header[] { new BasicHeader("Age", "6"), }; - CacheEntry entry = new CacheEntry(headers); - - CacheValidityPolicy impl = new CacheValidityPolicy() { - - @Override - protected long getApparentAgeSecs(HttpCacheEntry entry) { - return 10; - } - - }; - - Assert.assertEquals(10, impl.getCorrectedReceivedAgeSecs(entry)); - } - - @Test - public void testResponseDelayIsDifferenceBetweenResponseAndRequestTimes() { - Date now = new Date(); - Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); - Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - - CacheEntry entry = new CacheEntry(tenSecondsAgo, sixSecondsAgo); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertEquals(4, impl.getResponseDelaySecs(entry)); - } - - @Test - public void testCorrectedInitialAgeIsCorrectedReceivedAgePlusResponseDelay() { - CacheEntry entry = new CacheEntry(); - CacheValidityPolicy impl = new CacheValidityPolicy() { - - @Override - protected long getCorrectedReceivedAgeSecs(HttpCacheEntry entry) { - return 7; - } - - @Override - protected long getResponseDelaySecs(HttpCacheEntry entry) { - return 13; - } - - }; - Assert.assertEquals(20, impl.getCorrectedInitialAgeSecs(entry)); - } - - @Test - public void testResidentTimeSecondsIsTimeSinceResponseTime() { - final Date now = new Date(); - final Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); - - CacheEntry entry = new CacheEntry(now, sixSecondsAgo); - - CacheValidityPolicy impl = new CacheValidityPolicy() { - - @Override - protected Date getCurrentDate() { - return now; - } - - }; - - Assert.assertEquals(6, impl.getResidentTimeSecs(entry)); - } - - @Test - public void testCurrentAgeIsCorrectedInitialAgePlusResidentTime() { - CacheEntry entry = new CacheEntry(); - CacheValidityPolicy impl = new CacheValidityPolicy() { - - @Override - protected long getCorrectedInitialAgeSecs(HttpCacheEntry entry) { - return 11; - } - - @Override - protected long getResidentTimeSecs(HttpCacheEntry entry) { - return 17; - } - }; - Assert.assertEquals(28, impl.getCurrentAgeSecs(entry)); - } - - @Test - public void testFreshnessLifetimeIsSMaxAgeIfPresent() { - Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10") }; - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); - } - - @Test - public void testFreshnessLifetimeIsMaxAgeIfPresent() { - Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10") }; - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); - } - - @Test - public void testFreshnessLifetimeIsMostRestrictiveOfMaxAgeAndSMaxAge() { - Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"), - new BasicHeader("Cache-Control", "s-maxage=20") }; - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); - - headers = new Header[] { new BasicHeader("Cache-Control", "max-age=20"), - new BasicHeader("Cache-Control", "s-maxage=10") }; - entry = new CacheEntry(headers); - Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); - } - - @Test - public void testFreshnessLifetimeIsMaxAgeEvenIfExpiresIsPresent() { - Date now = new Date(); - Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); - Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"), - new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), - new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) }; - - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); - } - - @Test - public void testFreshnessLifetimeIsSMaxAgeEvenIfExpiresIsPresent() { - Date now = new Date(); - Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); - Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10"), - new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), - new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) }; - - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); - } - - @Test - public void testFreshnessLifetimeIsFromExpiresHeaderIfNoMaxAge() { - Date now = new Date(); - Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); - Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - Header[] headers = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), - new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) }; - - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - Assert.assertEquals(4, impl.getFreshnessLifetimeSecs(entry)); - } - - @Test - public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() { - CacheEntry entry = new CacheEntry(); - CacheValidityPolicy impl = new CacheValidityPolicy() { - - @Override - public long getCurrentAgeSecs(HttpCacheEntry entry) { - return 6; - } - - @Override - public long getFreshnessLifetimeSecs(HttpCacheEntry entry) { - return 10; - } - }; - - Assert.assertTrue(impl.isResponseFresh(entry)); - } - - @Test - public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() { - CacheEntry entry = new CacheEntry(); - CacheValidityPolicy impl = new CacheValidityPolicy() { - - @Override - public long getCurrentAgeSecs(HttpCacheEntry entry) { - return 6; - } - - @Override - public long getFreshnessLifetimeSecs(HttpCacheEntry entry) { - return 6; - } - }; - - Assert.assertFalse(impl.isResponseFresh(entry)); - } - - @Test - public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() { - CacheEntry entry = new CacheEntry(); - CacheValidityPolicy impl = new CacheValidityPolicy() { - - @Override - public long getCurrentAgeSecs(HttpCacheEntry entry) { - return 10; - } - - @Override - public long getFreshnessLifetimeSecs(HttpCacheEntry entry) { - return 6; - } - }; - - Assert.assertFalse(impl.isResponseFresh(entry)); - } - - @Test - public void testCacheEntryIsRevalidatableIfHeadersIncludeETag() { - - Header[] headers = { - new BasicHeader("Expires", DateUtils.formatDate(new Date())), - new BasicHeader("ETag", "somevalue")}; - - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertTrue(impl.isRevalidatable(entry)); - } - - @Test - public void testCacheEntryIsRevalidatableIfHeadersIncludeLastModifiedDate() { - - Header[] headers = { - new BasicHeader("Expires", DateUtils.formatDate(new Date())), - new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())) }; - - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertTrue(impl.isRevalidatable(entry)); - } - - @Test - public void testCacheEntryIsNotRevalidatableIfNoAppropriateHeaders() { - - Header[] headers = { - new BasicHeader("Expires", DateUtils.formatDate(new Date())), - new BasicHeader("Cache-Control", "public") }; - - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertFalse(impl.isRevalidatable(entry)); - } - - @Test - public void testMalformedDateHeaderIsIgnored() { - - Header[] headers = new Header[] { new BasicHeader("Date", "asdf") }; - CacheEntry entry = new CacheEntry(headers); - - CacheValidityPolicy impl = new CacheValidityPolicy(); - Date d = impl.getDateValue(entry); - - Assert.assertNull(d); - } - - @Test - public void testMalformedContentLengthReturnsNegativeOne() { - - Header[] headers = new Header[] { new BasicHeader("Content-Length", "asdf") }; - CacheEntry entry = new CacheEntry(headers); - - CacheValidityPolicy impl = new CacheValidityPolicy(); - long length = impl.getContentLengthValue(entry); - - Assert.assertEquals(-1, length); - } - - @Test - public void testNegativeAgeHeaderValueReturnsMaxAge() { - - Header[] headers = new Header[] { new BasicHeader("Age", "-100") }; - CacheEntry entry = new CacheEntry(headers); - - CacheValidityPolicy impl = new CacheValidityPolicy(); - long length = impl.getAgeValue(entry); - - Assert.assertEquals(CacheEntry.MAX_AGE, length); - } - - @Test - public void testMalformedAgeHeaderValueReturnsMaxAge() { - - Header[] headers = new Header[] { new BasicHeader("Age", "asdf") }; - CacheEntry entry = new CacheEntry(headers); - - CacheValidityPolicy impl = new CacheValidityPolicy(); - long length = impl.getAgeValue(entry); - - Assert.assertEquals(CacheEntry.MAX_AGE, length); - } - - @Test - public void testMalformedCacheControlMaxAgeHeaderReturnsZero() { - - Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=asdf") }; - CacheEntry entry = new CacheEntry(headers); - - CacheValidityPolicy impl = new CacheValidityPolicy(); - long maxage = impl.getMaxAge(entry); - - Assert.assertEquals(0, maxage); - } - - @Test - public void testMalformedExpirationDateReturnsNull() { - Header[] headers = new Header[] { new BasicHeader("Expires", "asdf") }; - CacheEntry entry = new CacheEntry(headers); - - CacheValidityPolicy impl = new CacheValidityPolicy(); - Date expirationDate = impl.getExpirationDate(entry); - - Assert.assertNull(expirationDate); - } - - @Test - public void testMustRevalidateIsFalseIfDirectiveNotPresent() { - Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") }; - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertFalse(impl.mustRevalidate(entry)); - } - - @Test - public void testMustRevalidateIsTrueWhenDirectiveIsPresent() { - Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, must-revalidate") }; - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertTrue(impl.mustRevalidate(entry)); - } - - @Test - public void testProxyRevalidateIsFalseIfDirectiveNotPresent() { - Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") }; - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertFalse(impl.proxyRevalidate(entry)); - } - - @Test - public void testProxyRevalidateIsTrueWhenDirectiveIsPresent() { - Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, proxy-revalidate") }; - CacheEntry entry = new CacheEntry(headers); - CacheValidityPolicy impl = new CacheValidityPolicy(); - - Assert.assertTrue(impl.proxyRevalidate(entry)); - } - -} diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java 2010-09-11 17:10:30.000000000 -0400 @@ -30,8 +30,13 @@ import org.apache.http.Header; import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.StatusLine; +import org.apache.http.client.cache.HttpCacheEntry; +import org.apache.http.client.cache.Resource; import org.apache.http.impl.cookie.DateUtils; -import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Before; @@ -39,92 +44,120 @@ public class TestCachedHttpResponseGenerator { - private CacheEntry entry; - private CacheValidityPolicy mockValidityPolicy; + private HttpCacheEntry entry; private CachedHttpResponseGenerator impl; + private HttpResponse resp; + private StatusLine statusLine; + private Resource mockResource; + private Date tenSecondsFromNow; + private Date tenSecondsAgo; + private Date eightSecondsAgo; + private Date sixSecondsAgo; + private Date now; @Before - public void setUp() { - Date now = new Date(); - Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); - Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); - Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L); - Header[] hdrs = { new BasicHeader("Date", DateUtils.formatDate(eightSecondsAgo)), - new BasicHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)), - new BasicHeader("Content-Length", "150") }; - - entry = new CacheEntry(tenSecondsAgo, sixSecondsAgo, hdrs); - mockValidityPolicy = EasyMock.createMock(CacheValidityPolicy.class); - impl = new CachedHttpResponseGenerator(mockValidityPolicy); - } - - public void replayMocks() { - EasyMock.replay(mockValidityPolicy); + public void setUp() throws Exception { + now = new Date(); + sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); + eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); + tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); + tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L); + resp = HttpTestUtils.make200Response(); + resp.setHeader("Date", DateUtils.formatDate(eightSecondsAgo)); + resp.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); + + statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); + + entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, resp, sixSecondsAgo); + mockResource = EasyMock.createMock(Resource.class); + impl = new CachedHttpResponseGenerator(); } @Test - public void testResponseHasContentLength() { - byte[] buf = new byte[] { 1, 2, 3, 4, 5 }; - CacheEntry entry = new CacheEntry(buf); - + public void testResponseHasContentLength() throws Exception { + int origLength = (int)resp.getEntity().getContentLength(); + resp.removeHeaders("Content-Length"); + entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, resp, sixSecondsAgo); + impl = new CachedHttpResponseGenerator(); + HttpResponse response = impl.generateResponse(entry); Header length = response.getFirstHeader("Content-Length"); Assert.assertNotNull("Content-Length Header is missing", length); - Assert.assertEquals("Content-Length does not match buffer length", buf.length, Integer - .parseInt(length.getValue())); + Assert.assertEquals("Content-Length does not match buffer length", + origLength, Integer.parseInt(length.getValue())); } @Test - public void testContentLengthIsNotAddedWhenTransferEncodingIsPresent() { + public void testContentLengthIsNotAddedWhenTransferEncodingIsPresent() + throws Exception { + resp.removeHeaders("Content-Length"); + resp.setHeader("Transfer-Encoding", "chunked"); + entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, resp, sixSecondsAgo); + impl = new CachedHttpResponseGenerator(); + + HttpResponse result = impl.generateResponse(entry); - Header[] hdrs = new Header[] { new BasicHeader("Transfer-Encoding", "chunked") }; - byte[] buf = new byte[] { 1, 2, 3, 4, 5 }; - CacheEntry entry = new CacheEntry(hdrs, buf); - - HttpResponse response = impl.generateResponse(entry); - - Header length = response.getFirstHeader("Content-Length"); - - Assert.assertNull(length); + Assert.assertNull(result.getFirstHeader("Content-Length")); } @Test public void testResponseMatchesCacheEntry() { - HttpResponse response = impl.generateResponse(entry); - - Assert.assertTrue(response.containsHeader("Content-Length")); - - Assert.assertSame("HTTP", response.getProtocolVersion().getProtocol()); - Assert.assertEquals(1, response.getProtocolVersion().getMajor()); - Assert.assertEquals(1, response.getProtocolVersion().getMinor()); + impl = new CachedHttpResponseGenerator(); + + HttpResponse result = impl.generateResponse(entry); + + Assert.assertTrue(result.containsHeader("Content-Length")); + Assert.assertSame("HTTP", result.getProtocolVersion().getProtocol()); + Assert.assertEquals(1, result.getProtocolVersion().getMajor()); + Assert.assertEquals(1, result.getProtocolVersion().getMinor()); } @Test public void testResponseStatusCodeMatchesCacheEntry() { + impl = new CachedHttpResponseGenerator(); + HttpResponse response = impl.generateResponse(entry); Assert.assertEquals(entry.getStatusCode(), response.getStatusLine().getStatusCode()); } - @Test + @SuppressWarnings("serial") + @Test public void testAgeHeaderIsPopulatedWithCurrentAgeOfCacheEntryIfNonZero() { - currentAge(10L); - replayMocks(); + entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource, null) { + @Override + public boolean isStale(Date d, boolean b) { + return false; + } + @Override + public long getCurrentAgeSecs(Date d) { + return 10L; + } + }; - HttpResponse response = impl.generateResponse(entry); + HttpResponse response = impl.generateResponse(entry); Header ageHdr = response.getFirstHeader("Age"); Assert.assertNotNull(ageHdr); Assert.assertEquals(10L, Long.parseLong(ageHdr.getValue())); } - @Test + + @SuppressWarnings("serial") + @Test public void testAgeHeaderIsNotPopulatedIfCurrentAgeOfCacheEntryIsZero() { - currentAge(0L); - replayMocks(); + entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource, null) { + @Override + public boolean isStale(Date d, boolean b) { + return false; + } + @Override + public long getCurrentAgeSecs(Date d) { + return 0L; + } + }; HttpResponse response = impl.generateResponse(entry); @@ -132,21 +165,25 @@ Assert.assertNull(ageHdr); } - @Test + @SuppressWarnings("serial") + @Test public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() { - currentAge(CacheEntry.MAX_AGE + 1L); - replayMocks(); + entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource, null) { + @Override + public boolean isStale(Date d, boolean b) { + return false; + } + @Override + public long getCurrentAgeSecs(Date d) { + return (HttpCacheEntry.MAX_AGE + 1L); + } + }; HttpResponse response = impl.generateResponse(entry); Header ageHdr = response.getFirstHeader("Age"); Assert.assertNotNull(ageHdr); - Assert.assertEquals(CacheEntry.MAX_AGE, Long.parseLong(ageHdr.getValue())); - } - - private void currentAge(long sec) { - EasyMock.expect( - mockValidityPolicy.getCurrentAgeSecs(entry)).andReturn(sec); + Assert.assertEquals(HttpCacheEntry.MAX_AGE, Long.parseLong(ageHdr.getValue())); } } diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java 2010-09-11 17:10:30.000000000 -0400 @@ -26,11 +26,20 @@ */ package org.apache.http.impl.client.cache; +import java.util.Date; + +import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.StatusLine; +import org.apache.http.client.cache.HttpCacheEntry; +import org.apache.http.client.cache.Resource; +import org.apache.http.impl.cookie.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; -import org.easymock.classextension.EasyMock; +import org.apache.http.message.BasicStatusLine; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -39,225 +48,196 @@ private HttpHost host; private HttpRequest request; - private CacheEntry entry; - private CacheValidityPolicy mockValidityPolicy; + private HttpCacheEntry entry; private CachedResponseSuitabilityChecker impl; - + private final StatusLine statusLine = + new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); + private Resource resource; + + private Date now; + private Date elevenSecondsAgo; + private Date tenSecondsAgo; + private Date nineSecondsAgo; + @Before - public void setUp() { + public void setUp() throws Exception { host = new HttpHost("foo.example.com"); - request = new BasicHttpRequest("GET", "/foo"); - mockValidityPolicy = EasyMock.createMock(CacheValidityPolicy.class); - entry = new CacheEntry(); - - impl = new CachedResponseSuitabilityChecker(mockValidityPolicy); - } - - public void replayMocks() { - EasyMock.replay(mockValidityPolicy); - } + request = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1); + entry = HttpTestUtils.makeCacheEntry(); - public void verifyMocks() { - EasyMock.verify(mockValidityPolicy); + byte[] body = HttpTestUtils.getRandomBytes(50); + resource = new HeapResource(body); + + now = new Date(); + elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L); + tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); + nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); + + impl = new CachedResponseSuitabilityChecker(true) { + @Override + protected Date getCurrentDate() { return now; } + }; } @Test public void testNotSuitableIfContentLengthHeaderIsWrong() { - responseIsFresh(true); - contentLengthMatchesActualLength(false); - - replayMocks(); - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - - verifyMocks(); - - Assert.assertFalse(result); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=3600"), + new BasicHeader("Content-Length","51") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry)); } @Test - public void testSuitableIfContentLengthHeaderIsRight() { - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - - replayMocks(); - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - - verifyMocks(); - - Assert.assertTrue(result); - } - - @Test - public void testSuitableIfCacheEntryIsFresh() { - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - - verifyMocks(); - - Assert.assertTrue(result); + public void testSuitableIfNotStaleAndContentLengthHeaderIsRight() { + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=3600"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry)); } @Test public void testNotSuitableIfCacheEntryIsNotFresh() { - responseIsFresh(false); - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - - verifyMocks(); - - Assert.assertFalse(result); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=2"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry)); } @Test public void testNotSuitableIfRequestHasNoCache() { request.addHeader("Cache-Control", "no-cache"); - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - verifyMocks(); - Assert.assertFalse(result); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=3600"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry)); } @Test public void testNotSuitableIfAgeExceedsRequestMaxAge() { - request.addHeader("Cache-Control", "max-age=10"); - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - currentAge(20L); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - verifyMocks(); - Assert.assertFalse(result); + request.addHeader("Cache-Control", "max-age=2"); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=3600"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry)); } @Test public void testSuitableIfFreshAndAgeIsUnderRequestMaxAge() { - request.addHeader("Cache-Control", "max-age=10"); - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - currentAge(5L); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - verifyMocks(); - Assert.assertTrue(result); + request.addHeader("Cache-Control", "max-age=20"); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=3600"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry)); } @Test public void testSuitableIfFreshAndFreshnessLifetimeGreaterThanRequestMinFresh() { - request.addHeader("Cache-Control", "min-fresh=10"); - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - freshnessLifetime(15L); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - verifyMocks(); - Assert.assertTrue(result); + request.addHeader("Cache-Control", "min-fresh=2"); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=15"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry)); } @Test public void testNotSuitableIfFreshnessLifetimeLessThanRequestMinFresh() { request.addHeader("Cache-Control", "min-fresh=10"); - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - freshnessLifetime(5L); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - verifyMocks(); - Assert.assertFalse(result); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=15"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry)); } - // this is compliant but possibly misses some cache hits; would - // need to change logic to add Warning header if we allowed this @Test - public void testNotSuitableEvenIfStaleButPermittedByRequestMaxStale() { - request.addHeader("Cache-Control", "max-stale=10"); - responseIsFresh(false); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - verifyMocks(); - Assert.assertFalse(result); + public void testSuitableIfStaleButPermittedByRequestMaxStale() { + request.addHeader("Cache-Control", "max-stale=100"); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=5"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertTrue(entry.isStale(now, true)); + Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry)); } @Test - public void testMalformedCacheControlMaxAgeRequestHeaderCausesUnsuitableEntry() { + public void testMalformedCacheControlMaxAgeRequestHeaderIsIgnoredForFreshEntry() { request.addHeader(new BasicHeader("Cache-Control", "max-age=foo")); - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - - verifyMocks(); - - Assert.assertFalse(result); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=20"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry)); } @Test - public void testMalformedCacheControlMinFreshRequestHeaderCausesUnsuitableEntry() { + public void testMalformedCacheControlMinFreshRequestHeaderIsIgnoredForFreshEntry() { request.addHeader(new BasicHeader("Cache-Control", "min-fresh=foo")); - - responseIsFresh(true); - contentLengthMatchesActualLength(true); - modifiedSince(false, request); - - replayMocks(); - - boolean result = impl.canCachedResponseBeUsed(host, request, entry); - - verifyMocks(); - - Assert.assertFalse(result); - } - - private void currentAge(long sec) { - EasyMock.expect( - mockValidityPolicy.getCurrentAgeSecs(entry)).andReturn(sec); - } - - private void freshnessLifetime(long sec) { - EasyMock.expect( - mockValidityPolicy.getFreshnessLifetimeSecs(entry)).andReturn(sec); - } - - private void responseIsFresh(boolean fresh) { - EasyMock.expect( - mockValidityPolicy.isResponseFresh(entry)).andReturn(fresh); - } - - private void modifiedSince(boolean modified, HttpRequest request) { - EasyMock.expect( - mockValidityPolicy.modifiedSince(entry, request)).andReturn(modified); - } - - private void contentLengthMatchesActualLength(boolean b) { - EasyMock.expect( - mockValidityPolicy.contentLengthHeaderMatchesActualLength(entry)).andReturn(b); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=20"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry)); + } + + @Test + public void testMalformedCacheControlMaxStaleRequestHeaderIsIgnoredForStaleEntry() { + request.addHeader(new BasicHeader("Cache-Control", "max-stale=foo")); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=5"), + new BasicHeader("Content-Length","50") + }; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null); + Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry)); + } + + @SuppressWarnings("serial") + @Test + public void testMaxStaleRequestIsIgnoredIfOriginInsistsOnFreshness() { + request.addHeader(new BasicHeader("Cache-Control", "max-stale=100")); + Header[] headers = { + new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), + new BasicHeader("Cache-Control","max-age=5,must-revalidate"), + new BasicHeader("Content-Length","50") + }; + final boolean sharedCache = true; + entry = new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, resource, null) { + @Override + public boolean originInsistsOnFreshness(boolean b) { + Assert.assertEquals(sharedCache, b); + return true; + } + }; + Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry)); } } \ No newline at end of file diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java 2010-09-11 17:10:30.000000000 -0400 @@ -74,14 +74,13 @@ private CachingHttpClient impl; private boolean mockedImpl; - private CacheValidityPolicy mockValidityPolicy; private CacheableRequestPolicy mockRequestPolicy; private HttpClient mockBackend; private HttpCache mockCache; private CachedResponseSuitabilityChecker mockSuitabilityChecker; private ResponseCachingPolicy mockResponsePolicy; private HttpResponse mockBackendResponse; - private CacheEntry mockCacheEntry; + private HttpCacheEntry mockCacheEntry; private CachedHttpResponseGenerator mockResponseGenerator; private ClientConnectionManager mockConnectionManager; private ResponseHandler mockHandler; @@ -104,7 +103,6 @@ @Before public void setUp() { mockRequestPolicy = EasyMock.createMock(CacheableRequestPolicy.class); - mockValidityPolicy = EasyMock.createMock(CacheValidityPolicy.class); mockBackend = EasyMock.createMock(HttpClient.class); mockCache = EasyMock.createMock(HttpCache.class); mockSuitabilityChecker = EasyMock.createMock(CachedResponseSuitabilityChecker.class); @@ -113,7 +111,7 @@ mockHandler = EasyMock.createMock(ResponseHandler.class); mockBackendResponse = EasyMock.createMock(HttpResponse.class); mockUriRequest = EasyMock.createMock(HttpUriRequest.class); - mockCacheEntry = EasyMock.createMock(CacheEntry.class); + mockCacheEntry = EasyMock.createMock(HttpCacheEntry.class); mockResponseGenerator = EasyMock.createMock(CachedHttpResponseGenerator.class); mockCachedResponse = EasyMock.createMock(HttpResponse.class); mockConditionalRequestBuilder = EasyMock.createMock(ConditionalRequestBuilder.class); @@ -130,7 +128,6 @@ params = new BasicHttpParams(); impl = new CachingHttpClient( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, @@ -143,7 +140,6 @@ private void replayMocks() { EasyMock.replay(mockRequestPolicy); - EasyMock.replay(mockValidityPolicy); EasyMock.replay(mockSuitabilityChecker); EasyMock.replay(mockResponsePolicy); EasyMock.replay(mockCacheEntry); @@ -167,7 +163,6 @@ private void verifyMocks() { EasyMock.verify(mockRequestPolicy); - EasyMock.verify(mockValidityPolicy); EasyMock.verify(mockSuitabilityChecker); EasyMock.verify(mockResponsePolicy); EasyMock.verify(mockCacheEntry); @@ -359,7 +354,8 @@ requestProtocolValidationIsCalled(); getCacheEntryReturns(mockCacheEntry); cacheEntrySuitable(true); - responseIsGeneratedFromCache(); + cacheEntryIsStale(false); + responseIsGeneratedFromCache(); requestIsFatallyNonCompliant(null); replayMocks(); @@ -410,7 +406,6 @@ final HttpResponse theResponse = mockBackendResponse; impl = new CachingHttpClient( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, @@ -448,7 +443,6 @@ final Object value = new Object(); impl = new CachingHttpClient( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, @@ -494,7 +488,6 @@ final HttpContext theContext = context; impl = new CachingHttpClient( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, @@ -532,7 +525,6 @@ final HttpResponse theResponse = mockBackendResponse; impl = new CachingHttpClient( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, @@ -568,7 +560,6 @@ final HttpResponse theResponse = mockBackendResponse; impl = new CachingHttpClient( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, @@ -607,7 +598,6 @@ final Object theValue = new Object(); impl = new CachingHttpClient( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, @@ -648,7 +638,6 @@ final Object theValue = new Object(); impl = new CachingHttpClient( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, @@ -704,6 +693,7 @@ cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(true); cacheEntrySuitable(true); + cacheEntryIsStale(false); getCacheEntryReturns(mockCacheEntry); responseIsGeneratedFromCache(); @@ -1096,8 +1086,8 @@ } private void cacheEntryValidatable(boolean b) { - EasyMock.expect(mockValidityPolicy.isRevalidatable( - EasyMock.anyObject())).andReturn(b); + EasyMock.expect(mockCacheEntry.isRevalidatable()) + .andReturn(b); } private void backendResponseCodeIs(int code) { @@ -1149,6 +1139,11 @@ EasyMock.anyObject(), EasyMock.anyObject())).andReturn(suitable); } + + private void cacheEntryIsStale(boolean stale) { + EasyMock.expect(mockCacheEntry.isStale(EasyMock.isA(Date.class), EasyMock.anyBoolean())) + .andReturn(stale); + } private void responseIsGeneratedFromCache() { EasyMock.expect(mockResponseGenerator.generateResponse( @@ -1192,7 +1187,6 @@ mockedImpl = true; impl = EasyMock.createMockBuilder(CachingHttpClient.class).withConstructor( mockBackend, - mockValidityPolicy, mockResponsePolicy, mockCache, mockResponseGenerator, diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.java 2010-09-11 17:10:30.000000000 -0400 @@ -31,10 +31,10 @@ import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; -import org.apache.http.ProtocolException; +import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.impl.cookie.DateUtils; -import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.junit.Assert; import org.junit.Before; @@ -43,14 +43,18 @@ public class TestConditionalRequestBuilder { private ConditionalRequestBuilder impl; + private HttpResponse resp; + private HttpCacheEntry entry; @Before public void setUp() throws Exception { + resp = HttpTestUtils.make200Response(); + entry = HttpTestUtils.makeCacheEntry(resp); impl = new ConditionalRequestBuilder(); } @Test - public void testBuildConditionalRequestWithLastModified() throws ProtocolException { + public void testBuildConditionalRequestWithLastModified() throws Exception { String theMethod = "GET"; String theUri = "/theuri"; String lastModified = "this is my last modified date"; @@ -58,12 +62,11 @@ HttpRequest request = new BasicHttpRequest(theMethod, theUri); request.addHeader("Accept-Encoding", "gzip"); - Header[] headers = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(new Date())), - new BasicHeader("Last-Modified", lastModified) }; + resp.setHeader("Last-Modified", lastModified); + entry = HttpTestUtils.makeCacheEntry(resp); - CacheEntry cacheEntry = new CacheEntry(headers); - HttpRequest newRequest = impl.buildConditionalRequest(request, cacheEntry); +// CacheEntry cacheEntry = new CacheEntry(headers); + HttpRequest newRequest = impl.buildConditionalRequest(request, entry); Assert.assertNotSame(request, newRequest); @@ -81,7 +84,7 @@ } @Test - public void testBuildConditionalRequestWithETag() throws ProtocolException { + public void testBuildConditionalRequestWithETag() throws Exception { String theMethod = "GET"; String theUri = "/theuri"; String theETag = "this is my eTag"; @@ -89,14 +92,11 @@ HttpRequest request = new BasicHttpRequest(theMethod, theUri); request.addHeader("Accept-Encoding", "gzip"); - Header[] headers = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(new Date())), - new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())), - new BasicHeader("ETag", theETag) }; + resp.setHeader("Last-Modified", DateUtils.formatDate(new Date())); + resp.setHeader("ETag", theETag); + entry = HttpTestUtils.makeCacheEntry(resp); - CacheEntry cacheEntry = new CacheEntry(headers); - - HttpRequest newRequest = impl.buildConditionalRequest(request, cacheEntry); + HttpRequest newRequest = impl.buildConditionalRequest(request, entry); Assert.assertNotSame(request, newRequest); @@ -122,13 +122,12 @@ Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); - Header[] cacheEntryHeaders = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), - new BasicHeader("ETag", "\"etag\""), - new BasicHeader("Cache-Control","max-age=5, must-revalidate") }; - CacheEntry cacheEntry = new CacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders); + resp.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); + resp.setHeader("ETag", "\"etag\""); + resp.setHeader("Cache-Control","max-age=5, must-revalidate"); + entry = HttpTestUtils.makeCacheEntry(elevenSecondsAgo, resp, nineSecondsAgo); - HttpRequest result = impl.buildConditionalRequest(request, cacheEntry); + HttpRequest result = impl.buildConditionalRequest(request, entry); boolean foundMaxAge0 = false; for(Header h : result.getHeaders("Cache-Control")) { @@ -150,13 +149,12 @@ Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); - Header[] cacheEntryHeaders = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), - new BasicHeader("ETag", "\"etag\""), - new BasicHeader("Cache-Control","max-age=5, proxy-revalidate") }; - CacheEntry cacheEntry = new CacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders); + resp.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); + resp.setHeader("ETag", "\"etag\""); + resp.setHeader("Cache-Control","max-age=5, proxy-revalidate"); + entry = HttpTestUtils.makeCacheEntry(elevenSecondsAgo, resp, nineSecondsAgo); - HttpRequest result = impl.buildConditionalRequest(request, cacheEntry); + HttpRequest result = impl.buildConditionalRequest(request, entry); boolean foundMaxAge0 = false; for(Header h : result.getHeaders("Cache-Control")) { diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java 2010-09-11 17:10:30.000000000 -0400 @@ -81,7 +81,7 @@ */ private HttpRequest requestToPopulateStaleCacheEntry() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); @@ -170,7 +170,7 @@ HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); req2.setHeader("Cache-Control","max-stale=20"); - backendExpectsAnyRequest().andThrow(new IOException()); + backendExpectsAnyRequest().andThrow(new IOException()).times(0,1); replayMocks(); impl.execute(host, req1); @@ -218,7 +218,7 @@ public void testReturnsCachedResponsesAppropriatelyWhenNoOriginCommunication() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("Cache-Control", "public, max-age=5"); @@ -299,4 +299,5 @@ assertEquals(warning, result.getFirstHeader("Warning").getValue()); } + } diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java 2010-09-11 17:10:30.000000000 -0400 @@ -44,11 +44,11 @@ import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.RequestWrapper; import org.apache.http.impl.cookie.DateUtils; -import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; @@ -865,21 +865,21 @@ // put something cacheable in the cache HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.addHeader("Cache-Control", "max-age=3600"); resp1.setHeader(eHeader, oldVal); // get a head that penetrates the cache HttpRequest req2 = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1); req2.addHeader("Cache-Control", "no-cache"); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setEntity(null); resp2.setHeader(eHeader, newVal); // next request doesn't tolerate stale entry HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); req3.addHeader("Cache-Control", "max-stale=0"); - HttpResponse resp3 = make200Response(); + HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader(eHeader, newVal); EasyMock.expect( @@ -1135,7 +1135,7 @@ throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=3600"); @@ -1165,7 +1165,7 @@ throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=3600"); @@ -1197,7 +1197,7 @@ @Test public void test206ResponseGeneratedFromCacheMustHaveDateHeader() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=3600"); @@ -1306,7 +1306,7 @@ Date nextSecond = new Date(now.getTime() + 1000L); Date inTwoHoursPlusASec = new Date(now.getTime() + 2 * 3600 * 1000L + 1000L); - HttpResponse originResponse2 = make200Response(); + HttpResponse originResponse2 = HttpTestUtils.make200Response(); originResponse2.setHeader("Date", DateUtils.formatDate(nextSecond)); originResponse2.setHeader("Cache-Control", "max-age=7200"); originResponse2.setHeader("Expires", DateUtils.formatDate(inTwoHoursPlusASec)); @@ -1350,7 +1350,7 @@ Date now = new Date(); Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L); - originResponse = make200Response(); + originResponse = HttpTestUtils.make200Response(); originResponse.addHeader("Allow", "GET,HEAD"); originResponse.addHeader("Cache-Control", "max-age=3600"); originResponse.addHeader("Content-Language", "en"); @@ -1447,7 +1447,7 @@ Date now = new Date(); HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("ETag", "\"etag1\""); byte[] bytes1 = new byte[128]; @@ -1475,7 +1475,7 @@ Date inTwoSeconds = new Date(now.getTime() + 2000L); HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp3 = make200Response(); + HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Date", DateUtils.formatDate(inTwoSeconds)); resp3.setHeader("Cache-Control", "max-age=3600"); resp3.setHeader("ETag", "\"etag2\""); @@ -1523,7 +1523,7 @@ Date now = new Date(); HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); Date oneHourAgo = new Date(now.getTime() - 3600L); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(oneHourAgo)); @@ -1552,7 +1552,7 @@ Date inTwoSeconds = new Date(now.getTime() + 2000L); HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp3 = make200Response(); + HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Date", DateUtils.formatDate(inTwoSeconds)); resp3.setHeader("Cache-Control", "max-age=3600"); resp3.setHeader("ETag", "\"etag2\""); @@ -1811,7 +1811,7 @@ HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); req1.setHeader("Accept-Encoding", "gzip"); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"v1\""); resp1.setHeader("Cache-Control", "max-age=7200"); resp1.setHeader("Expires", DateUtils.formatDate(inTwoHours)); @@ -1822,7 +1822,7 @@ req1.setHeader("Accept-Encoding", "gzip"); req1.setHeader("Cache-Control", "no-cache"); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag", "\"v2\""); resp2.setHeader("Cache-Control", "max-age=3600"); resp2.setHeader("Expires", DateUtils.formatDate(inTwoHours)); @@ -1870,7 +1870,7 @@ HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "W/\"v1\""); resp1.setHeader("Allow", "GET,HEAD"); resp1.setHeader("Content-Encoding", "x-coding"); @@ -1919,7 +1919,7 @@ // load cache with cacheable entry HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag1\""); resp1.setHeader("Cache-Control", "max-age=3600"); @@ -1941,7 +1941,7 @@ // unconditional validation doesn't use If-None-Match HttpRequest unconditionalValidation = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); // new response to unconditional validation provides new body - HttpResponse resp3 = make200Response(); + HttpResponse resp3 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag2\""); resp1.setHeader("Cache-Control", "max-age=3600"); @@ -1979,7 +1979,7 @@ HttpRequest initialRequest = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse cachedResponse = make200Response(); + HttpResponse cachedResponse = HttpTestUtils.make200Response(); cachedResponse.setHeader("Cache-Control", "max-age=3600"); cachedResponse.setHeader("ETag", "\"etag\""); @@ -1999,7 +1999,7 @@ conditionalResponse.setHeader("X-Extra", "junk"); // to be used if the cache generates an unconditional validation - HttpResponse unconditionalResponse = make200Response(); + HttpResponse unconditionalResponse = HttpTestUtils.make200Response(); unconditionalResponse.setHeader("Date", DateUtils.formatDate(inFiveSeconds)); unconditionalResponse.setHeader("ETag", "\"etag\""); @@ -2209,17 +2209,10 @@ Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); - Header[] hdrs = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(nineSecondsAgo)), - new BasicHeader("Cache-Control", "max-age=0"), - new BasicHeader("ETag", "\"etag\""), - new BasicHeader("Content-Length", "128") - }; - - byte[] bytes = new byte[128]; - (new Random()).nextBytes(bytes); - - CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes); + originResponse.setHeader("Date", DateUtils.formatDate(nineSecondsAgo)); + originResponse.setHeader("Cache-Control", "max-age=0"); + originResponse.setHeader("ETag", "\"etag\""); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, originResponse, eightSecondsAgo); impl = new CachingHttpClient(mockBackend, mockCache, params); @@ -2253,23 +2246,44 @@ } @Test - public void testMustReturnAFreshEnoughCacheEntryIfItHasIt() throws Exception { + public void testMustReturnACacheEntryIfClientOkWithStaleness() + throws Exception { - Date now = new Date(); + Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); - Header[] hdrs = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(nineSecondsAgo)), - new BasicHeader("Cache-Control", "max-age=3600"), - new BasicHeader("Content-Length", "128") - }; + originResponse.setHeader("Date", DateUtils.formatDate(nineSecondsAgo)); + originResponse.setHeader("Cache-Control", "max-age=5"); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, originResponse, eightSecondsAgo); + + impl = new CachingHttpClient(mockBackend, mockCache, params); + request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1); + request.setHeader("Cache-Control","max-stale=20"); + + mockCache.flushInvalidatedCacheEntriesFor(host, request); + EasyMock.expect(mockCache.getCacheEntry(host, request)).andReturn(entry); + + replayMocks(); + HttpResponse result = impl.execute(host, request); + verifyMocks(); + + Assert.assertEquals(200, result.getStatusLine().getStatusCode()); + + } + + @Test + public void testMustReturnAFreshEnoughCacheEntryIfItHasIt() throws Exception { - byte[] bytes = new byte[128]; - (new Random()).nextBytes(bytes); + Date now = new Date(); + Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); + Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); + Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); - CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes); + originResponse.setHeader("Date", DateUtils.formatDate(nineSecondsAgo)); + originResponse.setHeader("Cache-Control", "max-age=3600"); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, originResponse, eightSecondsAgo); impl = new CachingHttpClient(mockBackend, mockCache, params); request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1); @@ -2307,17 +2321,11 @@ Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); - Header[] hdrs = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(nineSecondsAgo)), - new BasicHeader("Cache-Control", "max-age=0"), - new BasicHeader("Content-Length", "128"), - new BasicHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)) - }; - - byte[] bytes = new byte[128]; - (new Random()).nextBytes(bytes); + originResponse.setHeader("Date", DateUtils.formatDate(nineSecondsAgo)); + originResponse.setHeader("Cache-Control", "max-age=0"); + originResponse.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); - CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, originResponse, eightSecondsAgo); impl = new CachingHttpClient(mockBackend, mockCache, params); request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1); @@ -2372,7 +2380,7 @@ Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 25 * 1000L); HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=5"); @@ -2437,7 +2445,7 @@ Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=5"); @@ -2510,16 +2518,9 @@ Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); - Header[] hdrs = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(nineSecondsAgo)), - new BasicHeader("Cache-Control", "max-age=3600"), - new BasicHeader("Content-Length", "128") - }; - - byte[] bytes = new byte[128]; - (new Random()).nextBytes(bytes); - - CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes); + originResponse.setHeader("Date", DateUtils.formatDate(nineSecondsAgo)); + originResponse.setHeader("Cache-Control", "max-age=3600"); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, originResponse, eightSecondsAgo); impl = new CachingHttpClient(mockBackend, mockCache, params); request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1); @@ -2560,29 +2561,22 @@ Date requestTime = new Date(thirtySixHoursAgo.getTime() - 1000L); Date responseTime = new Date(thirtySixHoursAgo.getTime() + 1000L); - Header[] hdrs = new Header[] { - new BasicHeader("Date", DateUtils.formatDate(thirtySixHoursAgo)), - new BasicHeader("Cache-Control", "public"), - new BasicHeader("Last-Modified", DateUtils.formatDate(oneYearAgo)), - new BasicHeader("Content-Length", "128") - }; - - byte[] bytes = new byte[128]; - (new Random()).nextBytes(bytes); - - CacheEntry entry = new CacheEntry(requestTime, responseTime, hdrs, bytes); + originResponse.setHeader("Date", DateUtils.formatDate(thirtySixHoursAgo)); + originResponse.setHeader("Cache-Control", "public"); + originResponse.setHeader("Last-Modified", DateUtils.formatDate(oneYearAgo)); + HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(requestTime, originResponse, responseTime); impl = new CachingHttpClient(mockBackend, mockCache, params); request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1); - HttpResponse validated = make200Response(); + HttpResponse validated = HttpTestUtils.make200Response(); validated.setHeader("Cache-Control", "public"); validated.setHeader("Last-Modified", DateUtils.formatDate(oneYearAgo)); validated.setHeader("Content-Length", "128"); - validated.setEntity(new ByteArrayEntity(bytes)); + validated.setEntity(originResponse.getEntity()); - HttpResponse reconstructed = make200Response(); + HttpResponse reconstructed = HttpTestUtils.make200Response(); Capture cap = new Capture(); @@ -2632,7 +2626,7 @@ // put an entry in the cache HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(inFiveSecond)); resp1.setHeader("ETag", "\"etag1\""); resp1.setHeader("Cache-Control", "max-age=3600"); @@ -2642,7 +2636,7 @@ HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); req2.setHeader("Cache-Control", "max-age=0,max-stale=0"); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Date", DateUtils.formatDate(now)); // older resp2.setHeader("ETag", "\"etag2\""); resp2.setHeader("Cache-Control", "max-age=3600"); @@ -2760,7 +2754,7 @@ public void testSubrangeGETMustUseStrongComparisonForCachedResponse() throws Exception { Date now = new Date(); HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("ETag", "\"etag\""); @@ -2800,7 +2794,7 @@ Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); @@ -2861,7 +2855,7 @@ * header fields in the request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 - */ + */ @Test public void testConditionalRequestWhereNotAllValidatorsMatchCannotBeServedFromCache() throws Exception { @@ -2870,7 +2864,7 @@ Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L); HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); @@ -2878,7 +2872,7 @@ HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); req2.setHeader("If-None-Match", "W/\"etag\""); - req2.setHeader("If-Unmodified-Since", DateUtils.formatDate(twentySecondsAgo)); + req2.setHeader("If-Modified-Since", DateUtils.formatDate(twentySecondsAgo)); // must hit the origin again for the second request EasyMock.expect( @@ -2957,7 +2951,7 @@ * already present: - Content-Location - Content-MD5 - ETag - Last-Modified */ private void testDoesNotModifyHeaderFromOrigin(String header, String value) throws Exception { - originResponse = make200Response(); + originResponse = HttpTestUtils.make200Response(); originResponse.setHeader(header, value); backendExpectsAnyRequest().andReturn(originResponse); @@ -3030,7 +3024,7 @@ HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - originResponse = make200Response(); + originResponse = HttpTestUtils.make200Response(); originResponse.setHeader("Cache-Control", "max-age=3600"); originResponse.setHeader(header, value); @@ -3420,7 +3414,7 @@ */ public void testCachedEntityBodyIsUsedForResponseAfter304Validation() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("ETag","\"etag\""); @@ -3478,7 +3472,7 @@ @Test public void testResponseIncludesCacheEntryEndToEndHeadersForResponseAfter304Validation() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("ETag","\"etag\""); decorateWithEndToEndHeaders(resp1); @@ -3513,7 +3507,7 @@ public void testUpdatedEndToEndHeadersFrom304ArePassedOnResponseAndUpdatedInCacheEntry() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("ETag","\"etag\""); decorateWithEndToEndHeaders(resp1); @@ -3564,7 +3558,7 @@ @Test public void testMultiHeadersAreSuccessfullyReplacedOn304Validation() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.addHeader("Cache-Control","max-age=3600"); resp1.addHeader("Cache-Control","public"); resp1.setHeader("ETag","\"etag\""); @@ -3623,7 +3617,7 @@ Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L); HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp1.setEntity(makeBody(50)); + resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); resp1.setHeader("Cache-Control","max-age=3600"); @@ -3636,7 +3630,7 @@ req2.setHeader("Range","bytes=50-127"); HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp2.setEntity(makeBody(78)); + resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("Server","MockServer/1.0"); @@ -3647,7 +3641,7 @@ HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - resp3.setEntity(makeBody(128)); + resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); @@ -3672,7 +3666,7 @@ req1.setHeader("Range","bytes=0-49"); HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp1.setEntity(makeBody(50)); + resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Server","MockServer/1.0"); @@ -3684,7 +3678,7 @@ req2.setHeader("Range","bytes=50-127"); HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp2.setEntity(makeBody(78)); + resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag1\""); @@ -3696,7 +3690,7 @@ HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - resp3.setEntity(makeBody(128)); + resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); @@ -3721,7 +3715,7 @@ req1.setHeader("Range","bytes=0-49"); HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp1.setEntity(makeBody(50)); + resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("ETag","\"etag1\""); @@ -3734,7 +3728,7 @@ req2.setHeader("Range","bytes=50-127"); HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp2.setEntity(makeBody(78)); + resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag2\""); @@ -3746,7 +3740,7 @@ HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - resp3.setEntity(makeBody(128)); + resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); @@ -3771,7 +3765,7 @@ req1.setHeader("Range","bytes=0-49"); HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp1.setEntity(makeBody(50)); + resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("ETag","\"etag1\""); @@ -3784,7 +3778,7 @@ req2.setHeader("Range","bytes=50-127"); HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp2.setEntity(makeBody(78)); + resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("Server","MockServer/1.0"); @@ -3796,7 +3790,7 @@ req3.setHeader("Range","bytes=0-49"); HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - resp3.setEntity(makeBody(128)); + resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); @@ -3822,7 +3816,7 @@ req1.setHeader("Range","bytes=0-49"); HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp1.setEntity(makeBody(50)); + resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Server","MockServer/1.0"); @@ -3834,7 +3828,7 @@ req2.setHeader("Range","bytes=50-127"); HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp2.setEntity(makeBody(78)); + resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag1\""); @@ -3847,7 +3841,7 @@ req3.setHeader("Range","bytes=0-49"); HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - resp3.setEntity(makeBody(128)); + resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); @@ -3873,7 +3867,7 @@ req1.setHeader("Range","bytes=0-49"); HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp1.setEntity(makeBody(50)); + resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Etag","\"etag1\""); @@ -3886,7 +3880,7 @@ req2.setHeader("Range","bytes=50-127"); HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp2.setEntity(makeBody(78)); + resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag2\""); @@ -3899,7 +3893,7 @@ req3.setHeader("Range","bytes=0-49"); HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - resp3.setEntity(makeBody(128)); + resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); @@ -3925,7 +3919,7 @@ req1.setHeader("Range","bytes=0-49"); HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp1.setEntity(makeBody(50)); + resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Etag","\"etag1\""); @@ -3938,7 +3932,7 @@ req2.setHeader("Range","bytes=50-127"); HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp2.setEntity(makeBody(78)); + resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag2\""); @@ -3951,7 +3945,7 @@ req3.setHeader("Range","bytes=50-127"); HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - resp3.setEntity(makeBody(128)); + resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); @@ -3976,7 +3970,7 @@ req1.setHeader("Range","bytes=0-49"); HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp1.setEntity(makeBody(50)); + resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Etag","\"etag1\""); @@ -3989,7 +3983,7 @@ req2.setHeader("Range","bytes=50-127"); HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); - resp2.setEntity(makeBody(78)); + resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag2\""); @@ -4002,7 +3996,7 @@ req3.setHeader("Range","bytes=0-49"); HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - resp3.setEntity(makeBody(128)); + resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); @@ -4032,7 +4026,7 @@ HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req1.setHeader("Accept-Encoding","gzip"); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag1\""); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Vary","Accept-Encoding"); @@ -4042,7 +4036,7 @@ HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req2.removeHeaders("Accept-Encoding"); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag","\"etag1\""); resp2.setHeader("Cache-Control","max-age=3600"); @@ -4065,7 +4059,7 @@ public void testCannotServeFromCacheForVaryStar() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag1\""); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Vary","*"); @@ -4074,7 +4068,7 @@ HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag","\"etag1\""); resp2.setHeader("Cache-Control","max-age=3600"); @@ -4116,7 +4110,7 @@ HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req1.setHeader("User-Agent","MyBrowser/1.0"); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag1\""); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Vary","User-Agent"); @@ -4131,7 +4125,7 @@ conditional.setHeader("User-Agent","MyBrowser/1.5"); conditional.setHeader("If-None-Match","\"etag1\""); - HttpResponse resp200 = make200Response(); + HttpResponse resp200 = HttpTestUtils.make200Response(); resp200.setHeader("ETag","\"etag1\""); resp200.setHeader("Vary","User-Agent"); @@ -4181,7 +4175,7 @@ */ @Test public void testIncompleteResponseMustNotBeReturnedToClientWithoutMarkingItAs206() throws Exception { - originResponse.setEntity(makeBody(128)); + originResponse.setEntity(HttpTestUtils.makeBody(128)); originResponse.setHeader("Content-Length","256"); backendExpectsAnyRequest().andReturn(originResponse); @@ -4212,7 +4206,7 @@ protected void testUnsafeOperationInvalidatesCacheForThatUri( HttpRequest unsafeReq) throws Exception, IOException { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public, max-age=3600"); backendExpectsAnyRequest().andReturn(resp1); @@ -4222,7 +4216,7 @@ backendExpectsAnyRequest().andReturn(resp2); HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp3 = make200Response(); + HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Cache-Control","public, max-age=3600"); // this origin request MUST happen due to invalidation @@ -4256,7 +4250,7 @@ protected void testUnsafeMethodInvalidatesCacheForHeaderUri( HttpRequest unsafeReq) throws Exception, IOException { HttpRequest req1 = new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public, max-age=3600"); backendExpectsAnyRequest().andReturn(resp1); @@ -4266,7 +4260,7 @@ backendExpectsAnyRequest().andReturn(resp2); HttpRequest req3 = new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1); - HttpResponse resp3 = make200Response(); + HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Cache-Control","public, max-age=3600"); // this origin request MUST happen due to invalidation @@ -4362,7 +4356,7 @@ HttpHost otherHost = new HttpHost("bar.example.com"); HttpRequest req1 = new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public, max-age=3600"); backendExpectsAnyRequest().andReturn(resp1); @@ -4470,7 +4464,7 @@ public void testPOSTRequestsAreWrittenThroughToOrigin() throws Exception { HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST","/",HttpVersion.HTTP_1_1); - req.setEntity(makeBody(128)); + req.setEntity(HttpTestUtils.makeBody(128)); req.setHeader("Content-Length","128"); testRequestIsWrittenThroughToOrigin(req); } @@ -4479,7 +4473,7 @@ public void testPUTRequestsAreWrittenThroughToOrigin() throws Exception { HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("PUT","/",HttpVersion.HTTP_1_1); - req.setEntity(makeBody(128)); + req.setEntity(HttpTestUtils.makeBody(128)); req.setHeader("Content-Length","128"); testRequestIsWrittenThroughToOrigin(req); } @@ -4590,7 +4584,7 @@ backendExpectsAnyRequest().andReturn(authorizedResponse); HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control","max-age=3600"); if (maxTimes > 0) { @@ -4609,7 +4603,7 @@ @Test public void testSharedCacheMustNotNormallyCacheAuthorizedResponses() throws Exception { - HttpResponse resp = make200Response(); + HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","max-age=3600"); resp.setHeader("ETag","\"etag\""); testSharedCacheRevalidatesAuthorizedResponse(resp, 1, 1); @@ -4618,7 +4612,7 @@ @Test public void testSharedCacheMayCacheAuthorizedResponsesWithSMaxAgeHeader() throws Exception { - HttpResponse resp = make200Response(); + HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","s-maxage=3600"); resp.setHeader("ETag","\"etag\""); testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1); @@ -4627,7 +4621,7 @@ @Test public void testSharedCacheMustRevalidateAuthorizedResponsesWhenSMaxAgeIsZero() throws Exception { - HttpResponse resp = make200Response(); + HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","s-maxage=0"); resp.setHeader("ETag","\"etag\""); testSharedCacheRevalidatesAuthorizedResponse(resp, 1, 1); @@ -4636,7 +4630,7 @@ @Test public void testSharedCacheMayCacheAuthorizedResponsesWithMustRevalidate() throws Exception { - HttpResponse resp = make200Response(); + HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","must-revalidate"); resp.setHeader("ETag","\"etag\""); testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1); @@ -4645,7 +4639,7 @@ @Test public void testSharedCacheMayCacheAuthorizedResponsesWithCacheControlPublic() throws Exception { - HttpResponse resp = make200Response(); + HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","public"); testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1); } @@ -4665,7 +4659,7 @@ HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req2.setHeader("Authorization",authorization2); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); Capture cap = new Capture(); EasyMock.expect(mockBackend.execute(EasyMock.eq(host), @@ -4689,7 +4683,7 @@ throws Exception { Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date",DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Cache-Control","s-maxage=5"); @@ -4702,7 +4696,7 @@ throws Exception { Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date",DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Cache-Control","maxage=5, must-revalidate"); @@ -4729,7 +4723,7 @@ Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control","max-age=5"); resp1.setHeader("Etag","\"etag\""); @@ -4738,7 +4732,7 @@ HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req2.setHeader("Cache-Control","max-stale=60"); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); Capture cap = new Capture(); EasyMock.expect(mockBackend.execute(EasyMock.eq(host), @@ -4809,13 +4803,13 @@ protected void testCacheIsNotUsedWhenRespondingToRequest(HttpRequest req) throws Exception { HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Etag","\"etag\""); resp1.setHeader("Cache-Control","max-age=3600"); backendExpectsAnyRequest().andReturn(resp1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Etag","\"etag2\""); resp2.setHeader("Cache-Control","max-age=1200"); @@ -4868,7 +4862,7 @@ HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req2.setHeader("Cache-Control","max-stale=3600"); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag","\"etag2\""); resp2.setHeader("Cache-Control","max-age=5, must-revalidate"); @@ -4900,7 +4894,7 @@ @Test public void testStaleEntryWithMustRevalidateIsNotUsedWithoutRevalidatingWithOrigin() throws Exception { - HttpResponse response = make200Response(); + HttpResponse response = HttpTestUtils.make200Response(); Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); response.setHeader("Date",DateUtils.formatDate(tenSecondsAgo)); @@ -4937,7 +4931,7 @@ @Test public void testGenerates504IfCannotRevalidateAMustRevalidateEntry() throws Exception { - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("ETag","\"etag\""); @@ -4957,7 +4951,7 @@ public void testStaleEntryWithProxyRevalidateOnSharedCacheIsNotUsedWithoutRevalidatingWithOrigin() throws Exception { if (impl.isSharedCache()) { - HttpResponse response = make200Response(); + HttpResponse response = HttpTestUtils.make200Response(); Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); response.setHeader("Date",DateUtils.formatDate(tenSecondsAgo)); @@ -4972,7 +4966,7 @@ public void testGenerates504IfSharedCacheCannotRevalidateAProxyRevalidateEntry() throws Exception { if (impl.isSharedCache()) { - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); Date now = new Date(); Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("ETag","\"etag\""); @@ -4994,13 +4988,13 @@ throws Exception { if (impl.isSharedCache()) { HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","private,max-age=3600"); backendExpectsAnyRequest().andReturn(resp1); HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); // this backend request MUST happen backendExpectsAnyRequest().andReturn(resp2); @@ -5016,14 +5010,14 @@ throws Exception { if (impl.isSharedCache()) { HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("X-Personal","stuff"); resp1.setHeader("Cache-Control","private=\"X-Personal\",s-maxage=3600"); backendExpectsAnyRequest().andReturn(resp1); HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); // this backend request MAY happen backendExpectsAnyRequest().andReturn(resp2).times(0,1); @@ -5048,14 +5042,14 @@ public void testNoCacheCannotSatisfyASubsequentRequestWithoutRevalidation() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Cache-Control","no-cache"); backendExpectsAnyRequest().andReturn(resp1); HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); // this MUST happen backendExpectsAnyRequest().andReturn(resp2); @@ -5070,7 +5064,7 @@ public void testNoCacheCannotSatisfyASubsequentRequestWithoutRevalidationEvenWithContraryIndications() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Cache-Control","no-cache,s-maxage=3600"); @@ -5078,7 +5072,7 @@ HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req2.setHeader("Cache-Control","max-stale=7200"); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); // this MUST happen backendExpectsAnyRequest().andReturn(resp2); @@ -5099,7 +5093,7 @@ public void testNoCacheOnFieldIsNotReturnedWithoutRevalidation() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("X-Stuff","things"); resp1.setHeader("Cache-Control","no-cache=\"X-Stuff\", max-age=3600"); @@ -5107,7 +5101,7 @@ backendExpectsAnyRequest().andReturn(resp1); HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag","\"etag\""); resp2.setHeader("X-Stuff","things"); resp2.setHeader("Cache-Control","no-cache=\"X-Stuff\",max-age=3600"); @@ -5264,13 +5258,13 @@ public void testCacheDoesNotAssumeContentLocationHeaderIndicatesAnotherCacheableResource() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public,max-age=3600"); resp1.setHeader("Etag","\"etag\""); resp1.setHeader("Content-Location","http://foo.example.com/bar"); HttpRequest req2 = new BasicHttpRequest("GET", "/bar", HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control","public,max-age=3600"); resp2.setHeader("Etag","\"etag\""); @@ -5314,13 +5308,13 @@ private void testInvalidExpiresHeaderIsTreatedAsStale( final String expiresHeader) throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Expires", expiresHeader); HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); backendExpectsAnyRequest().andReturn(resp1); // second request to origin MUST happen @@ -5353,13 +5347,13 @@ public void testExpiresHeaderEqualToDateHeaderIsTreatedAsStale() throws Exception { HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Expires", resp1.getFirstHeader("Date").getValue()); HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); - HttpResponse resp2 = make200Response(); + HttpResponse resp2 = HttpTestUtils.make200Response(); backendExpectsAnyRequest().andReturn(resp1); // second request to origin MUST happen @@ -5661,7 +5655,7 @@ Date now = new Date(); Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L); - HttpResponse resp1 = make200Response(); + HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(twentySecondsAgo)); resp1.setHeader("Cache-Control","public,max-age=5"); resp1.setHeader("ETag", "\"etag1\""); diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestURIExtractor.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestURIExtractor.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestURIExtractor.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestURIExtractor.java 2010-09-11 17:10:30.000000000 -0400 @@ -30,6 +30,7 @@ import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; +import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.HttpGet; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; @@ -46,13 +47,13 @@ URIExtractor extractor; private HttpHost host; - private CacheEntry mockEntry; + private HttpCacheEntry mockEntry; private HttpRequest mockRequest; @Before public void setUp() throws Exception { host = new HttpHost("foo.example.com"); - mockEntry = EasyMock.createMock(CacheEntry.class); + mockEntry = EasyMock.createMock(HttpCacheEntry.class); mockRequest = EasyMock.createMock(HttpRequest.class); extractor = new URIExtractor(); } diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java 2010-09-11 08:32:18.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java 2010-09-11 17:10:30.000000000 -0400 @@ -39,7 +39,7 @@ import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.impl.client.cache.CacheConfig; -import org.apache.http.impl.client.cache.CacheEntry; +import org.apache.http.impl.client.cache.HttpTestUtils; import org.easymock.EasyMock; import org.junit.Test; @@ -68,9 +68,9 @@ } @Test - public void testCachePut() throws IOException { + public void testCachePut() throws Exception { final String key = "foo"; - final HttpCacheEntry value = new CacheEntry(); + final HttpCacheEntry value = HttpTestUtils.makeCacheEntry(); Element e = new Element(key, new byte[]{}); @@ -96,9 +96,9 @@ } @Test - public void testCacheGet() throws IOException { + public void testCacheGet() throws Exception { final String key = "foo"; - final HttpCacheEntry cachedValue = new CacheEntry(); + final HttpCacheEntry cachedValue = HttpTestUtils.makeCacheEntry(); Element element = new Element(key, new byte[]{}); @@ -126,9 +126,9 @@ } @Test - public void testCacheUpdateNullEntry() throws IOException, HttpCacheUpdateException { + public void testCacheUpdateNullEntry() throws Exception { final String key = "foo"; - final HttpCacheEntry updatedValue = new CacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); Element element = new Element(key, new byte[]{}); @@ -152,10 +152,10 @@ } @Test - public void testCacheUpdate() throws IOException, HttpCacheUpdateException { + public void testCacheUpdate() throws Exception { final String key = "foo"; - final HttpCacheEntry existingValue = new CacheEntry(); - final HttpCacheEntry updatedValue = new CacheEntry(); + final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); Element existingElement = new Element(key, new byte[]{}); @@ -180,10 +180,10 @@ } @Test - public void testSingleCacheUpdateRetry() throws IOException, HttpCacheUpdateException { + public void testSingleCacheUpdateRetry() throws Exception { final String key = "foo"; - final HttpCacheEntry existingValue = new CacheEntry(); - final HttpCacheEntry updatedValue = new CacheEntry(); + final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); Element existingElement = new Element(key, new byte[]{}); @@ -212,10 +212,10 @@ } @Test - public void testCacheUpdateFail() throws IOException, HttpCacheUpdateException { + public void testCacheUpdateFail() throws Exception { final String key = "foo"; - final HttpCacheEntry existingValue = new CacheEntry(); - final HttpCacheEntry updatedValue = new CacheEntry(); + final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); Element existingElement = new Element(key, new byte[]{}); diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheProtocolRequirements.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheProtocolRequirements.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheProtocolRequirements.java 2010-09-11 08:32:18.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheProtocolRequirements.java 2010-09-11 17:10:30.000000000 -0400 @@ -74,7 +74,7 @@ request = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1); - originResponse = make200Response(); + originResponse = HttpTestUtils.make200Response(); params = new CacheConfig(); params.setMaxObjectSizeBytes(MAX_BYTES); diff -ruN --exclude .svn httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.java httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.java --- httpcomponents-client-trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.java 2010-09-11 08:32:19.000000000 -0400 +++ httpcomponents-client-modified/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.java 2010-09-11 17:10:30.000000000 -0400 @@ -29,8 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; - import junit.framework.TestCase; import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; @@ -41,7 +39,7 @@ import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.impl.client.cache.CacheConfig; -import org.apache.http.impl.client.cache.CacheEntry; +import org.apache.http.impl.client.cache.HttpTestUtils; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; @@ -72,9 +70,9 @@ } @Test - public void testCachePut() throws IOException, HttpCacheUpdateException { + public void testCachePut() throws Exception { final String url = "foo"; - final HttpCacheEntry value = new CacheEntry(); + final HttpCacheEntry value = HttpTestUtils.makeCacheEntry(); mockSerializer.writeTo(EasyMock.isA(HttpCacheEntry.class), EasyMock .isA(OutputStream.class)); EasyMock.expect( @@ -86,10 +84,9 @@ } @Test - public void testCacheGet() throws UnsupportedEncodingException, - IOException, HttpCacheUpdateException { + public void testCacheGet() throws Exception { final String url = "foo"; - final HttpCacheEntry cacheEntry = new CacheEntry(); + final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(); EasyMock.expect(mockMemcachedClient.get(url)).andReturn(new byte[] {}); EasyMock.expect( mockSerializer.readFrom(EasyMock.isA(InputStream.class))) @@ -123,10 +120,9 @@ } @Test - public void testCacheUpdateNullEntry() throws IOException, - HttpCacheUpdateException { + public void testCacheUpdateNullEntry() throws Exception { final String url = "foo"; - final HttpCacheEntry updatedValue = new CacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(HttpCacheEntry old) { @@ -152,10 +148,10 @@ } @Test - public void testCacheUpdate() throws IOException, HttpCacheUpdateException { + public void testCacheUpdate() throws Exception { final String url = "foo"; - final HttpCacheEntry existingValue = new CacheEntry(); - final HttpCacheEntry updatedValue = new CacheEntry(); + final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); CASValue v = new CASValue(1234, new byte[] {}); @@ -186,11 +182,10 @@ } @Test - public void testSingleCacheUpdateRetry() throws IOException, - HttpCacheUpdateException { + public void testSingleCacheUpdateRetry() throws Exception { final String url = "foo"; - final HttpCacheEntry existingValue = new CacheEntry(); - final HttpCacheEntry updatedValue = new CacheEntry(); + final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); CASValue v = new CASValue(1234, new byte[] {}); HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { @@ -226,11 +221,11 @@ } @Test - public void testCacheUpdateFail() throws IOException, + public void testCacheUpdateFail() throws Exception, HttpCacheUpdateException { final String url = "foo"; - final HttpCacheEntry existingValue = new CacheEntry(); - final HttpCacheEntry updatedValue = new CacheEntry(); + final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); CASValue v = new CASValue(1234, new byte[] {}); HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { Binary files httpcomponents-client-trunk/httpclient-cache/target/classes/org/apache/http/client/cache/HttpCacheEntry.class and httpcomponents-client-modified/httpclient-cache/target/classes/org/apache/http/client/cache/HttpCacheEntry.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/classes/org/apache/http/impl/client/cache/CacheValidityPolicy.class and httpcomponents-client-modified/httpclient-cache/target/classes/org/apache/http/impl/client/cache/CacheValidityPolicy.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/classes/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.class and httpcomponents-client-modified/httpclient-cache/target/classes/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/classes/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.class and httpcomponents-client-modified/httpclient-cache/target/classes/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/classes/org/apache/http/impl/client/cache/CachingHttpClient.class and httpcomponents-client-modified/httpclient-cache/target/classes/org/apache/http/impl/client/cache/CachingHttpClient.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$1.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$1.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$2.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$2.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$3.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$3.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$4.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$4.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$5.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$5.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$6.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$6.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$7.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry$7.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/client/cache/TestHttpCacheEntry.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/AbstractProtocolTest.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/AbstractProtocolTest.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/CacheEntry.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/CacheEntry.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/HttpTestUtils.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/HttpTestUtils.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestBasicHttpCache.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestBasicHttpCache.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheEntry.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheEntry.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheEntryUpdater.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheEntryUpdater.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheInvalidator.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheInvalidator.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$1.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$1.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$2.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$2.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$3.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$3.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$4.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$4.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$5.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$5.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$6.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$6.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$7.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$7.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$8.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy$8.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCacheValidityPolicy.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator$1.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator$1.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator$2.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator$2.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator$3.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator$3.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker$1.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker$1.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker$2.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker$2.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$1.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$1.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$2.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$2.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$3.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$3.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$4.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$4.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$5.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$5.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$6.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$6.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$7.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient$7.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestCachingHttpClient.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestProtocolRecommendations.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestProtocolRecommendations.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestProtocolRequirements.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestProtocolRequirements.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$1.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$1.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$2.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$2.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$3.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$3.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$4.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$4.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$5.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$5.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$6.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor$6.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/TestURIExtractor.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/ehcache/TestEhcacheProtocolRequirements.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/ehcache/TestEhcacheProtocolRequirements.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage$1.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage$1.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage$2.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage$2.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage$3.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage$3.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage$4.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage$4.class differ Binary files httpcomponents-client-trunk/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.class and httpcomponents-client-modified/httpclient-cache/target/test-classes/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.class differ