Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ public void cancelled() {
if (LOG.isDebugEnabled()) {
LOG.debug("{} request cannot be served from cache", exchangeId);
}
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback);
}
}

Expand All @@ -414,6 +414,7 @@ void chainProceed(
}

void callBackend(
final RequestCacheControl requestCacheControl,
final HttpHost target,
final HttpRequest request,
final AsyncEntityProducer entityProducer,
Expand All @@ -434,7 +435,7 @@ public AsyncDataConsumer handleResponse(
final HttpResponse backendResponse,
final EntityDetails entityDetails) throws HttpException, IOException {
final Instant responseDate = getCurrentDate();
final AsyncExecCallback callback = new BackendResponseHandler(target, request, requestDate, responseDate, scope, asyncExecCallback);
final AsyncExecCallback callback = new BackendResponseHandler(requestCacheControl, target, request, requestDate, responseDate, scope, asyncExecCallback);
callbackRef.set(callback);
return callback.handleResponse(backendResponse, entityDetails);
}
Expand Down Expand Up @@ -563,6 +564,7 @@ public void releaseResources() {

class BackendResponseHandler implements AsyncExecCallback {

private final RequestCacheControl requestCacheControl;
private final HttpHost target;
private final HttpRequest request;
private final Instant requestDate;
Expand All @@ -572,12 +574,14 @@ class BackendResponseHandler implements AsyncExecCallback {
private final AtomicReference<CachingAsyncDataConsumer> cachingConsumerRef;

BackendResponseHandler(
final RequestCacheControl requestCacheControl,
final HttpHost target,
final HttpRequest request,
final Instant requestDate,
final Instant responseDate,
final AsyncExecChain.Scope scope,
final AsyncExecCallback asyncExecCallback) {
this.requestCacheControl = requestCacheControl;
this.target = target;
this.request = request;
this.requestDate = requestDate;
Expand Down Expand Up @@ -620,7 +624,8 @@ public void cancelled() {
final HttpCacheContext context = HttpCacheContext.cast(scope.clientContext);
final ResponseCacheControl responseCacheControl = CacheControlHeaderParser.INSTANCE.parse(backendResponse);
context.setResponseCacheControl(responseCacheControl);
final boolean cacheable = responseCachingPolicy.isResponseCacheable(responseCacheControl, request, backendResponse);
final boolean cacheable = responseCachingPolicy.isResponseCacheable(
requestCacheControl, responseCacheControl, request, backendResponse);
if (cacheable) {
storeRequestIfModifiedSinceFor304Response(request, backendResponse);
if (LOG.isDebugEnabled()) {
Expand Down Expand Up @@ -870,22 +875,22 @@ private void handleCacheHit(
if (LOG.isDebugEnabled()) {
LOG.debug("{} cache entry does not match the request; calling backend", exchangeId);
}
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback);
} else if (entityProducer != null && !entityProducer.isRepeatable()) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} request is not repeatable; calling backend", exchangeId);
}
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback);
} else if (hit.entry.getStatus() == HttpStatus.SC_NOT_MODIFIED && !suitabilityChecker.isConditional(request)) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} non-modified cache entry does not match the non-conditional request; calling backend", exchangeId);
}
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback);
} else if (cacheSuitability == CacheSuitability.REVALIDATION_REQUIRED) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} revalidation required; revalidating cache entry", exchangeId);
}
revalidateCacheEntryWithoutFallback(responseCacheControl, hit, target, request, entityProducer, scope, chain, asyncExecCallback);
revalidateCacheEntryWithoutFallback(requestCacheControl, responseCacheControl, hit, target, request, entityProducer, scope, chain, asyncExecCallback);
} else if (cacheSuitability == CacheSuitability.STALE_WHILE_REVALIDATED) {
if (cacheRevalidator != null) {
if (LOG.isDebugEnabled()) {
Expand All @@ -909,7 +914,7 @@ private void handleCacheHit(
cacheRevalidator.revalidateCacheEntry(
hit.getEntryKey(),
asyncExecCallback,
c -> revalidateCacheEntry(responseCacheControl, hit, target, request, entityProducer, fork, chain, c));
c -> revalidateCacheEntry(requestCacheControl, responseCacheControl, hit, target, request, entityProducer, fork, chain, c));
context.setCacheResponseStatus(CacheResponseStatus.CACHE_MODULE_RESPONSE);
final SimpleHttpResponse cacheResponse = responseGenerator.generateResponse(request, hit.entry);
context.setCacheEntry(hit.entry);
Expand All @@ -932,12 +937,13 @@ private void handleCacheHit(
if (LOG.isDebugEnabled()) {
LOG.debug("{} cache entry not usable; calling backend", exchangeId);
}
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback);
}
}
}

