You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2023/05/21 13:51:39 UTC
[httpcomponents-client] 03/03: Parse Cache-Control request and response headers only once
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch 5.3.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git
commit 8a20b7a275be0d82cd6c9badac1c362623d90c93
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun May 21 12:25:38 2023 +0200
Parse Cache-Control request and response headers only once
---
.../client5/http/impl/cache/AsyncCachingExec.java | 59 ++-
.../http/impl/cache/CacheValidityPolicy.java | 57 ++-
.../http/impl/cache/CacheableRequestPolicy.java | 3 +-
.../cache/CachedResponseSuitabilityChecker.java | 55 ++-
.../hc/client5/http/impl/cache/CachingExec.java | 57 +--
.../client5/http/impl/cache/CachingExecBase.java | 58 +--
.../http/impl/cache/ConditionalRequestBuilder.java | 4 +-
.../http/impl/cache/ResponseCacheControl.java | 18 +-
.../http/impl/cache/ResponseCachingPolicy.java | 133 ++----
.../http/impl/cache/TestCacheValidityPolicy.java | 284 ++++++------
.../impl/cache/TestCacheableRequestPolicy.java | 102 ++---
.../TestCachedResponseSuitabilityChecker.java | 142 ++++--
.../http/impl/cache/TestCachingExecChain.java | 18 +-
.../impl/cache/TestConditionalRequestBuilder.java | 41 +-
.../http/impl/cache/TestResponseCachingPolicy.java | 480 +++++++++++----------
15 files changed, 765 insertions(+), 746 deletions(-)
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
index 884842eb6..8234ef002 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
@@ -239,7 +239,9 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
requestCompliance.makeRequestCompliant(request);
request.addHeader(HttpHeaders.VIA,via);
- if (!cacheableRequestPolicy.isServableFromCache(request)) {
+ final RequestCacheControl requestCacheControl = CacheControlHeaderParser.INSTANCE.parse(request);
+
+ if (!cacheableRequestPolicy.isServableFromCache(requestCacheControl, request)) {
LOG.debug("Request is not servable from cache");
operation.setDependency(responseCache.flushCacheEntriesInvalidatedByRequest(target, request, new FutureCallback<Boolean>() {
@@ -266,9 +268,10 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
public void completed(final HttpCacheEntry entry) {
if (entry == null) {
LOG.debug("Cache miss");
- handleCacheMiss(target, request, entityProducer, scope, chain, asyncExecCallback);
+ handleCacheMiss(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback);
} else {
- handleCacheHit(target, request, entityProducer, scope, chain, asyncExecCallback, entry);
+ final ResponseCacheControl responseCacheControl = CacheControlHeaderParser.INSTANCE.parse(entry);
+ handleCacheHit(requestCacheControl, responseCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback, entry);
}
}
@@ -488,7 +491,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
}
});
- final boolean cacheable = responseCachingPolicy.isResponseCacheable(request, backendResponse);
+ final ResponseCacheControl responseCacheControl = CacheControlHeaderParser.INSTANCE.parse(backendResponse);
+ final boolean cacheable = responseCachingPolicy.isResponseCacheable(responseCacheControl, request, backendResponse);
if (cacheable) {
cachingConsumerRef.set(new CachingAsyncDataConsumer(asyncExecCallback, backendResponse, entityDetails));
storeRequestIfModifiedSinceFor304Response(request, backendResponse);
@@ -612,6 +616,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
}
private void handleCacheHit(
+ final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl,
final HttpHost target,
final HttpRequest request,
final AsyncEntityProducer entityProducer,
@@ -623,28 +629,30 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
recordCacheHit(target, request);
final Instant now = getCurrentDate();
- if (requestContainsNoCacheDirective(request)) {
+ if (requestCacheControl.isNoCache()) {
// Revalidate with the server due to no-cache directive in response
if (LOG.isDebugEnabled()) {
LOG.debug("Revalidating with server due to no-cache directive in response.");
}
- revalidateCacheEntry(target, request, entityProducer, scope, chain, asyncExecCallback, entry);
+ revalidateCacheEntry(requestCacheControl, responseCacheControl,
+ target, request, entityProducer, scope, chain, asyncExecCallback, entry);
return;
}
- if (suitabilityChecker.canCachedResponseBeUsed(request, entry, now)) {
- if (responseCachingPolicy.responseContainsNoCacheDirective(entry)) {
+ if (suitabilityChecker.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now)) {
+ if (responseCachingPolicy.responseContainsNoCacheDirective(responseCacheControl, entry)) {
// Revalidate with the server due to no-cache directive in response
- revalidateCacheEntry(target, request, entityProducer, scope, chain, asyncExecCallback, entry);
+ revalidateCacheEntry(requestCacheControl, responseCacheControl,
+ target, request, entityProducer, scope, chain, asyncExecCallback, entry);
return;
}
LOG.debug("Cache hit");
try {
- final SimpleHttpResponse cacheResponse = generateCachedResponse(request, context, entry, now);
+ final SimpleHttpResponse cacheResponse = generateCachedResponse(responseCacheControl, request, context, entry, now);
triggerResponse(cacheResponse, scope, asyncExecCallback);
} catch (final ResourceIOException ex) {
recordCacheFailure(target, request);
- if (!mayCallBackend(request)) {
+ if (!mayCallBackend(requestCacheControl)) {
final SimpleHttpResponse cacheResponse = generateGatewayTimeout(context);
triggerResponse(cacheResponse, scope, asyncExecCallback);
} else {
@@ -656,20 +664,20 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
}
}
}
- } else if (!mayCallBackend(request)) {
+ } else if (!mayCallBackend(requestCacheControl)) {
LOG.debug("Cache entry not suitable but only-if-cached requested");
final SimpleHttpResponse cacheResponse = generateGatewayTimeout(context);
triggerResponse(cacheResponse, scope, asyncExecCallback);
} else if (!(entry.getStatus() == HttpStatus.SC_NOT_MODIFIED && !suitabilityChecker.isConditional(request))) {
LOG.debug("Revalidating cache entry");
- final boolean staleIfErrorEnabled = responseCachingPolicy.isStaleIfErrorEnabled(entry);
+ final boolean staleIfErrorEnabled = responseCachingPolicy.isStaleIfErrorEnabled(responseCacheControl, entry);
if (cacheRevalidator != null
- && !staleResponseNotAllowed(request, entry, now)
- && validityPolicy.mayReturnStaleWhileRevalidating(entry, now)
+ && !staleResponseNotAllowed(requestCacheControl, responseCacheControl, entry, now)
+ && validityPolicy.mayReturnStaleWhileRevalidating(responseCacheControl, entry, now)
|| staleIfErrorEnabled) {
LOG.debug("Serving stale with asynchronous revalidation");
try {
- final SimpleHttpResponse cacheResponse = generateCachedResponse(request, context, entry, now);
+ final SimpleHttpResponse cacheResponse = generateCachedResponse(responseCacheControl, request, context, entry, now);
final String exchangeId = ExecSupport.getNextExchangeId();
context.setExchangeId(exchangeId);
final AsyncExecChain.Scope fork = new AsyncExecChain.Scope(
@@ -684,7 +692,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
cacheRevalidator.revalidateCacheEntry(
responseCache.generateKey(target, request, entry),
asyncExecCallback,
- asyncExecCallback1 -> revalidateCacheEntry(target, request, entityProducer, fork, chain, asyncExecCallback1, entry));
+ asyncExecCallback1 -> revalidateCacheEntry(requestCacheControl, responseCacheControl,
+ target, request, entityProducer, fork, chain, asyncExecCallback1, entry));
triggerResponse(cacheResponse, scope, asyncExecCallback);
} catch (final ResourceIOException ex) {
if (staleIfErrorEnabled) {
@@ -692,7 +701,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
LOG.debug("Serving stale response due to IOException and stale-if-error enabled");
}
try {
- final SimpleHttpResponse cacheResponse = generateCachedResponse(request, context, entry, now);
+ final SimpleHttpResponse cacheResponse = generateCachedResponse(responseCacheControl,
+ request, context, entry, now);
triggerResponse(cacheResponse, scope, asyncExecCallback);
} catch (final ResourceIOException ex2) {
if (LOG.isDebugEnabled()) {
@@ -705,7 +715,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
}
}
} else {
- revalidateCacheEntry(target, request, entityProducer, scope, chain, asyncExecCallback, entry);
+ revalidateCacheEntry(requestCacheControl, responseCacheControl,
+ target, request, entityProducer, scope, chain, asyncExecCallback, entry);
}
} else {
LOG.debug("Cache entry not usable; calling backend");
@@ -714,6 +725,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
}
void revalidateCacheEntry(
+ final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl,
final HttpHost target,
final HttpRequest request,
final AsyncEntityProducer entityProducer,
@@ -723,6 +736,7 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
final HttpCacheEntry cacheEntry) {
final Instant requestDate = getCurrentDate();
final HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(
+ responseCacheControl,
BasicRequestBuilder.copy(scope.originalRequest).build(),
cacheEntry);
chainProceed(conditionalRequest, entityProducer, scope, chain, new AsyncExecCallback() {
@@ -791,8 +805,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
return new AsyncExecCallbackWrapper(asyncExecCallback, () -> triggerUpdatedCacheEntryResponse(backendResponse, responseDate));
}
if (staleIfErrorAppliesTo(statusCode)
- && !staleResponseNotAllowed(request, cacheEntry, getCurrentDate())
- && validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
+ && !staleResponseNotAllowed(requestCacheControl, responseCacheControl, cacheEntry, getCurrentDate())
+ && validityPolicy.mayReturnStaleIfError(requestCacheControl, responseCacheControl, cacheEntry, responseDate)) {
return new AsyncExecCallbackWrapper(asyncExecCallback, this::triggerResponseStaleCacheEntry);
}
return new BackendResponseHandler(target, conditionalRequest, requestDate, responseDate, scope, asyncExecCallback);
@@ -897,6 +911,7 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
}
private void handleCacheMiss(
+ final RequestCacheControl requestCacheControl,
final HttpHost target,
final HttpRequest request,
final AsyncEntityProducer entityProducer,
@@ -905,7 +920,7 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
final AsyncExecCallback asyncExecCallback) {
recordCacheMiss(target, request);
- if (mayCallBackend(request)) {
+ if (mayCallBackend(requestCacheControl)) {
final CancellableDependency operation = scope.cancellableDependency;
operation.setDependency(responseCache.getVariantCacheEntriesWithEtags(
target,
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheValidityPolicy.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheValidityPolicy.java
index 456bb834a..633506a02 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheValidityPolicy.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheValidityPolicy.java
@@ -34,7 +34,6 @@ import org.apache.hc.client5.http.cache.Resource;
import org.apache.hc.client5.http.utils.DateUtils;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.util.TimeValue;
class CacheValidityPolicy {
@@ -50,8 +49,8 @@ class CacheValidityPolicy {
return TimeValue.ofSeconds(getCorrectedInitialAge(entry).toSeconds() + getResidentTime(entry, now).toSeconds());
}
- public TimeValue getFreshnessLifetime(final HttpCacheEntry entry) {
- final long maxAge = getMaxAge(entry);
+ public TimeValue getFreshnessLifetime(final ResponseCacheControl responseCacheControl, final HttpCacheEntry entry) {
+ final long maxAge = getMaxAge(responseCacheControl);
if (maxAge > -1) {
return TimeValue.ofSeconds(maxAge);
}
@@ -69,8 +68,9 @@ class CacheValidityPolicy {
return TimeValue.ofSeconds(diff.getSeconds());
}
- public boolean isResponseFresh(final HttpCacheEntry entry, final Instant now) {
- return getCurrentAge(entry, now).compareTo(getFreshnessLifetime(entry)) == -1;
+ public boolean isResponseFresh(final ResponseCacheControl responseCacheControl, final HttpCacheEntry entry,
+ final Instant now) {
+ return getCurrentAge(entry, now).compareTo(getFreshnessLifetime(responseCacheControl, entry)) == -1;
}
/**
@@ -114,36 +114,28 @@ class CacheValidityPolicy {
|| entry.getFirstHeader(HttpHeaders.LAST_MODIFIED) != null;
}
- public boolean mustRevalidate(final HttpCacheEntry entry) {
- final ResponseCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(entry);
- return cacheControl.isMustRevalidate();
- }
-
- public boolean proxyRevalidate(final HttpCacheEntry entry) {
- final ResponseCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(entry);
- return cacheControl.isProxyRevalidate();
- }
-
- public boolean mayReturnStaleWhileRevalidating(final HttpCacheEntry entry, final Instant now) {
- final ResponseCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(entry);
- if (cacheControl.getStaleWhileRevalidate() >= 0) {
- final TimeValue staleness = getStaleness(entry, now);
- if (staleness.compareTo(TimeValue.ofSeconds(cacheControl.getStaleWhileRevalidate())) <= 0) {
+ public boolean mayReturnStaleWhileRevalidating(final ResponseCacheControl responseCacheControl,
+ final HttpCacheEntry entry, final Instant now) {
+ if (responseCacheControl.getStaleWhileRevalidate() >= 0) {
+ final TimeValue staleness = getStaleness(responseCacheControl, entry, now);
+ if (staleness.compareTo(TimeValue.ofSeconds(responseCacheControl.getStaleWhileRevalidate())) <= 0) {
return true;
}
}
return false;
}
- public boolean mayReturnStaleIfError(final HttpRequest request, final HttpCacheEntry entry, final Instant now) {
- final RequestCacheControl requestCacheControl = CacheControlHeaderParser.INSTANCE.parse(request);
- final ResponseCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(entry);
- final TimeValue staleness = getStaleness(entry, now);
- return mayReturnStaleIfError(requestCacheControl, staleness) || mayReturnStaleIfError(cacheControl, staleness);
+ public boolean mayReturnStaleIfError(final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl, final HttpCacheEntry entry,
+ final Instant now) {
+ final TimeValue staleness = getStaleness(responseCacheControl, entry, now);
+ return mayReturnStaleIfError(requestCacheControl, staleness) ||
+ mayReturnStaleIfError(responseCacheControl, staleness);
}
- private boolean mayReturnStaleIfError(final CacheControl cacheControl, final TimeValue staleness) {
- return cacheControl.getStaleIfError() >= 0 && staleness.compareTo(TimeValue.ofSeconds(cacheControl.getStaleIfError())) <= 0;
+ private boolean mayReturnStaleIfError(final CacheControl responseCacheControl, final TimeValue staleness) {
+ return responseCacheControl.getStaleIfError() >= 0 &&
+ staleness.compareTo(TimeValue.ofSeconds(responseCacheControl.getStaleIfError())) <= 0;
}
/**
@@ -222,10 +214,9 @@ class CacheValidityPolicy {
}
- protected long getMaxAge(final HttpCacheEntry entry) {
- final ResponseCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(entry);
- final long maxAge = cacheControl.getMaxAge();
- final long sharedMaxAge = cacheControl.getSharedMaxAge();
+ protected long getMaxAge(final ResponseCacheControl responseCacheControl) {
+ final long maxAge = responseCacheControl.getMaxAge();
+ final long sharedMaxAge = responseCacheControl.getSharedMaxAge();
if (sharedMaxAge == -1) {
return maxAge;
} else if (maxAge == -1) {
@@ -235,9 +226,9 @@ class CacheValidityPolicy {
}
}
- public TimeValue getStaleness(final HttpCacheEntry entry, final Instant now) {
+ public TimeValue getStaleness(final ResponseCacheControl responseCacheControl, final HttpCacheEntry entry, final Instant now) {
final TimeValue age = getCurrentAge(entry, now);
- final TimeValue freshness = getFreshnessLifetime(entry);
+ final TimeValue freshness = getFreshnessLifetime(responseCacheControl, entry);
if (age.compareTo(freshness) <= 0) {
return TimeValue.ZERO_MILLISECONDS;
}
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheableRequestPolicy.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheableRequestPolicy.java
index eef1034cd..d75da8fda 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheableRequestPolicy.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheableRequestPolicy.java
@@ -48,7 +48,7 @@ class CacheableRequestPolicy {
* an HttpRequest
* @return boolean Is it possible to serve this request from cache
*/
- public boolean isServableFromCache(final HttpRequest request) {
+ public boolean isServableFromCache(final RequestCacheControl cacheControl, final HttpRequest request) {
final String method = request.getMethod();
final ProtocolVersion pv = request.getVersion() != null ? request.getVersion() : HttpVersion.DEFAULT;
@@ -69,7 +69,6 @@ class CacheableRequestPolicy {
return false;
}
- final RequestCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(request);
if (cacheControl.isNoStore()) {
LOG.debug("Request with no-store is not serveable from cache");
return false;
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedResponseSuitabilityChecker.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedResponseSuitabilityChecker.java
index abb6fc559..e63cd7da7 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedResponseSuitabilityChecker.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedResponseSuitabilityChecker.java
@@ -70,56 +70,50 @@ class CachedResponseSuitabilityChecker {
this(new CacheValidityPolicy(), config);
}
- private boolean isFreshEnough(final HttpCacheEntry entry, final HttpRequest request, final Instant now) {
- if (validityStrategy.isResponseFresh(entry, now)) {
+ private boolean isFreshEnough(final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl, final HttpCacheEntry entry,
+ final Instant now) {
+ if (validityStrategy.isResponseFresh(responseCacheControl, entry, now)) {
return true;
}
if (useHeuristicCaching &&
validityStrategy.isResponseHeuristicallyFresh(entry, now, heuristicCoefficient, heuristicDefaultLifetime)) {
return true;
}
- if (originInsistsOnFreshness(entry)) {
+ if (originInsistsOnFreshness(responseCacheControl)) {
return false;
}
- final RequestCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(request);
- if (cacheControl.getMaxStale() == -1) {
+ if (requestCacheControl.getMaxStale() == -1) {
return false;
}
- return (cacheControl.getMaxStale() > validityStrategy.getStaleness(entry, now).toSeconds());
+ return (requestCacheControl.getMaxStale() > validityStrategy.getStaleness(responseCacheControl, entry, now).toSeconds());
}
- private boolean originInsistsOnFreshness(final HttpCacheEntry entry) {
- if (validityStrategy.mustRevalidate(entry)) {
+ private boolean originInsistsOnFreshness(final ResponseCacheControl responseCacheControl) {
+ if (responseCacheControl.isMustRevalidate()) {
return true;
}
if (!sharedCache) {
return false;
}
- final ResponseCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(entry);
- return cacheControl.isProxyRevalidate() || cacheControl.getSharedMaxAge() >= 0;
+ return responseCacheControl.isProxyRevalidate() || responseCacheControl.getSharedMaxAge() >= 0;
}
/**
* Determine if I can utilize a {@link HttpCacheEntry} to respond to the given
* {@link HttpRequest}
- *
- * @param request
- * {@link HttpRequest}
- * @param entry
- * {@link HttpCacheEntry}
- * @param now
- * Right now in time
- * @return boolean yes/no answer
* @since 5.3
*/
- public boolean canCachedResponseBeUsed(final HttpRequest request, final HttpCacheEntry entry, final Instant now) {
+ public boolean canCachedResponseBeUsed(final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl, final HttpRequest request,
+ final HttpCacheEntry entry, final Instant now) {
if (isGetRequestWithHeadCacheEntry(request, entry)) {
LOG.debug("Cache entry created by HEAD request cannot be used to serve GET request");
return false;
}
- if (!isFreshEnough(entry, request, now)) {
+ if (!isFreshEnough(requestCacheControl, responseCacheControl, entry, now)) {
LOG.debug("Cache entry is not fresh enough");
return false;
}
@@ -149,38 +143,37 @@ class CachedResponseSuitabilityChecker {
"request method, entity or a 204 response");
return false;
}
- final RequestCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(request);
- if (cacheControl.isNoCache()) {
+ if (requestCacheControl.isNoCache()) {
LOG.debug("Response contained NO CACHE directive, cache was not suitable");
return false;
}
- if (cacheControl.isNoStore()) {
+ if (requestCacheControl.isNoStore()) {
LOG.debug("Response contained NO STORE directive, cache was not suitable");
return false;
}
- if (cacheControl.getMaxAge() >= 0) {
- if (validityStrategy.getCurrentAge(entry, now).toSeconds() > cacheControl.getMaxAge()) {
+ if (requestCacheControl.getMaxAge() >= 0) {
+ if (validityStrategy.getCurrentAge(entry, now).toSeconds() > requestCacheControl.getMaxAge()) {
LOG.debug("Response from cache was not suitable due to max age");
return false;
}
}
- if (cacheControl.getMaxStale() >= 0) {
- if (validityStrategy.getFreshnessLifetime(entry).toSeconds() > cacheControl.getMaxStale()) {
+ if (requestCacheControl.getMaxStale() >= 0) {
+ if (validityStrategy.getFreshnessLifetime(responseCacheControl, entry).toSeconds() > requestCacheControl.getMaxStale()) {
LOG.debug("Response from cache was not suitable due to max stale freshness");
return false;
}
}
- if (cacheControl.getMinFresh() >= 0) {
- if (cacheControl.getMinFresh() == 0) {
+ if (requestCacheControl.getMinFresh() >= 0) {
+ if (requestCacheControl.getMinFresh() == 0) {
return false;
}
final TimeValue age = validityStrategy.getCurrentAge(entry, now);
- final TimeValue freshness = validityStrategy.getFreshnessLifetime(entry);
- if (freshness.toSeconds() - age.toSeconds() < cacheControl.getMinFresh()) {
+ final TimeValue freshness = validityStrategy.getFreshnessLifetime(responseCacheControl, entry);
+ if (freshness.toSeconds() - age.toSeconds() < requestCacheControl.getMinFresh()) {
LOG.debug("Response from cache was not suitable due to min fresh " +
"freshness requirement");
return false;
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
index b89c834af..9d39cc7e5 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
@@ -217,7 +217,8 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
requestCompliance.makeRequestCompliant(request);
request.addHeader(HttpHeaders.VIA, via);
- if (!cacheableRequestPolicy.isServableFromCache(request)) {
+ final RequestCacheControl requestCacheControl = CacheControlHeaderParser.INSTANCE.parse(request);
+ if (!cacheableRequestPolicy.isServableFromCache(requestCacheControl, request)) {
LOG.debug("Request is not servable from cache");
responseCache.flushCacheEntriesInvalidatedByRequest(target, request);
return callBackend(target, request, scope, chain);
@@ -226,9 +227,10 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
final HttpCacheEntry entry = responseCache.getCacheEntry(target, request);
if (entry == null) {
LOG.debug("Cache miss");
- return handleCacheMiss(target, request, scope, chain);
+ return handleCacheMiss(target, request, requestCacheControl, scope, chain);
} else {
- return handleCacheHit(target, request, scope, chain, entry);
+ final ResponseCacheControl responseCacheControl = CacheControlHeaderParser.INSTANCE.parse(entry);
+ return handleCacheHit(requestCacheControl, responseCacheControl, target, request, scope, chain, entry);
}
}
@@ -276,6 +278,8 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
}
private ClassicHttpResponse handleCacheHit(
+ final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl,
final HttpHost target,
final ClassicHttpRequest request,
final ExecChain.Scope scope,
@@ -286,41 +290,40 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
recordCacheHit(target, request);
final Instant now = getCurrentDate();
-
- if (requestContainsNoCacheDirective(request)) {
+ if (requestCacheControl.isNoCache()) {
// Revalidate with the server
- return revalidateCacheEntry(target, request, scope, chain, entry);
+ return revalidateCacheEntry(requestCacheControl, responseCacheControl, target, request, scope, chain, entry);
}
- if (suitabilityChecker.canCachedResponseBeUsed(request, entry, now)) {
- if (responseCachingPolicy.responseContainsNoCacheDirective(entry)) {
+ if (suitabilityChecker.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now)) {
+ if (responseCachingPolicy.responseContainsNoCacheDirective(responseCacheControl, entry)) {
// Revalidate with the server due to no-cache directive in response
if (LOG.isDebugEnabled()) {
LOG.debug("Revalidating with server due to no-cache directive in response.");
}
- return revalidateCacheEntry(target, request, scope, chain, entry);
+ return revalidateCacheEntry(requestCacheControl, responseCacheControl, target, request, scope, chain, entry);
}
LOG.debug("Cache hit");
try {
- return convert(generateCachedResponse(request, context, entry, now), scope);
+ return convert(generateCachedResponse(responseCacheControl, request, context, entry, now), scope);
} catch (final ResourceIOException ex) {
recordCacheFailure(target, request);
- if (!mayCallBackend(request)) {
+ if (!mayCallBackend(requestCacheControl)) {
return convert(generateGatewayTimeout(context), scope);
}
setResponseStatus(scope.clientContext, CacheResponseStatus.FAILURE);
return chain.proceed(request, scope);
}
- } else if (!mayCallBackend(request)) {
+ } else if (!mayCallBackend(requestCacheControl)) {
LOG.debug("Cache entry not suitable but only-if-cached requested");
return convert(generateGatewayTimeout(context), scope);
} else if (!(entry.getStatus() == HttpStatus.SC_NOT_MODIFIED && !suitabilityChecker.isConditional(request))) {
LOG.debug("Revalidating cache entry");
- final boolean staleIfErrorEnabled = responseCachingPolicy.isStaleIfErrorEnabled(entry);
+ final boolean staleIfErrorEnabled = responseCachingPolicy.isStaleIfErrorEnabled(responseCacheControl, entry);
try {
if (cacheRevalidator != null
- && !staleResponseNotAllowed(request, entry, now)
- && validityPolicy.mayReturnStaleWhileRevalidating(entry, now)
+ && !staleResponseNotAllowed(requestCacheControl, responseCacheControl, entry, now)
+ && validityPolicy.mayReturnStaleWhileRevalidating(responseCacheControl, entry, now)
|| staleIfErrorEnabled) {
LOG.debug("Serving stale with asynchronous revalidation");
final String exchangeId = ExecSupport.getNextExchangeId();
@@ -331,21 +334,21 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
scope.originalRequest,
scope.execRuntime.fork(null),
HttpClientContext.create());
- final SimpleHttpResponse response = generateCachedResponse(request, context, entry, now);
+ final SimpleHttpResponse response = generateCachedResponse(responseCacheControl, request, context, entry, now);
cacheRevalidator.revalidateCacheEntry(
responseCache.generateKey(target, request, entry),
- () -> revalidateCacheEntry(target, request, fork, chain, entry));
+ () -> revalidateCacheEntry(requestCacheControl, responseCacheControl, target, request, fork, chain, entry));
return convert(response, scope);
}
- return revalidateCacheEntry(target, request, scope, chain, entry);
+ return revalidateCacheEntry(requestCacheControl, responseCacheControl, target, request, scope, chain, entry);
} catch (final IOException ioex) {
if (staleIfErrorEnabled) {
if (LOG.isDebugEnabled()) {
LOG.debug("Serving stale response due to IOException and stale-if-error enabled");
}
- return convert(generateCachedResponse(request, context, entry, now), scope);
+ return convert(generateCachedResponse(responseCacheControl, request, context, entry, now), scope);
}
- return convert(handleRevalidationFailure(request, context, entry, now), scope);
+ return convert(handleRevalidationFailure(requestCacheControl, responseCacheControl, request, context, entry, now), scope);
}
} else {
LOG.debug("Cache entry not usable; calling backend");
@@ -354,6 +357,8 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
}
ClassicHttpResponse revalidateCacheEntry(
+ final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl,
final HttpHost target,
final ClassicHttpRequest request,
final ExecChain.Scope scope,
@@ -361,7 +366,7 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
final HttpCacheEntry cacheEntry) throws IOException, HttpException {
Instant requestDate = getCurrentDate();
final ClassicHttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(
- scope.originalRequest, cacheEntry);
+ responseCacheControl, scope.originalRequest, cacheEntry);
ClassicHttpResponse backendResponse = chain.proceed(conditionalRequest, scope);
try {
@@ -394,8 +399,8 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
}
if (staleIfErrorAppliesTo(statusCode)
- && !staleResponseNotAllowed(request, cacheEntry, getCurrentDate())
- && validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
+ && !staleResponseNotAllowed(requestCacheControl, responseCacheControl, cacheEntry, getCurrentDate())
+ && validityPolicy.mayReturnStaleIfError(requestCacheControl, responseCacheControl, cacheEntry, responseDate)) {
try {
final SimpleHttpResponse cachedResponse = responseGenerator.generateResponse(request, cacheEntry);
cachedResponse.addHeader(HttpHeaders.WARNING, "110 localhost \"Response is stale\"");
@@ -422,7 +427,8 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
responseCompliance.ensureProtocolCompliance(scope.originalRequest, request, backendResponse);
responseCache.flushCacheEntriesInvalidatedByExchange(target, request, backendResponse);
- final boolean cacheable = responseCachingPolicy.isResponseCacheable(request, backendResponse);
+ final ResponseCacheControl responseCacheControl = CacheControlHeaderParser.INSTANCE.parse(backendResponse);
+ final boolean cacheable = responseCachingPolicy.isResponseCacheable(responseCacheControl, request, backendResponse);
if (cacheable) {
storeRequestIfModifiedSinceFor304Response(request, backendResponse);
return cacheAndReturnResponse(target, request, backendResponse, scope, requestDate, responseDate);
@@ -498,11 +504,12 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
private ClassicHttpResponse handleCacheMiss(
final HttpHost target,
final ClassicHttpRequest request,
+ final RequestCacheControl requestCacheControl,
final ExecChain.Scope scope,
final ExecChain chain) throws IOException, HttpException {
recordCacheMiss(target, request);
- if (!mayCallBackend(request)) {
+ if (!mayCallBackend(requestCacheControl)) {
return new BasicClassicHttpResponse(HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout");
}
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExecBase.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExecBase.java
index 4f0f3fafe..535ec5e67 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExecBase.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExecBase.java
@@ -28,7 +28,6 @@ package org.apache.hc.client5.http.impl.cache;
import java.io.IOException;
import java.time.Instant;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -184,6 +183,7 @@ public class CachingExecBase {
}
SimpleHttpResponse generateCachedResponse(
+ final ResponseCacheControl responseCacheControl,
final HttpRequest request,
final HttpContext context,
final HttpCacheEntry entry,
@@ -196,7 +196,7 @@ public class CachingExecBase {
cachedResponse = responseGenerator.generateResponse(request, entry);
}
setResponseStatus(context, CacheResponseStatus.CACHE_HIT);
- if (TimeValue.isPositive(validityPolicy.getStaleness(entry, now))) {
+ if (TimeValue.isPositive(validityPolicy.getStaleness(responseCacheControl, entry, now))) {
cachedResponse.addHeader(HttpHeaders.WARNING,"110 localhost \"Response is stale\"");
}
@@ -205,7 +205,7 @@ public class CachingExecBase {
final Header header = entry.getFirstHeader(HttpHeaders.DATE);
if (header != null) {
final Instant responseDate = DateUtils.parseStandardDate(header.getValue());
- final TimeValue freshnessLifetime = validityPolicy.getFreshnessLifetime(entry);
+ final TimeValue freshnessLifetime = validityPolicy.getFreshnessLifetime(responseCacheControl, entry);
final TimeValue currentAge = validityPolicy.getCurrentAge(entry, responseDate);
if (freshnessLifetime.compareTo(ONE_DAY) > 0 && currentAge.compareTo(ONE_DAY) > 0) {
cachedResponse.addHeader(HttpHeaders.WARNING,"113 localhost \"Heuristic expiration\"");
@@ -220,11 +220,13 @@ public class CachingExecBase {
}
SimpleHttpResponse handleRevalidationFailure(
+ final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl,
final HttpRequest request,
final HttpContext context,
final HttpCacheEntry entry,
final Instant now) throws IOException {
- if (staleResponseNotAllowed(request, entry, now)) {
+ if (staleResponseNotAllowed(requestCacheControl, responseCacheControl, entry, now)) {
return generateGatewayTimeout(context);
} else {
return unvalidatedCacheHit(request, context, entry);
@@ -247,14 +249,16 @@ public class CachingExecBase {
return cachedResponse;
}
- boolean staleResponseNotAllowed(final HttpRequest request, final HttpCacheEntry entry, final Instant now) {
- return validityPolicy.mustRevalidate(entry)
- || (cacheConfig.isSharedCache() && validityPolicy.proxyRevalidate(entry))
- || explicitFreshnessRequest(request, entry, now);
+ boolean staleResponseNotAllowed(final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl,
+ final HttpCacheEntry entry,
+ final Instant now) {
+ return responseCacheControl.isMustRevalidate()
+ || (cacheConfig.isSharedCache() && responseCacheControl.isProxyRevalidate())
+ || explicitFreshnessRequest(requestCacheControl, responseCacheControl, entry, now);
}
- boolean mayCallBackend(final HttpRequest request) {
- final RequestCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(request);
+ boolean mayCallBackend(final RequestCacheControl cacheControl) {
if (cacheControl.isOnlyIfCached()) {
LOG.debug("Request marked only-if-cached");
return false;
@@ -262,15 +266,16 @@ public class CachingExecBase {
return true;
}
- boolean explicitFreshnessRequest(final HttpRequest request, final HttpCacheEntry entry, final Instant now) {
- final RequestCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(request);
- if (cacheControl.getMaxStale() >= 0) {
+ boolean explicitFreshnessRequest(final RequestCacheControl requestCacheControl,
+ final ResponseCacheControl responseCacheControl, final HttpCacheEntry entry,
+ final Instant now) {
+ if (requestCacheControl.getMaxStale() >= 0) {
final TimeValue age = validityPolicy.getCurrentAge(entry, now);
- final TimeValue lifetime = validityPolicy.getFreshnessLifetime(entry);
- if (age.toSeconds() - lifetime.toSeconds() > cacheControl.getMaxStale()) {
+ final TimeValue lifetime = validityPolicy.getFreshnessLifetime(responseCacheControl, entry);
+ if (age.toSeconds() - lifetime.toSeconds() > requestCacheControl.getMaxStale()) {
return true;
}
- } else if (cacheControl.getMinFresh() >= 0 || cacheControl.getMaxAge() >= 0) {
+ } else if (requestCacheControl.getMinFresh() >= 0 || requestCacheControl.getMaxAge() >= 0) {
return true;
}
return false;
@@ -375,25 +380,4 @@ public class CachingExecBase {
}
}
- /**
- * Checks if the provided HttpRequest contains a 'no-cache' directive in its Cache-Control header.
- * <p>
- * According to the HTTP/1.1 specification, a 'no-cache' directive in a request message means
- * that the client allows a stored response to be used only if it is first validated with the
- * origin server (or with an intermediate cache that has a fresh response). This directive
- * applies to both shared and private caches.
- *
- * @param request the HttpRequest to check for the 'no-cache' directive
- * @return true if the 'no-cache' directive is present in the Cache-Control header of the request,
- * false otherwise
- */
- boolean requestContainsNoCacheDirective(final HttpRequest request) {
- final Iterator<Header> it = request.headerIterator(HttpHeaders.CACHE_CONTROL);
- if (it == null || !it.hasNext()) {
- return false;
- } else {
- final ResponseCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parseResponse(it);
- return cacheControl.isNoCache();
- }
- }
}
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ConditionalRequestBuilder.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ConditionalRequestBuilder.java
index 113a106db..ec923ab73 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ConditionalRequestBuilder.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ConditionalRequestBuilder.java
@@ -49,11 +49,12 @@ class ConditionalRequestBuilder<T extends HttpRequest> {
* the entry with the origin. Build the origin {@link org.apache.hc.core5.http.HttpRequest}
* here and return it.
*
+ * @param cacheControl the cache control directives.
* @param request the original request from the caller
* @param cacheEntry the entry that needs to be re-validated
* @return the wrapped request
*/
- public T buildConditionalRequest(final T request, final HttpCacheEntry cacheEntry) {
+ public T buildConditionalRequest(final ResponseCacheControl cacheControl, final T request, final HttpCacheEntry cacheEntry) {
final T newRequest = messageCopier.create(request);
final Header eTag = cacheEntry.getFirstHeader(HttpHeaders.ETAG);
@@ -64,7 +65,6 @@ class ConditionalRequestBuilder<T extends HttpRequest> {
if (lastModified != null) {
newRequest.setHeader(HttpHeaders.IF_MODIFIED_SINCE, lastModified.getValue());
}
- final ResponseCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(cacheEntry);
if (cacheControl.isMustRevalidate() || cacheControl.isProxyRevalidate()) {
newRequest.addHeader(HttpHeaders.CACHE_CONTROL, HeaderConstants.CACHE_CONTROL_MAX_AGE + "=0");
}
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseCacheControl.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseCacheControl.java
index 845fcc702..54b10da60 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseCacheControl.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseCacheControl.java
@@ -99,6 +99,8 @@ final class ResponseCacheControl implements CacheControl {
*/
private final Set<String> noCacheFields;
+ private final boolean undefined;
+
/**
* Creates a new instance of {@code CacheControl} with the specified values.
*
@@ -129,6 +131,16 @@ final class ResponseCacheControl implements CacheControl {
this.staleWhileRevalidate = staleWhileRevalidate;
this.staleIfError = staleIfError;
this.noCacheFields = noCacheFields != null ? Collections.unmodifiableSet(noCacheFields) : Collections.emptySet();
+ this.undefined = maxAge == -1 &&
+ sharedMaxAge == -1 &&
+ !noCache &&
+ !noStore &&
+ !cachePrivate &&
+ !mustRevalidate &&
+ !proxyRevalidate &&
+ !cachePublic &&
+ staleWhileRevalidate == -1
+ && staleIfError == -1;
}
/**
@@ -235,6 +247,10 @@ final class ResponseCacheControl implements CacheControl {
return noCacheFields;
}
+ public boolean isUndefined() {
+ return undefined;
+ }
+
@Override
public String toString() {
return "CacheControl{" +
@@ -252,7 +268,7 @@ final class ResponseCacheControl implements CacheControl {
'}';
}
- static Builder create() {
+ static Builder builder() {
return new Builder();
}
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseCachingPolicy.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseCachingPolicy.java
index 2eb900892..82a09bd3c 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseCachingPolicy.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseCachingPolicy.java
@@ -45,10 +45,8 @@ import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.MessageHeaders;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.message.MessageSupport;
-import org.apache.hc.core5.util.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -161,11 +159,9 @@ class ResponseCachingPolicy {
/**
* Determines if an HttpResponse can be cached.
*
- * @param httpMethod What type of request was this, a GET, PUT, other?
- * @param response The origin response
* @return {@code true} if response is cacheable
*/
- public boolean isResponseCacheable(final String httpMethod, final HttpResponse response, final ResponseCacheControl cacheControl) {
+ public boolean isResponseCacheable(final ResponseCacheControl cacheControl, final String httpMethod, final HttpResponse response) {
boolean cacheable = false;
if (!HeaderConstants.GET_METHOD.equals(httpMethod) && !HeaderConstants.HEAD_METHOD.equals(httpMethod)
@@ -242,7 +238,7 @@ class ResponseCachingPolicy {
}
// calculate freshness lifetime
- final Duration freshnessLifetime = calculateFreshnessLifetime(response, cacheControl);
+ final Duration freshnessLifetime = calculateFreshnessLifetime(cacheControl, response);
if (freshnessLifetime.isNegative() || freshnessLifetime.isZero()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Freshness lifetime is invalid");
@@ -250,7 +246,7 @@ class ResponseCachingPolicy {
return false;
}
- return cacheable || isExplicitlyCacheable(response, cacheControl);
+ return cacheable || isExplicitlyCacheable(cacheControl, response);
}
private boolean unknownStatusCode(final int status) {
@@ -295,57 +291,21 @@ class ResponseCachingPolicy {
}
}
- protected boolean isExplicitlyCacheable(final HttpResponse response, final ResponseCacheControl cacheControl ) {
+ protected boolean isExplicitlyCacheable(final ResponseCacheControl cacheControl, final HttpResponse response) {
if (response.getFirstHeader(HttpHeaders.EXPIRES) != null) {
return true;
}
- if (cacheControl == null) {
- return false;
- }else {
- return cacheControl.getMaxAge() > 0 || cacheControl.getSharedMaxAge()>0 ||
- cacheControl.isMustRevalidate() || cacheControl.isProxyRevalidate() || (cacheControl.isPublic());
- }
+ return cacheControl.getMaxAge() > 0 || cacheControl.getSharedMaxAge()>0 ||
+ cacheControl.isMustRevalidate() || cacheControl.isProxyRevalidate() || (cacheControl.isPublic());
}
/**
* Determine if the {@link HttpResponse} gotten from the origin is a
* cacheable response.
*
- * @param request the {@link HttpRequest} that generated an origin hit. Can't be {@code null}.
- * @param response the {@link HttpResponse} from the origin. Can't be {@code null}.
- * @return {@code true} if response is cacheable
- * @since 5.3
- */
- public boolean isResponseCacheable(final HttpRequest request, final HttpResponse response) {
- Args.notNull(request, "Request");
- Args.notNull(response, "Response");
- return isResponseCacheable(request, response, parseCacheControlHeader(response));
- }
-
- /**
- * Determines if an HttpResponse can be cached.
- *
- * @param httpMethod What type of request was this, a GET, PUT, other?. Can't be {@code null}.
- * @param response The origin response. Can't be {@code null}.
* @return {@code true} if response is cacheable
- * @since 5.3
*/
- public boolean isResponseCacheable(final String httpMethod, final HttpResponse response) {
- Args.notEmpty(httpMethod, "httpMethod");
- Args.notNull(response, "Response");
- return isResponseCacheable(httpMethod, response, parseCacheControlHeader(response));
- }
-
-
- /**
- * Determine if the {@link HttpResponse} gotten from the origin is a
- * cacheable response.
- *
- * @param request the {@link HttpRequest} that generated an origin hit
- * @param response the {@link HttpResponse} from the origin
- * @return {@code true} if response is cacheable
- */
- public boolean isResponseCacheable(final HttpRequest request, final HttpResponse response, final ResponseCacheControl cacheControl) {
+ public boolean isResponseCacheable(final ResponseCacheControl cacheControl, final HttpRequest request, final HttpResponse response) {
final ProtocolVersion version = request.getVersion() != null ? request.getVersion() : HttpVersion.DEFAULT;
if (version.compareToVersion(HttpVersion.HTTP_1_1) > 0) {
if (LOG.isDebugEnabled()) {
@@ -353,7 +313,7 @@ class ResponseCachingPolicy {
}
return false;
}
- if (cacheControl != null && cacheControl.isNoStore()) {
+ if (cacheControl.isNoStore()) {
LOG.debug("Response is explicitly non-cacheable per cache control directive");
return false;
}
@@ -362,31 +322,31 @@ class ResponseCachingPolicy {
if (neverCache1_0ResponsesWithQueryString && from1_0Origin(response)) {
LOG.debug("Response is not cacheable as it had a query string");
return false;
- } else if (!neverCache1_1ResponsesWithQueryString && !isExplicitlyCacheable(response, cacheControl)) {
+ } else if (!neverCache1_1ResponsesWithQueryString && !isExplicitlyCacheable(cacheControl, response)) {
LOG.debug("Response is not cacheable as it is missing explicit caching headers");
return false;
}
}
- if (expiresHeaderLessOrEqualToDateHeaderAndNoCacheControl(response, cacheControl)) {
+ if (expiresHeaderLessOrEqualToDateHeaderAndNoCacheControl(cacheControl, response)) {
LOG.debug("Expires header less or equal to Date header and no cache control directives");
return false;
}
if (sharedCache) {
if (request.countHeaders(HttpHeaders.AUTHORIZATION) > 0
- && cacheControl != null && !(cacheControl.getSharedMaxAge() > -1 || cacheControl.isMustRevalidate() || cacheControl.isPublic())) {
+ && !(cacheControl.getSharedMaxAge() > -1 || cacheControl.isMustRevalidate() || cacheControl.isPublic())) {
LOG.debug("Request contains private credentials");
return false;
}
}
final String method = request.getMethod();
- return isResponseCacheable(method, response, cacheControl);
+ return isResponseCacheable(cacheControl, method, response);
}
- private boolean expiresHeaderLessOrEqualToDateHeaderAndNoCacheControl(final HttpResponse response, final ResponseCacheControl cacheControl) {
- if (cacheControl != null) {
+ private boolean expiresHeaderLessOrEqualToDateHeaderAndNoCacheControl(final ResponseCacheControl cacheControl, final HttpResponse response) {
+ if (!cacheControl.isUndefined()) {
return false;
}
final Header expiresHdr = response.getFirstHeader(HttpHeaders.EXPIRES);
@@ -446,9 +406,9 @@ class ResponseCachingPolicy {
* @param response the HTTP response for which to calculate the freshness lifetime
* @return the freshness lifetime of the response, in seconds
*/
- private Duration calculateFreshnessLifetime(final HttpResponse response, final ResponseCacheControl cacheControl) {
+ private Duration calculateFreshnessLifetime(final ResponseCacheControl cacheControl, final HttpResponse response) {
- if (cacheControl == null) {
+ if (cacheControl.isUndefined()) {
// If no cache-control header is present, assume no caching directives and return a default value
return DEFAULT_FRESHNESS_DURATION; // 5 minutes
}
@@ -488,43 +448,21 @@ class ResponseCachingPolicy {
* {@code stale-while-revalidate} directive in its Cache-Control header. If it does, this method returns {@code true},
* indicating that a stale response can be served. If not, it returns {@code false}.
*
- * @param entry the cached HTTP message entry to check
* @return {@code true} if a stale response can be served in case of an error status code, {@code false} otherwise
*/
- boolean isStaleIfErrorEnabled(final HttpCacheEntry entry) {
+ boolean isStaleIfErrorEnabled(final ResponseCacheControl cacheControl, final HttpCacheEntry entry) {
// Check if the stale-while-revalidate extension is enabled
if (staleIfErrorEnabled) {
// Check if the cached response has an error status code
final int statusCode = entry.getStatus();
if (statusCode >= HttpStatus.SC_INTERNAL_SERVER_ERROR && statusCode <= HttpStatus.SC_GATEWAY_TIMEOUT) {
// Check if the cached response has a stale-while-revalidate directive
- final ResponseCacheControl cacheControl = parseCacheControlHeader(entry);
- if (cacheControl == null) {
- return false;
- } else {
- return cacheControl.getStaleWhileRevalidate() > 0;
- }
+ return cacheControl.getStaleWhileRevalidate() > 0;
}
}
return false;
}
- /**
- * Parses the Cache-Control header from the given HTTP messageHeaders and returns the corresponding CacheControl instance.
- * If the header is not present, returns a CacheControl instance with default values for all directives.
- *
- * @param messageHeaders the HTTP message to parse the header from
- * @return a CacheControl instance with the parsed directives or default values if the header is not present
- */
- private ResponseCacheControl parseCacheControlHeader(final MessageHeaders messageHeaders) {
- final Iterator<Header> it = messageHeaders.headerIterator(HttpHeaders.CACHE_CONTROL);
- if (it == null || !it.hasNext()) {
- return null;
- } else {
- return CacheControlHeaderParser.INSTANCE.parseResponse(it);
- }
- }
-
/**
* Determines if the given {@link HttpCacheEntry} requires revalidation based on the presence of the {@code no-cache} directive
* in the Cache-Control header.
@@ -539,33 +477,26 @@ class ResponseCachingPolicy {
* @param entry the {@link HttpCacheEntry} containing the headers to check for the {@code no-cache} directive.
* @return true if revalidation is required based on the {@code no-cache} directive, {@code false} otherwise.
*/
- boolean responseContainsNoCacheDirective(final HttpCacheEntry entry) {
- final ResponseCacheControl responseCacheControl = parseCacheControlHeader(entry);
-
- if (responseCacheControl != null) {
- final Set<String> noCacheFields = responseCacheControl.getNoCacheFields();
+ boolean responseContainsNoCacheDirective(final ResponseCacheControl responseCacheControl, final HttpCacheEntry entry) {
+ final Set<String> noCacheFields = responseCacheControl.getNoCacheFields();
- // If no-cache directive is present and has no field names
- if (responseCacheControl.isNoCache() && noCacheFields.isEmpty()) {
- LOG.debug("No-cache directive present without field names. Revalidation required.");
- return true;
- }
+ // If no-cache directive is present and has no field names
+ if (responseCacheControl.isNoCache() && noCacheFields.isEmpty()) {
+ LOG.debug("No-cache directive present without field names. Revalidation required.");
+ return true;
+ }
- // If no-cache directive is present with field names
- if (responseCacheControl.isNoCache()) {
- for (final String field : noCacheFields) {
- if (entry.getFirstHeader(field) != null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("No-cache directive field '{}' found in response headers. Revalidation required.", field);
- }
- return true;
+ // If no-cache directive is present with field names
+ if (responseCacheControl.isNoCache()) {
+ for (final String field : noCacheFields) {
+ if (entry.getFirstHeader(field) != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("No-cache directive field '{}' found in response headers. Revalidation required.", field);
}
+ return true;
}
}
}
- if (LOG.isDebugEnabled()) {
- LOG.debug("No no-cache directives found in response headers. No revalidation required.");
- }
return false;
}
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheValidityPolicy.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheValidityPolicy.java
index 60dc0f7d6..36fbad53f 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheValidityPolicy.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheValidityPolicy.java
@@ -38,9 +38,7 @@ import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.utils.DateUtils;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.http.message.BasicHttpRequest;
import org.apache.hc.core5.util.TimeValue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -161,68 +159,75 @@ public class TestCacheValidityPolicy {
@Test
public void testFreshnessLifetimeIsSMaxAgeIfPresent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(entry));
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder()
+ .setSharedMaxAge(10)
+ .build();
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+ assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(cacheControl, entry));
}
@Test
public void testFreshnessLifetimeIsMaxAgeIfPresent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(entry));
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder()
+ .setMaxAge(10)
+ .build();
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+ assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(cacheControl, entry));
}
@Test
public void testFreshnessLifetimeIsMostRestrictiveOfMaxAgeAndSMaxAge() {
- Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"),
- new BasicHeader("Cache-Control", "s-maxage=20") };
- HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(entry));
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder()
+ .setMaxAge(10)
+ .setSharedMaxAge(20)
+ .build();
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+ assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(cacheControl, entry));
- headers = new Header[] { new BasicHeader("Cache-Control", "max-age=20"),
- new BasicHeader("Cache-Control", "s-maxage=10") };
- entry = HttpTestUtils.makeCacheEntry(headers);
- assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(entry));
+ final ResponseCacheControl cacheControl2 = ResponseCacheControl.builder()
+ .setMaxAge(20)
+ .setSharedMaxAge(10)
+ .build();
+ assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(cacheControl2, entry));
}
@Test
public void testFreshnessLifetimeIsMaxAgeEvenIfExpiresIsPresent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"),
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder()
+ .setMaxAge(10)
+ .build();
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo)) };
-
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(entry));
+ new BasicHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo)));
+ assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(cacheControl, entry));
}
@Test
public void testFreshnessLifetimeIsSMaxAgeEvenIfExpiresIsPresent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10"),
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder()
+ .setSharedMaxAge(10)
+ .build();
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo)) };
-
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(entry));
+ new BasicHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo)));
+ assertEquals(TimeValue.ofSeconds(10), impl.getFreshnessLifetime(cacheControl, entry));
}
@Test
public void testFreshnessLifetimeIsFromExpiresHeaderIfNoMaxAge() {
- final Header[] headers = new Header[] {
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder()
+ .build();
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo)) };
-
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertEquals(TimeValue.ofSeconds(4), impl.getFreshnessLifetime(entry));
+ new BasicHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo)));
+ assertEquals(TimeValue.ofSeconds(4), impl.getFreshnessLifetime(cacheControl, entry));
}
@Test
public void testHeuristicFreshnessLifetime() {
- final Header[] headers = new Header[] {
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
new BasicHeader("Date", DateUtils.formatStandardDate(oneSecondAgo)),
- new BasicHeader("Last-Modified", DateUtils.formatStandardDate(elevenSecondsAgo))
- };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
+ new BasicHeader("Last-Modified", DateUtils.formatStandardDate(elevenSecondsAgo)));
assertEquals(TimeValue.ofSeconds(1), impl.getHeuristicFreshnessLifetime(entry, 0.1f, TimeValue.ZERO_MILLISECONDS));
}
@@ -235,18 +240,16 @@ public class TestCacheValidityPolicy {
@Test
public void testHeuristicFreshnessLifetimeIsNonNegative() {
- final Header[] headers = new Header[] {
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
new BasicHeader("Date", DateUtils.formatStandardDate(elevenSecondsAgo)),
- new BasicHeader("Last-Modified", DateUtils.formatStandardDate(oneSecondAgo))
- };
-
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
+ new BasicHeader("Last-Modified", DateUtils.formatStandardDate(oneSecondAgo)));
assertTrue(TimeValue.isNonNegative(impl.getHeuristicFreshnessLifetime(entry, 0.1f, TimeValue.ofSeconds(10))));
}
@Test
public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() {
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder().build();
impl = new CacheValidityPolicy() {
@Override
public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) {
@@ -255,17 +258,18 @@ public class TestCacheValidityPolicy {
return TimeValue.ofSeconds(6);
}
@Override
- public TimeValue getFreshnessLifetime(final HttpCacheEntry e) {
+ public TimeValue getFreshnessLifetime(final ResponseCacheControl cacheControl, final HttpCacheEntry e) {
assertSame(entry, e);
return TimeValue.ofSeconds(10);
}
};
- assertTrue(impl.isResponseFresh(entry, now));
+ assertTrue(impl.isResponseFresh(responseCacheControl, entry, now));
}
@Test
public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() {
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder().build();
impl = new CacheValidityPolicy() {
@Override
public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) {
@@ -274,17 +278,18 @@ public class TestCacheValidityPolicy {
return TimeValue.ofSeconds(6);
}
@Override
- public TimeValue getFreshnessLifetime(final HttpCacheEntry e) {
+ public TimeValue getFreshnessLifetime(final ResponseCacheControl cacheControl, final HttpCacheEntry e) {
assertSame(entry, e);
return TimeValue.ofSeconds(6);
}
};
- assertFalse(impl.isResponseFresh(entry, now));
+ assertFalse(impl.isResponseFresh(responseCacheControl, entry, now));
}
@Test
public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() {
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder().build();
impl = new CacheValidityPolicy() {
@Override
public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) {
@@ -293,70 +298,70 @@ public class TestCacheValidityPolicy {
return TimeValue.ofSeconds(10);
}
@Override
- public TimeValue getFreshnessLifetime(final HttpCacheEntry e) {
+ public TimeValue getFreshnessLifetime(final ResponseCacheControl cacheControl, final HttpCacheEntry e) {
assertSame(entry, e);
return TimeValue.ofSeconds(6);
}
};
- assertFalse(impl.isResponseFresh(entry, now));
+ assertFalse(impl.isResponseFresh(responseCacheControl, entry, now));
}
@Test
public void testCacheEntryIsRevalidatableIfHeadersIncludeETag() {
- final Header[] headers = {
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
new BasicHeader("Expires", DateUtils.formatStandardDate(Instant.now())),
- new BasicHeader("ETag", "somevalue")};
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
+ new BasicHeader("ETag", "somevalue"));
assertTrue(impl.isRevalidatable(entry));
}
@Test
public void testCacheEntryIsRevalidatableIfHeadersIncludeLastModifiedDate() {
- final Header[] headers = {
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
new BasicHeader("Expires", DateUtils.formatStandardDate(Instant.now())),
- new BasicHeader("Last-Modified", DateUtils.formatStandardDate(Instant.now())) };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
+ new BasicHeader("Last-Modified", DateUtils.formatStandardDate(Instant.now())));
assertTrue(impl.isRevalidatable(entry));
}
@Test
public void testCacheEntryIsNotRevalidatableIfNoAppropriateHeaders() {
- final Header[] headers = {
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
new BasicHeader("Expires", DateUtils.formatStandardDate(Instant.now())),
- new BasicHeader("Cache-Control", "public") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
+ new BasicHeader("Cache-Control", "public"));
assertFalse(impl.isRevalidatable(entry));
}
@Test
public void testMissingContentLengthDoesntInvalidateEntry() {
final int contentLength = 128;
- final Header[] headers = {}; // no Content-Length header
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers, HttpTestUtils.getRandomBytes(contentLength));
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
+ new Header[] { }, // no Content-Length header
+ HttpTestUtils.getRandomBytes(contentLength));
assertTrue(impl.contentLengthHeaderMatchesActualLength(entry));
}
@Test
public void testCorrectContentLengthDoesntInvalidateEntry() {
final int contentLength = 128;
- final Header[] headers = { new BasicHeader(HttpHeaders.CONTENT_LENGTH, Integer.toString(contentLength)) };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers, HttpTestUtils.getRandomBytes(contentLength));
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
+ new Header[] { new BasicHeader(HttpHeaders.CONTENT_LENGTH, Integer.toString(contentLength)) },
+ HttpTestUtils.getRandomBytes(contentLength));
assertTrue(impl.contentLengthHeaderMatchesActualLength(entry));
}
@Test
public void testWrongContentLengthInvalidatesEntry() {
final int contentLength = 128;
- final Header[] headers = {new BasicHeader(HttpHeaders.CONTENT_LENGTH, Integer.toString(contentLength+1))};
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers, HttpTestUtils.getRandomBytes(contentLength));
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
+ new Header[]{ new BasicHeader(HttpHeaders.CONTENT_LENGTH, Integer.toString(contentLength+1)) },
+ HttpTestUtils.getRandomBytes(contentLength));
assertFalse(impl.contentLengthHeaderMatchesActualLength(entry));
}
@Test
public void testNullResourceInvalidatesEntry() {
final int contentLength = 128;
- final Header[] headers = {new BasicHeader(HttpHeaders.CONTENT_LENGTH, Integer.toString(contentLength))};
- final HttpCacheEntry entry = HttpTestUtils.makeHeadCacheEntry(headers);
+ final HttpCacheEntry entry = HttpTestUtils.makeHeadCacheEntry(
+ new BasicHeader(HttpHeaders.CONTENT_LENGTH, Integer.toString(contentLength)));
assertFalse(impl.contentLengthHeaderMatchesActualLength(entry));
}
@@ -370,133 +375,108 @@ public class TestCacheValidityPolicy {
@Test
public void testMalformedAgeHeaderValueReturnsMaxAge() {
- final Header[] headers = new Header[] { new BasicHeader("Age", "asdf") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(
+ new BasicHeader("Age", "asdf"));
// in seconds
assertEquals(CacheValidityPolicy.MAX_AGE.toSeconds(), impl.getAgeValue(entry));
}
- @Test
- public void testMalformedCacheControlMaxAgeHeaderReturnsZero() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=asdf") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- // in seconds
- assertEquals(0L, impl.getMaxAge(entry));
- }
-
- @Test
- public void testMustRevalidateIsFalseIfDirectiveNotPresent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertFalse(impl.mustRevalidate(entry));
- }
-
- @Test
- public void testMustRevalidateIsTrueWhenDirectiveIsPresent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, must-revalidate") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertTrue(impl.mustRevalidate(entry));
- }
-
- @Test
- public void testProxyRevalidateIsFalseIfDirectiveNotPresent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertFalse(impl.proxyRevalidate(entry));
- }
-
- @Test
- public void testProxyRevalidateIsTrueWhenDirectiveIsPresent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, proxy-revalidate") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
- assertTrue(impl.proxyRevalidate(entry));
- }
-
@Test
public void testMayReturnStaleIfErrorInResponseIsTrueWithinStaleness(){
- final Header[] headers = new Header[] {
- new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5, stale-if-error=15")
- };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
- final HttpRequest req = new BasicHttpRequest("GET","/");
- assertTrue(impl.mayReturnStaleIfError(req, entry, now));
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now,
+ new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)));
+ final RequestCacheControl requestCacheControl = RequestCacheControl.builder()
+ .build();
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .setStaleIfError(15)
+ .build();
+ assertTrue(impl.mayReturnStaleIfError(requestCacheControl, responseCacheControl, entry, now));
}
@Test
public void testMayReturnStaleIfErrorInRequestIsTrueWithinStaleness(){
- final Header[] headers = new Header[] {
- new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5")
- };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
- final HttpRequest req = new BasicHttpRequest("GET","/");
- req.setHeader("Cache-Control","stale-if-error=15");
- assertTrue(impl.mayReturnStaleIfError(req, entry, now));
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now,
+ new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)));
+ final RequestCacheControl requestCacheControl = RequestCacheControl.builder()
+ .build();
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setStaleIfError(15)
+ .build();
+ assertTrue(impl.mayReturnStaleIfError(requestCacheControl, responseCacheControl, entry, now));
}
@Test
public void testMayNotReturnStaleIfErrorInResponseAndAfterResponseWindow(){
- final Header[] headers = new Header[] {
- new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5, stale-if-error=1")
- };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
- final HttpRequest req = new BasicHttpRequest("GET","/");
- assertFalse(impl.mayReturnStaleIfError(req, entry, now));
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now,
+ new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)));
+ final RequestCacheControl requestCacheControl = RequestCacheControl.builder()
+ .build();
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .setStaleIfError(1)
+ .build();
+ assertFalse(impl.mayReturnStaleIfError(requestCacheControl, responseCacheControl, entry, now));
}
@Test
public void testMayNotReturnStaleIfErrorInResponseAndAfterRequestWindow(){
- final Header[] headers = new Header[] {
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now,
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5")
- };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
- final HttpRequest req = new BasicHttpRequest("GET","/");
- req.setHeader("Cache-Control","stale-if-error=1");
- assertFalse(impl.mayReturnStaleIfError(req, entry, now));
+ new BasicHeader("Cache-Control", "max-age=5"));
+ final RequestCacheControl requestCacheControl = RequestCacheControl.builder()
+ .setStaleIfError(1)
+ .build();
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .build();
+ assertFalse(impl.mayReturnStaleIfError(requestCacheControl, responseCacheControl, entry, now));
}
@Test
public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveIsAbsent() {
- final Header[] headers = new Header[] { new BasicHeader("Cache-control", "public") };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
- assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
+ assertFalse(impl.mayReturnStaleWhileRevalidating(responseCacheControl, entry, now));
}
@Test
public void testMayReturnStaleWhileRevalidatingIsTrueWhenWithinStaleness() {
- final Header[] headers = new Header[] {
- new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=15")
- };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now,
+ new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)));
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .setStaleWhileRevalidate(15)
+ .build();
- assertTrue(impl.mayReturnStaleWhileRevalidating(entry, now));
+ assertTrue(impl.mayReturnStaleWhileRevalidating(responseCacheControl, entry, now));
}
@Test
public void testMayReturnStaleWhileRevalidatingIsFalseWhenPastStaleness() {
final Instant twentyFiveSecondsAgo = now.minusSeconds(25);
- final Header[] headers = new Header[] {
- new BasicHeader("Date", DateUtils.formatStandardDate(twentyFiveSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=15")
- };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now,
+ new BasicHeader("Date", DateUtils.formatStandardDate(twentyFiveSecondsAgo)));
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .setStaleWhileRevalidate(15)
+ .build();
- assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
+ assertFalse(impl.mayReturnStaleWhileRevalidating(responseCacheControl, entry, now));
}
@Test
public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveEmpty() {
- final Header[] headers = new Header[] {
- new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=")
- };
- final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
-
- assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
+ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now,
+ new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)));
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .setStaleWhileRevalidate(0)
+ .build();
+
+ assertFalse(impl.mayReturnStaleWhileRevalidating(responseCacheControl, entry, now));
}
}
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheableRequestPolicy.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheableRequestPolicy.java
index b14405a86..8a2d088b3 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheableRequestPolicy.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheableRequestPolicy.java
@@ -43,100 +43,106 @@ public class TestCacheableRequestPolicy {
@Test
public void testIsGetServableFromCache() {
final BasicHttpRequest request = new BasicHttpRequest("GET", "someUri");
+ final RequestCacheControl cacheControl = RequestCacheControl.builder().build();
- Assertions.assertTrue(policy.isServableFromCache(request));
+ Assertions.assertTrue(policy.isServableFromCache(cacheControl, request));
}
@Test
public void testIsGetWithCacheControlServableFromCache() {
- BasicHttpRequest request = new BasicHttpRequest("GET", "someUri");
- request.addHeader("Cache-Control", "no-cache");
-
- Assertions.assertFalse(policy.isServableFromCache(request));
-
- request = new BasicHttpRequest("GET", "someUri");
- request.addHeader("Cache-Control", "no-store");
- request.addHeader("Cache-Control", "max-age=20");
+ final BasicHttpRequest request = new BasicHttpRequest("GET", "someUri");
+ final RequestCacheControl cacheControl = RequestCacheControl.builder()
+ .setNoCache(true)
+ .build();
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl, request));
- request = new BasicHttpRequest("GET", "someUri");
- request.addHeader("Cache-Control", "public");
- request.addHeader("Cache-Control", "no-store, max-age=20");
+ final RequestCacheControl cacheControl2 = RequestCacheControl.builder()
+ .setNoStore(true)
+ .setMaxAge(20)
+ .build();
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl2, request));
}
@Test
public void testIsGetWithPragmaServableFromCache() {
- BasicHttpRequest request = new BasicHttpRequest("GET", "someUri");
+ final BasicHttpRequest request = new BasicHttpRequest("GET", "someUri");
request.addHeader("Pragma", "no-cache");
+ final RequestCacheControl cacheControl = RequestCacheControl.builder()
+ .build();
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl, request));
- request = new BasicHttpRequest("GET", "someUri");
- request.addHeader("Pragma", "value1");
- request.addHeader("Pragma", "value2");
+ final BasicHttpRequest request2 = new BasicHttpRequest("GET", "someUri");
+ request2.addHeader("Pragma", "value1");
+ request2.addHeader("Pragma", "value2");
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl, request2));
}
@Test
public void testIsHeadServableFromCache() {
- BasicHttpRequest request = new BasicHttpRequest("HEAD", "someUri");
+ final BasicHttpRequest request = new BasicHttpRequest("HEAD", "someUri");
+ final RequestCacheControl cacheControl = RequestCacheControl.builder().build();
- Assertions.assertTrue(policy.isServableFromCache(request));
+ Assertions.assertTrue(policy.isServableFromCache(cacheControl, request));
- request = new BasicHttpRequest("HEAD", "someUri");
- request.addHeader("Cache-Control", "public");
- request.addHeader("Cache-Control", "max-age=20");
+ final RequestCacheControl cacheControl2 = RequestCacheControl.builder()
+ .setMaxAge(20)
+ .build();
- Assertions.assertTrue(policy.isServableFromCache(request));
+ Assertions.assertTrue(policy.isServableFromCache(cacheControl2, request));
}
@Test
public void testIsHeadWithCacheControlServableFromCache() {
- BasicHttpRequest request = new BasicHttpRequest("HEAD", "someUri");
- request.addHeader("Cache-Control", "no-cache");
+ final BasicHttpRequest request = new BasicHttpRequest("HEAD", "someUri");
+ final RequestCacheControl cacheControl = RequestCacheControl.builder()
+ .setNoCache(true)
+ .build();
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl, request));
- request = new BasicHttpRequest("HEAD", "someUri");
request.addHeader("Cache-Control", "no-store");
request.addHeader("Cache-Control", "max-age=20");
+ final RequestCacheControl cacheControl2 = RequestCacheControl.builder()
+ .setNoStore(true)
+ .setMaxAge(20)
+ .build();
- Assertions.assertFalse(policy.isServableFromCache(request));
-
- request = new BasicHttpRequest("HEAD", "someUri");
- request.addHeader("Cache-Control", "public");
- request.addHeader("Cache-Control", "no-store, max-age=20");
-
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl2, request));
}
@Test
public void testIsHeadWithPragmaServableFromCache() {
- BasicHttpRequest request = new BasicHttpRequest("HEAD", "someUri");
- request.addHeader("Pragma", "no-cache");
+ final BasicHttpRequest request = new BasicHttpRequest("HEAD", "someUri");
+ final RequestCacheControl cacheControl = RequestCacheControl.builder()
+ .setNoCache(true)
+ .build();
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl, request));
- request = new BasicHttpRequest("HEAD", "someUri");
- request.addHeader("Pragma", "value1");
- request.addHeader("Pragma", "value2");
+ final BasicHttpRequest request2 = new BasicHttpRequest("HEAD", "someUri");
+ request2.addHeader("Pragma", "value1");
+ request2.addHeader("Pragma", "value2");
+ final RequestCacheControl cacheControl2 = RequestCacheControl.builder()
+ .build();
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl2, request2));
}
@Test
public void testIsArbitraryMethodServableFromCache() {
- BasicHttpRequest request = new BasicHttpRequest("TRACE", "someUri");
+ final BasicHttpRequest request = new BasicHttpRequest("TRACE", "someUri");
+ final RequestCacheControl cacheControl = RequestCacheControl.builder()
+ .build();
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl, request));
- request = new BasicHttpRequest("get", "someUri");
+ final BasicHttpRequest request2 = new BasicHttpRequest("get", "someUri");
- Assertions.assertFalse(policy.isServableFromCache(request));
+ Assertions.assertFalse(policy.isServableFromCache(cacheControl, request2));
}
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedResponseSuitabilityChecker.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedResponseSuitabilityChecker.java
index cf081b43c..de79c737e 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedResponseSuitabilityChecker.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedResponseSuitabilityChecker.java
@@ -32,7 +32,6 @@ import org.apache.hc.client5.http.cache.HeaderConstants;
import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.utils.DateUtils;
import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.message.BasicHttpRequest;
@@ -48,9 +47,10 @@ public class TestCachedResponseSuitabilityChecker {
private Instant tenSecondsAgo;
private Instant nineSecondsAgo;
- private HttpHost host;
private HttpRequest request;
private HttpCacheEntry entry;
+ private RequestCacheControl requestCacheControl;
+ private ResponseCacheControl responseCacheControl;
private CachedResponseSuitabilityChecker impl;
@BeforeEach
@@ -60,9 +60,10 @@ public class TestCachedResponseSuitabilityChecker {
tenSecondsAgo = now.minusSeconds(10);
nineSecondsAgo = now.minusSeconds(9);
- host = new HttpHost("foo.example.com");
request = new BasicHttpRequest("GET", "/foo");
entry = HttpTestUtils.makeCacheEntry();
+ requestCacheControl = RequestCacheControl.builder().build();
+ responseCacheControl = ResponseCacheControl.builder().build();
impl = new CachedResponseSuitabilityChecker(CacheConfig.DEFAULT);
}
@@ -75,117 +76,152 @@ public class TestCachedResponseSuitabilityChecker {
public void testNotSuitableIfContentLengthHeaderIsWrong() {
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","1")
};
entry = getEntry(headers);
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
+
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testSuitableIfCacheEntryIsFresh() {
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
- Assertions.assertTrue(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testNotSuitableIfCacheEntryIsNotFresh() {
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .build();
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testNotSuitableIfRequestHasNoCache() {
- request.addHeader("Cache-Control", "no-cache");
+ requestCacheControl = RequestCacheControl.builder()
+ .setNoCache(true)
+ .build();
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testNotSuitableIfAgeExceedsRequestMaxAge() {
- request.addHeader("Cache-Control", "max-age=10");
+ requestCacheControl = RequestCacheControl.builder()
+ .setMaxAge(10)
+ .build();
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
entry = getEntry(headers);
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testSuitableIfFreshAndAgeIsUnderRequestMaxAge() {
- request.addHeader("Cache-Control", "max-age=15");
+ requestCacheControl = RequestCacheControl.builder()
+ .setMaxAge(15)
+ .build();
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
- Assertions.assertTrue(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testSuitableIfFreshAndFreshnessLifetimeGreaterThanRequestMinFresh() {
- request.addHeader("Cache-Control", "min-fresh=10");
+ requestCacheControl = RequestCacheControl.builder()
+ .setMinFresh(10)
+ .build();
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
- Assertions.assertTrue(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testNotSuitableIfFreshnessLifetimeLessThanRequestMinFresh() {
- request.addHeader("Cache-Control", "min-fresh=10");
+ requestCacheControl = RequestCacheControl.builder()
+ .setMinFresh(10)
+ .build();
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=15"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(15)
+ .build();
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testSuitableEvenIfStaleButPermittedByRequestMaxStale() {
- request.addHeader("Cache-Control", "max-stale=10");
+ requestCacheControl = RequestCacheControl.builder()
+ .setMaxStale(10)
+ .build();
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
- Assertions.assertTrue(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .build();
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
public void testNotSuitableIfStaleButTooStaleForRequestMaxStale() {
- request.addHeader("Cache-Control", "max-stale=2");
+ requestCacheControl = RequestCacheControl.builder()
+ .setMaxStale(2)
+ .build();
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=5"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .build();
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
@@ -206,7 +242,7 @@ public class TestCachedResponseSuitabilityChecker {
.setHeuristicCoefficient(0.1f).build();
impl = new CachedResponseSuitabilityChecker(config);
- Assertions.assertTrue(impl.canCachedResponseBeUsed(request, entry, now));
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
@@ -224,7 +260,7 @@ public class TestCachedResponseSuitabilityChecker {
.build();
impl = new CachedResponseSuitabilityChecker(config);
- Assertions.assertTrue(impl.canCachedResponseBeUsed(request, entry, now));
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
@@ -232,24 +268,28 @@ public class TestCachedResponseSuitabilityChecker {
final HttpRequest headRequest = new BasicHttpRequest("HEAD", "/foo");
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = getEntry(headers);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
- Assertions.assertTrue(impl.canCachedResponseBeUsed(headRequest, entry, now));
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, headRequest, entry, now));
}
@Test
public void testNotSuitableIfRequestMethodIsGETAndEntryResourceIsNull() {
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = HttpTestUtils.makeHeadCacheEntry(headers);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
@@ -257,12 +297,14 @@ public class TestCachedResponseSuitabilityChecker {
impl = new CachedResponseSuitabilityChecker(CacheConfig.custom().build());
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = HttpTestUtils.makeCacheEntryWithNoRequestMethodOrEntity(headers);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
@@ -270,12 +312,14 @@ public class TestCachedResponseSuitabilityChecker {
impl = new CachedResponseSuitabilityChecker(CacheConfig.custom().build());
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = HttpTestUtils.makeCacheEntryWithNoRequestMethod(headers);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
- Assertions.assertTrue(impl.canCachedResponseBeUsed(request, entry, now));
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
@@ -283,11 +327,13 @@ public class TestCachedResponseSuitabilityChecker {
impl = new CachedResponseSuitabilityChecker(CacheConfig.custom().build());
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600")
};
entry = HttpTestUtils.make204CacheEntryWithNoRequestMethod(headers);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
- Assertions.assertTrue(impl.canCachedResponseBeUsed(request, entry, now));
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
@Test
@@ -296,12 +342,14 @@ public class TestCachedResponseSuitabilityChecker {
impl = new CachedResponseSuitabilityChecker(CacheConfig.custom().build());
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Content-Length","128")
};
entry = HttpTestUtils.makeHeadCacheEntryWithNoRequestMethod(headers);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
- Assertions.assertTrue(impl.canCachedResponseBeUsed(headRequest, entry, now));
+ Assertions.assertTrue(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, headRequest, entry, now));
}
@Test
@@ -309,11 +357,13 @@ public class TestCachedResponseSuitabilityChecker {
// Prepare a cache entry with HEAD method
final Header[] headers = {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("Cache-Control", "max-age=3600"),
new BasicHeader("Hc-Request-Method", HeaderConstants.HEAD_METHOD)
};
entry = getEntry(headers);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
// Validate that the cache entry is not suitable for the GET request
- Assertions.assertFalse(impl.canCachedResponseBeUsed(request, entry, now));
+ Assertions.assertFalse(impl.canCachedResponseBeUsed(requestCacheControl, responseCacheControl, request, entry, now));
}
}
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
index 1395f6cc0..07b3c67c9 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
@@ -39,8 +39,8 @@ import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
-import java.util.List;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
@@ -1498,16 +1498,16 @@ public class TestCachingExecChain {
// Set up the mock response chain
Mockito.when(mockExecChain.proceed(Mockito.any(), Mockito.any())).thenReturn(resp1);
- Mockito.when(responseCachingPolicy.isStaleIfErrorEnabled(Mockito.any())).thenReturn(true);
- Mockito.when(cacheableRequestPolicy.isServableFromCache(Mockito.any())).thenReturn(true);
- Mockito.when(validityPolicy.getStaleness(Mockito.any(), Mockito.any())).thenReturn(TimeValue.MAX_VALUE);
+ Mockito.when(responseCachingPolicy.isStaleIfErrorEnabled(Mockito.any(), Mockito.any())).thenReturn(true);
+ Mockito.when(cacheableRequestPolicy.isServableFromCache(Mockito.any(), Mockito.any())).thenReturn(true);
+ Mockito.when(validityPolicy.getStaleness(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(TimeValue.MAX_VALUE);
// Assuming validityPolicy is a Mockito mock
Mockito.when(validityPolicy.getCurrentAge(Mockito.any(), Mockito.any()))
.thenReturn(TimeValue.ofMilliseconds(0));
// Assuming validityPolicy is a Mockito mock
- Mockito.when(validityPolicy.getFreshnessLifetime(Mockito.any()))
+ Mockito.when(validityPolicy.getFreshnessLifetime(Mockito.any(), Mockito.any()))
.thenReturn(TimeValue.ofMilliseconds(0));
final SimpleHttpResponse response = SimpleHttpResponse.create(HttpStatus.SC_OK);
@@ -1599,16 +1599,16 @@ public class TestCachingExecChain {
// Set up the mock response chain
Mockito.when(mockExecChain.proceed(Mockito.any(), Mockito.any())).thenReturn(resp1);
- Mockito.when(responseCachingPolicy.isStaleIfErrorEnabled(Mockito.any())).thenReturn(true);
- Mockito.when(cacheableRequestPolicy.isServableFromCache(Mockito.any())).thenReturn(true);
- Mockito.when(validityPolicy.getStaleness(Mockito.any(), Mockito.any())).thenReturn(TimeValue.MAX_VALUE);
+ Mockito.when(responseCachingPolicy.isStaleIfErrorEnabled(Mockito.any(), Mockito.any())).thenReturn(true);
+ Mockito.when(cacheableRequestPolicy.isServableFromCache(Mockito.any(), Mockito.any())).thenReturn(true);
+ Mockito.when(validityPolicy.getStaleness(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(TimeValue.MAX_VALUE);
// Assuming validityPolicy is a Mockito mock
Mockito.when(validityPolicy.getCurrentAge(Mockito.any(), Mockito.any()))
.thenReturn(TimeValue.ofDays(2));
// Assuming validityPolicy is a Mockito mock
- Mockito.when(validityPolicy.getFreshnessLifetime(Mockito.any()))
+ Mockito.when(validityPolicy.getFreshnessLifetime(Mockito.any(), Mockito.any()))
.thenReturn(TimeValue.ofDays(2));
final SimpleHttpResponse response = SimpleHttpResponse.create(HttpStatus.SC_OK);
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
index ffff6e0fe..3ec083065 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
@@ -70,7 +70,8 @@ public class TestConditionalRequestBuilder {
new BasicHeader("Last-Modified", lastModified) };
final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers);
- final HttpRequest newRequest = impl.buildConditionalRequest(basicRequest, cacheEntry);
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder().build();
+ final HttpRequest newRequest = impl.buildConditionalRequest(cacheControl, basicRequest, cacheEntry);
Assertions.assertEquals(theMethod, newRequest.getMethod());
Assertions.assertEquals(theUri, newRequest.getRequestUri());
@@ -98,7 +99,8 @@ public class TestConditionalRequestBuilder {
};
final HttpRequest basicRequest = new BasicHttpRequest("GET", "/");
final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers);
- final HttpRequest result = impl.buildConditionalRequest(basicRequest, cacheEntry);
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder().build();
+ final HttpRequest result = impl.buildConditionalRequest(cacheControl, basicRequest, cacheEntry);
Assertions.assertEquals(lmDate,
result.getFirstHeader("If-Modified-Since").getValue());
Assertions.assertEquals(etag,
@@ -121,7 +123,8 @@ public class TestConditionalRequestBuilder {
final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers);
- final HttpRequest newRequest = impl.buildConditionalRequest(basicRequest, cacheEntry);
+ final ResponseCacheControl cacheControl = ResponseCacheControl.builder().build();
+ final HttpRequest newRequest = impl.buildConditionalRequest(cacheControl, basicRequest, cacheEntry);
Assertions.assertEquals(theMethod, newRequest.getMethod());
Assertions.assertEquals(theUri, newRequest.getRequestUri());
@@ -145,14 +148,18 @@ public class TestConditionalRequestBuilder {
final Header[] cacheEntryHeaders = new Header[] {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("ETag", "\"etag\""),
- new BasicHeader("Cache-Control","max-age=5, must-revalidate") };
+ new BasicHeader("ETag", "\"etag\"")
+ };
final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders);
- final HttpRequest result = impl.buildConditionalRequest(basicRequest, cacheEntry);
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .setMustRevalidate(true)
+ .build();
+ final HttpRequest result = impl.buildConditionalRequest(responseCacheControl, basicRequest, cacheEntry);
- final RequestCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(result);
- Assertions.assertEquals(0, cacheControl.getMaxAge());
+ final RequestCacheControl requestCacheControl = CacheControlHeaderParser.INSTANCE.parse(result);
+ Assertions.assertEquals(0, requestCacheControl.getMaxAge());
}
@Test
@@ -165,14 +172,18 @@ public class TestConditionalRequestBuilder {
final Header[] cacheEntryHeaders = new Header[] {
new BasicHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)),
- new BasicHeader("ETag", "\"etag\""),
- new BasicHeader("Cache-Control","max-age=5, proxy-revalidate") };
+ new BasicHeader("ETag", "\"etag\"")
+ };
final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders);
- final HttpRequest result = impl.buildConditionalRequest(basicRequest, cacheEntry);
+ final ResponseCacheControl responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(5)
+ .setProxyRevalidate(true)
+ .build();
+ final HttpRequest result = impl.buildConditionalRequest(responseCacheControl, basicRequest, cacheEntry);
- final RequestCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(result);
- Assertions.assertEquals(0, cacheControl.getMaxAge());
+ final RequestCacheControl requestCacheControl = CacheControlHeaderParser.INSTANCE.parse(result);
+ Assertions.assertEquals(0, requestCacheControl.getMaxAge());
}
@Test
@@ -195,8 +206,8 @@ public class TestConditionalRequestBuilder {
public void testBuildUnconditionalRequestAddsCacheControlNoCache()
throws Exception {
final HttpRequest result = impl.buildUnconditionalRequest(request);
- final RequestCacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(result);
- Assertions.assertTrue(cacheControl.isNoCache());
+ final RequestCacheControl requestCacheControl = CacheControlHeaderParser.INSTANCE.parse(result);
+ Assertions.assertTrue(requestCacheControl.isNoCache());
}
@Test
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestResponseCachingPolicy.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestResponseCachingPolicy.java
index 00d45b9e5..74de5c73a 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestResponseCachingPolicy.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestResponseCachingPolicy.java
@@ -26,6 +26,9 @@
*/
package org.apache.hc.client5.http.impl.cache;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
import java.time.Duration;
import java.time.Instant;
import java.util.Random;
@@ -38,19 +41,14 @@ import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.message.BasicHttpRequest;
import org.apache.hc.core5.http.message.BasicHttpResponse;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
public class TestResponseCachingPolicy {
- private static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1);
private ResponseCachingPolicy policy;
private HttpResponse response;
private HttpRequest request;
@@ -60,6 +58,7 @@ public class TestResponseCachingPolicy {
private Instant now;
private Instant tenSecondsFromNow;
private Instant sixSecondsAgo;
+ private ResponseCacheControl responseCacheControl;
@BeforeEach
public void setUp() throws Exception {
@@ -72,24 +71,25 @@ public class TestResponseCachingPolicy {
response = new BasicHttpResponse(HttpStatus.SC_OK, "");
response.setHeader("Date", DateUtils.formatStandardDate(Instant.now()));
response.setHeader("Content-Length", "0");
+ responseCacheControl = ResponseCacheControl.builder().build();
}
@Test
public void testIsGetCacheable() {
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadCacheable() {
policy = new ResponseCachingPolicy(0, true, false, false, true);
- Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testResponsesToRequestsWithAuthorizationHeadersAreNotCacheableBySharedCache() {
request = new BasicHttpRequest("GET","/");
request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
- Assertions.assertTrue(policy.isResponseCacheable(request,response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -97,51 +97,60 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, false, false, false, true);
request = new BasicHttpRequest("GET","/");
request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
- Assertions.assertTrue(policy.isResponseCacheable(request,response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testAuthorizedResponsesWithSMaxAgeAreCacheable() {
request = new BasicHttpRequest("GET","/");
request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
- response.setHeader("Cache-Control","s-maxage=3600");
- Assertions.assertTrue(policy.isResponseCacheable(request,response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setSharedMaxAge(3600)
+ .build();
+
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testAuthorizedResponsesWithMustRevalidateAreCacheable() {
request = new BasicHttpRequest("GET","/");
request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
- response.setHeader("Cache-Control","must-revalidate");
- Assertions.assertTrue(policy.isResponseCacheable(request,response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMustRevalidate(true)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testAuthorizedResponsesWithCacheControlPublicAreCacheable() {
request = new BasicHttpRequest("GET","/");
request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
- response.setHeader("Cache-Control","public");
- Assertions.assertTrue(policy.isResponseCacheable(request,response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testAuthorizedResponsesWithCacheControlMaxAgeAreNotCacheable() {
request = new BasicHttpRequest("GET","/");
request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
- response.setHeader("Cache-Control","max-age=3600");
- Assertions.assertFalse(policy.isResponseCacheable(request,response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(3600)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void test203ResponseCodeIsCacheable() {
response.setCode(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION);
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void test206ResponseCodeIsNotCacheable() {
response.setCode(HttpStatus.SC_PARTIAL_CONTENT);
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -150,42 +159,42 @@ public class TestResponseCachingPolicy {
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
response.setCode(HttpStatus.SC_PARTIAL_CONTENT);
- response.setHeader("Cache-Control", "public");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void test300ResponseCodeIsCacheable() {
response.setCode(HttpStatus.SC_MULTIPLE_CHOICES);
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void test301ResponseCodeIsCacheable() {
response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void test410ResponseCodeIsCacheable() {
response.setCode(HttpStatus.SC_GONE);
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testPlain302ResponseCodeIsNotCacheable() {
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
response.removeHeaders("Expires");
- response.removeHeaders("Cache-Control");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testPlain303ResponseCodeIsNotCacheableUnderDefaultBehavior() {
response.setCode(HttpStatus.SC_SEE_OTHER);
response.removeHeaders("Expires");
- response.removeHeaders("Cache-Control");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -193,8 +202,7 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, true, true);
response.setCode(HttpStatus.SC_SEE_OTHER);
response.removeHeaders("Expires");
- response.removeHeaders("Cache-Control");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@@ -202,8 +210,7 @@ public class TestResponseCachingPolicy {
public void testPlain307ResponseCodeIsNotCacheable() {
response.setCode(HttpStatus.SC_TEMPORARY_REDIRECT);
response.removeHeaders("Expires");
- response.removeHeaders("Cache-Control");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -211,40 +218,17 @@ public class TestResponseCachingPolicy {
final int status = getRandomStatus();
response.setCode(status);
response.setHeader("Expires", DateUtils.formatStandardDate(Instant.now()));
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testNon206WithMaxAgeIsCacheable() {
final int status = getRandomStatus();
response.setCode(status);
- response.setHeader("Cache-Control", "max-age=0");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
- }
-
- @Test
- public void testMalformedHeaderValue() {
- final int status = getRandomStatus();
- response.setCode(status);
- response.setHeader("Cache-Control", "max-age=boom");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
- }
-
-
- @Test
- public void testNullHeaderValue() {
- final int status = getRandomStatus();
- response.setCode(status);
- response.setHeader("Cache-Control", null);
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
- }
-
- @Test
- public void testMultipleHeaderValue() {
- final int status = getRandomStatus();
- response.setCode(status);
- response.setHeader("Cache-Control", "s-maxage=12,must-revalidate=true,max-age=23");
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(0)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -252,201 +236,250 @@ public class TestResponseCachingPolicy {
final int status = getRandomStatus();
response.setCode(status);
response.removeHeaders(HttpHeaders.CACHE_CONTROL);
- final boolean isCacheable = policy.isResponseCacheable("GET", response);
- Assertions.assertTrue(isCacheable);
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testNon206WithSMaxAgeIsCacheable() {
final int status = getRandomStatus();
response.setCode(status);
- response.setHeader("Cache-Control", "s-maxage=0");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setSharedMaxAge(1)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testNon206WithMustRevalidateIsCacheable() {
final int status = getRandomStatus();
response.setCode(status);
- response.setHeader("Cache-Control", "must-revalidate");
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMustRevalidate(true)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testNon206WithProxyRevalidateIsCacheable() {
final int status = getRandomStatus();
response.setCode(status);
- response.setHeader("Cache-Control", "proxy-revalidate");
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setProxyRevalidate(true)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testNon206WithPublicCacheControlIsCacheable() {
final int status = getRandomStatus();
response.setCode(status);
- response.setHeader("Cache-Control", "public");
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testNon206WithPrivateCacheControlIsNotCacheableBySharedCache() {
final int status = getRandomStatus();
response.setCode(status);
- response.setHeader("Cache-Control", "private");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePrivate(true)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void test200ResponseWithPrivateCacheControlIsCacheableByNonSharedCache() {
policy = new ResponseCachingPolicy(0, false, false, false, true);
response.setCode(HttpStatus.SC_OK);
- response.setHeader("Cache-Control", "private");
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePrivate(true)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsGetWithNoCacheCacheable() {
- response.addHeader("Cache-Control", "no-cache");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setNoCache(true)
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadWithNoCacheCacheable() {
- response.addHeader("Cache-Control", "no-cache");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setNoCache(true)
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testIsGetWithNoStoreCacheable() {
- response.addHeader("Cache-Control", "no-store");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setNoStore(true)
+ .build();
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadWithNoStoreCacheable() {
- response.addHeader("Cache-Control", "no-store");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setNoStore(true)
+ .build();
- Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testIsGetWithNoStoreEmbeddedInListCacheable() {
- response.addHeader("Cache-Control", "public, no-store");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .setNoStore(true)
+ .build();
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadWithNoStoreEmbeddedInListCacheable() {
- response.addHeader("Cache-Control", "public, no-store");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .setNoStore(true)
+ .build();
- Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testIsGetWithNoCacheEmbeddedInListCacheable() {
- response.addHeader("Cache-Control", "public, no-cache");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .setNoCache(true)
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadWithNoCacheEmbeddedInListCacheable() {
- response.addHeader("Cache-Control", "public, no-cache");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .setNoCache(true)
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testIsGetWithNoCacheEmbeddedInListAfterFirstHeaderCacheable() {
- response.addHeader("Cache-Control", "max-age=20");
- response.addHeader("Cache-Control", "public, no-cache");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(20)
+ .setCachePublic(true)
+ .setNoCache(true)
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadWithNoCacheEmbeddedInListAfterFirstHeaderCacheable() {
- response.addHeader("Cache-Control", "max-age=20");
- response.addHeader("Cache-Control", "public, no-cache");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(20)
+ .setCachePublic(true)
+ .setNoCache(true)
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testIsGetWithNoStoreEmbeddedInListAfterFirstHeaderCacheable() {
- response.addHeader("Cache-Control", "max-age=20");
- response.addHeader("Cache-Control", "public, no-store");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(20)
+ .setCachePublic(true)
+ .setNoStore(true)
+ .build();
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadWithNoStoreEmbeddedInListAfterFirstHeaderCacheable() {
- response.addHeader("Cache-Control", "max-age=20");
- response.addHeader("Cache-Control", "public, no-store");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(20)
+ .setCachePublic(true)
+ .setNoStore(true)
+ .build();
- Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testIsGetWithAnyCacheControlCacheable() {
- response.addHeader("Cache-Control", "max=10");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(10)
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
response = new BasicHttpResponse(HttpStatus.SC_OK, "");
response.setHeader("Date", DateUtils.formatStandardDate(Instant.now()));
- response.addHeader("Cache-Control", "no-transform");
response.setHeader("Content-Length", "0");
+ responseCacheControl = ResponseCacheControl.builder()
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadWithAnyCacheControlCacheable() {
policy = new ResponseCachingPolicy(0, true, false, false, true);
- response.addHeader("Cache-Control", "max=10");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(10)
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
response = new BasicHttpResponse(HttpStatus.SC_OK, "");
response.setHeader("Date", DateUtils.formatStandardDate(Instant.now()));
- response.addHeader("Cache-Control", "no-transform");
response.setHeader("Content-Length", "0");
+ responseCacheControl = ResponseCacheControl.builder()
+ .build();
- Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testIsGetWithout200Cacheable() {
HttpResponse response404 = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response404));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response404));
response404 = new BasicHttpResponse(HttpStatus.SC_GATEWAY_TIMEOUT, "");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response404));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response404));
}
@Test
public void testIsHeadWithout200Cacheable() {
HttpResponse response404 = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "");
- Assertions.assertFalse(policy.isResponseCacheable("HEAD", response404));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "HEAD", response404));
response404 = new BasicHttpResponse(HttpStatus.SC_GATEWAY_TIMEOUT, "");
- Assertions.assertFalse(policy.isResponseCacheable("HEAD", response404));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "HEAD", response404));
}
@Test
public void testVaryStarIsNotCacheable() {
response.setHeader("Vary", "*");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -454,30 +487,32 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, false, true);
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
- response.setHeader("Cache-Control", "public");
response.setHeader("Vary", "*");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testIsGetWithVaryHeaderCacheable() {
response.addHeader("Vary", "Accept-Encoding");
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testIsHeadWithVaryHeaderCacheable() {
policy = new ResponseCachingPolicy(0, true, false, false, true);
response.addHeader("Vary", "Accept-Encoding");
- Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "HEAD", response));
}
@Test
public void testIsArbitraryMethodCacheable() {
- Assertions.assertFalse(policy.isResponseCacheable("PUT", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "PUT", response));
- Assertions.assertFalse(policy.isResponseCacheable("get", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "get", response));
}
@Test
@@ -487,23 +522,18 @@ public class TestResponseCachingPolicy {
request = new HttpOptions("http://foo.example.com/");
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
response.setCode(HttpStatus.SC_NO_CONTENT);
- response.setHeader("Cache-Control", "public");
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
- }
-
- @Test
- public void testResponsesToRequestsWithNoStoreAreNotCacheable() {
- request.setHeader("Cache-Control","no-store");
- response.setHeader("Cache-Control","public");
- Assertions.assertTrue(policy.isResponseCacheable(request,response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesWithMultipleAgeHeadersAreNotCacheable() {
response.addHeader("Age", "3");
response.addHeader("Age", "5");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -511,17 +541,19 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, false, true);
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
- response.setHeader("Cache-Control", "public");
response.addHeader("Age", "3");
response.addHeader("Age", "5");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesWithMultipleDateHeadersAreNotCacheable() {
response.addHeader("Date", DateUtils.formatStandardDate(now));
response.addHeader("Date", DateUtils.formatStandardDate(sixSecondsAgo));
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -529,16 +561,18 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, false, true);
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
- response.setHeader("Cache-Control", "public");
response.addHeader("Date", DateUtils.formatStandardDate(now));
response.addHeader("Date", DateUtils.formatStandardDate(sixSecondsAgo));
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesWithMalformedDateHeadersAreNotCacheable() {
response.addHeader("Date", "garbage");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -546,16 +580,18 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, false, true);
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
- response.setHeader("Cache-Control", "public");
response.addHeader("Date", "garbage");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesWithMultipleExpiresHeadersAreNotCacheable() {
response.addHeader("Expires", DateUtils.formatStandardDate(now));
response.addHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo));
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -563,22 +599,24 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, false, true);
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
- response.setHeader("Cache-Control", "public");
response.addHeader("Expires", DateUtils.formatStandardDate(now));
response.addHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo));
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesWithoutDateHeadersAreNotCacheable() {
response.removeHeaders("Date");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testResponseThatHasTooMuchContentIsNotCacheable() {
response.setHeader("Content-Length", "9000");
- Assertions.assertFalse(policy.isResponseCacheable("GET", response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
@@ -586,41 +624,43 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, false, true);
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
- response.setHeader("Cache-Control", "public");
response.setHeader("Content-Length", "9000");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setCachePublic(true)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesThatAreSmallEnoughAreCacheable() {
response.setHeader("Content-Length", "0");
- Assertions.assertTrue(policy.isResponseCacheable("GET", response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, "GET", response));
}
@Test
public void testResponsesToGETWithQueryParamsButNoExplicitCachingAreNotCacheable() {
request = new BasicHttpRequest("GET", "/foo?s=bar");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesToHEADWithQueryParamsButNoExplicitCachingAreNotCacheable() {
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesToGETWithQueryParamsButNoExplicitCachingAreNotCacheableEvenWhen1_0QueryCachingDisabled() {
policy = new ResponseCachingPolicy(0, true, true, false, false);
request = new BasicHttpRequest("GET", "/foo?s=bar");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void testResponsesToHEADWithQueryParamsButNoExplicitCachingAreNotCacheableEvenWhen1_0QueryCachingDisabled() {
policy = new ResponseCachingPolicy(0, true, true, false, false);
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -628,7 +668,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("GET", "/foo?s=bar");
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -637,7 +677,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -646,7 +686,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("GET", "/foo?s=bar");
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -655,7 +695,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -663,7 +703,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("GET", "/foo?s=bar");
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
response.setVersion(HttpVersion.HTTP_1_0);
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -671,7 +711,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
response.setVersion(HttpVersion.HTTP_1_0);
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -680,7 +720,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("GET", "/foo?s=bar");
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
response.setVersion(HttpVersion.HTTP_1_0);
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -689,7 +729,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
response.setVersion(HttpVersion.HTTP_1_0);
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -699,7 +739,7 @@ public class TestResponseCachingPolicy {
response.setVersion(HttpVersion.HTTP_1_0);
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -710,7 +750,7 @@ public class TestResponseCachingPolicy {
response.setVersion(HttpVersion.HTTP_1_0);
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -721,7 +761,7 @@ public class TestResponseCachingPolicy {
response.setVersion(HttpVersion.HTTP_1_0);
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -732,21 +772,21 @@ public class TestResponseCachingPolicy {
response.setVersion(HttpVersion.HTTP_1_0);
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreNotCacheable() {
request = new BasicHttpRequest("GET", "/foo?s=bar");
response.setHeader(HttpHeaders.VIA, "1.0 someproxy");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void headsWithQueryParametersFrom1_0OriginsViaProxiesAreNotCacheable() {
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
response.setHeader(HttpHeaders.VIA, "1.0 someproxy");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -755,7 +795,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "1.0 someproxy");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -765,7 +805,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "1.0 someproxy");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -775,7 +815,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "1.0 someproxy");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -785,7 +825,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "1.0 someproxy");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -794,7 +834,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "HTTP/1.0 someproxy");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -804,7 +844,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "HTTP/1.0 someproxy");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -814,7 +854,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "HTTP/1.0 someproxy");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -824,7 +864,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "HTTP/1.0 someproxy");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -835,7 +875,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "1.1 someproxy");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -847,31 +887,32 @@ public class TestResponseCachingPolicy {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
response.setHeader(HttpHeaders.VIA, "1.1 someproxy");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void notCacheableIfExpiresEqualsDateAndNoCacheControl() {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(now));
- response.removeHeaders("Cache-Control");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void notCacheableIfExpiresPrecedesDateAndNoCacheControl() {
response.setHeader("Date", DateUtils.formatStandardDate(now));
response.setHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo));
- response.removeHeaders("Cache-Control");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void test302WithExplicitCachingHeaders() {
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
response.setHeader("Date", DateUtils.formatStandardDate(now));
- response.setHeader("Cache-Control","max-age=300");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(300)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -879,8 +920,10 @@ public class TestResponseCachingPolicy {
// RFC 2616 says: 303 should not be cached
response.setCode(HttpStatus.SC_SEE_OTHER);
response.setHeader("Date", DateUtils.formatStandardDate(now));
- response.setHeader("Cache-Control","max-age=300");
- Assertions.assertFalse(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(300)
+ .build();
+ Assertions.assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -890,24 +933,30 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, true, true);
response.setCode(HttpStatus.SC_SEE_OTHER);
response.setHeader("Date", DateUtils.formatStandardDate(now));
- response.setHeader("Cache-Control","max-age=300");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(300)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void test307WithExplicitCachingHeaders() {
response.setCode(HttpStatus.SC_TEMPORARY_REDIRECT);
response.setHeader("Date", DateUtils.formatStandardDate(now));
- response.setHeader("Cache-Control","max-age=300");
- Assertions.assertTrue(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(300)
+ .build();
+ Assertions.assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
public void otherStatusCodesAreCacheableWithExplicitCachingHeaders() {
response.setCode(HttpStatus.SC_NOT_FOUND);
response.setHeader("Date", DateUtils.formatStandardDate(now));
- response.setHeader("Cache-Control","max-age=300");
- assertTrue(policy.isResponseCacheable(request, response));
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(300)
+ .build();
+ assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -918,16 +967,13 @@ public class TestResponseCachingPolicy {
response = new BasicHttpResponse(HttpStatus.SC_OK, "");
response.setHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(Instant.now()));
- response.setHeader(HttpHeaders.EXPIRES, DateUtils.formatStandardDate(Instant.now().plus(tenSecondsFromNow)));
+ response.setHeader(HttpHeaders.EXPIRES, DateUtils.formatStandardDate(Instant.now().plus(tenSecondsFromNow)));
// Create ResponseCachingPolicy instance and test the method
policy = new ResponseCachingPolicy(0, true, false, false, false);
request = new BasicHttpRequest("POST", "/foo");
- final boolean isCacheable = policy.isResponseCacheable(request, response);
-
- // Verify the result
- assertTrue(isCacheable);
+ assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@@ -945,11 +991,10 @@ public class TestResponseCachingPolicy {
// Create ResponseCachingPolicy instance and test the method
policy = new ResponseCachingPolicy(0, true, false, false, false);
request = new BasicHttpRequest("POST", "/foo");
- response.addHeader(HttpHeaders.CACHE_CONTROL, "s-maxage=60");
- final boolean isCacheable = policy.isResponseCacheable(request, response);
-
- // Verify the result
- assertTrue(isCacheable);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(60)
+ .build();
+ assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -966,11 +1011,10 @@ public class TestResponseCachingPolicy {
// Create ResponseCachingPolicy instance and test the method
policy = new ResponseCachingPolicy(0, true, false, false,false);
request = new BasicHttpRequest("POST", "/foo");
- response.addHeader(HttpHeaders.CACHE_CONTROL, "max-age=60");
- final boolean isCacheable = policy.isResponseCacheable(request, response);
-
- // Verify the result
- assertTrue(isCacheable);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setMaxAge(60)
+ .build();
+ assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -987,15 +1031,9 @@ public class TestResponseCachingPolicy {
// Create ResponseCachingPolicy instance and test the method
policy = new ResponseCachingPolicy(0, true, false, false,false);
request = new BasicHttpRequest("POST", "/foo");
- response.addHeader(HttpHeaders.CACHE_CONTROL, "something");
- final boolean isCacheable = policy.isResponseCacheable(request, response);
-
- // Verify the result
- assertTrue(isCacheable);
+ assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
-
-
private int getRandomStatus() {
final int rnd = new Random().nextInt(acceptableCodes.length);
@@ -1010,7 +1048,7 @@ public class TestResponseCachingPolicy {
policy = new ResponseCachingPolicy(0, true, false, false, true);
response.setCode(HttpStatus.SC_OK);
response.setHeader("Date", DateUtils.formatStandardDate(now));
- assertTrue(policy.isResponseCacheable(request, response));
+ assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -1022,11 +1060,10 @@ public class TestResponseCachingPolicy {
// Create ResponseCachingPolicy instance and test the method
policy = new ResponseCachingPolicy(0, true, false, false, false);
request = new BasicHttpRequest("GET", "/foo");
- response.addHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
- final boolean isCacheable = policy.isResponseCacheable(request, response);
-
- // Verify the result
- assertTrue(isCacheable);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setNoCache(true)
+ .build();
+ assertTrue(policy.isResponseCacheable(responseCacheControl, request, response));
}
@Test
@@ -1038,10 +1075,9 @@ public class TestResponseCachingPolicy {
// Create ResponseCachingPolicy instance and test the method
policy = new ResponseCachingPolicy(0, true, false, false, false);
request = new BasicHttpRequest("GET", "/foo");
- response.addHeader(HttpHeaders.CACHE_CONTROL, "no-store");
- final boolean isCacheable = policy.isResponseCacheable(request, response);
-
- // Verify the result
- assertFalse(isCacheable);
+ responseCacheControl = ResponseCacheControl.builder()
+ .setNoStore(true)
+ .build();
+ assertFalse(policy.isResponseCacheable(responseCacheControl, request, response));
}
}
\ No newline at end of file