void revalidateCacheEntry(
final RequestCacheControl requestCacheControl,
final ResponseCacheControl responseCacheControl,
final CacheHit hit,
final HttpHost target,
Expand Down Expand Up @@ -1000,7 +1006,7 @@ AsyncExecCallback evaluateResponse(final HttpResponse backendResponse, final Ins
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
return new AsyncExecCallbackWrapper(() -> triggerUpdatedCacheEntryResponse(backendResponse, responseDate), asyncExecCallback::failed);
}
return new BackendResponseHandler(target, conditionalRequest, requestDate, responseDate, scope, asyncExecCallback);
return new BackendResponseHandler(requestCacheControl, target, conditionalRequest, requestDate, responseDate, scope, asyncExecCallback);
}

@Override
Expand Down Expand Up @@ -1101,6 +1107,7 @@ public void failed(final Exception cause) {
}

void revalidateCacheEntryWithoutFallback(
final RequestCacheControl requestCacheControl,
final ResponseCacheControl responseCacheControl,
final CacheHit hit,
final HttpHost target,
Expand All @@ -1111,7 +1118,7 @@ void revalidateCacheEntryWithoutFallback(
final AsyncExecCallback asyncExecCallback) {
final String exchangeId = scope.exchangeId;
final HttpCacheContext context = HttpCacheContext.cast(scope.clientContext);
revalidateCacheEntry(responseCacheControl, hit, target, request, entityProducer, scope, chain, new AsyncExecCallback() {
revalidateCacheEntry(requestCacheControl, responseCacheControl, hit, target, request, entityProducer, scope, chain, new AsyncExecCallback() {

private final AtomicBoolean committed = new AtomicBoolean();

Expand Down Expand Up @@ -1161,7 +1168,7 @@ void revalidateCacheEntryWithFallback(
final AsyncExecCallback asyncExecCallback) {
final String exchangeId = scope.exchangeId;
final HttpCacheContext context = HttpCacheContext.cast(scope.clientContext);
revalidateCacheEntry(responseCacheControl, hit, target, request, entityProducer, scope, chain, new AsyncExecCallback() {
revalidateCacheEntry(requestCacheControl, responseCacheControl, hit, target, request, entityProducer, scope, chain, new AsyncExecCallback() {

private final AtomicReference<HttpResponse> committed = new AtomicReference<>();

Expand Down Expand Up @@ -1267,9 +1274,9 @@ private void handleCacheMiss(
@Override
public void completed(final Collection<CacheHit> variants) {
if (variants != null && !variants.isEmpty()) {
negotiateResponseFromVariants(target, request, entityProducer, scope, chain, asyncExecCallback, variants);
negotiateResponseFromVariants(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback, variants);
} else {
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback);
}
}

Expand All @@ -1285,11 +1292,12 @@ public void cancelled() {

}));
} else {
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback);
}
}

void negotiateResponseFromVariants(
final RequestCacheControl requestCacheControl,
final HttpHost target,
final HttpRequest request,
final AsyncEntityProducer entityProducer,
Expand Down Expand Up @@ -1361,26 +1369,26 @@ public AsyncDataConsumer handleResponse(
final Instant responseDate = getCurrentDate();
final AsyncExecCallback callback;
if (backendResponse.getCode() != HttpStatus.SC_NOT_MODIFIED) {
callback = new BackendResponseHandler(target, request, requestDate, responseDate, scope, asyncExecCallback);
callback = new BackendResponseHandler(requestCacheControl, target, request, requestDate, responseDate, scope, asyncExecCallback);
} else {
final ETag resultEtag = ETag.get(backendResponse);
if (resultEtag == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} 304 response did not contain ETag", exchangeId);
}
callback = new AsyncExecCallbackWrapper(() -> callBackend(target, request, entityProducer, scope, chain, asyncExecCallback), asyncExecCallback::failed);
callback = new AsyncExecCallbackWrapper(() -> callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback), asyncExecCallback::failed);
} else {
final CacheHit match = variantMap.get(resultEtag);
if (match == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} 304 response did not contain ETag matching one sent in If-None-Match", exchangeId);
}
callback = new AsyncExecCallbackWrapper(() -> callBackend(target, request, entityProducer, scope, chain, asyncExecCallback), asyncExecCallback::failed);
callback = new AsyncExecCallbackWrapper(() -> callBackend(requestCacheControl, target, request, entityProducer, scope, chain, asyncExecCallback), asyncExecCallback::failed);
} else {
if (HttpCacheEntry.isNewer(match.entry, backendResponse)) {
final HttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(
BasicRequestBuilder.copy(request).build());
callback = new AsyncExecCallbackWrapper(() -> callBackend(target, unconditional, entityProducer, scope, chain, asyncExecCallback), asyncExecCallback::failed);
callback = new AsyncExecCallbackWrapper(() -> callBackend(requestCacheControl, target, unconditional, entityProducer, scope, chain, asyncExecCallback), asyncExecCallback::failed);
} else {
callback = new AsyncExecCallbackWrapper(() -> updateVariantCacheEntry(backendResponse, responseDate, match), asyncExecCallback::failed);
}
Expand Down
Loading
Loading