final Map<String, Variant> variants) throws IOException, HttpException {
final HttpRequestWrapper conditionalRequest = conditionalRequestBuilder
.buildConditionalRequestFromVariants(request, variants);
final Date requestDate = getCurrentDate();
final CloseableHttpResponse backendResponse = backend.execute(
route, conditionalRequest, context, execAware);
try {
final Date responseDate = getCurrentDate();
backendResponse.addHeader("Via", generateViaHeader(backendResponse));
if (backendResponse.getStatusLine().getStatusCode() != HttpStatus.SC_NOT_MODIFIED) {
return handleBackendResponse(
route, request, context, execAware,
requestDate, responseDate, backendResponse);
}
final Header resultEtagHeader = backendResponse.getFirstHeader(HeaderConstants.ETAG);
if (resultEtagHeader == null) {
log.warn("304 response did not contain ETag");
IOUtils.consume(backendResponse.getEntity());
backendResponse.close();
return callBackend(route, request, context, execAware);
}
final String resultEtag = resultEtagHeader.getValue();
final Variant matchingVariant = variants.get(resultEtag);
if (matchingVariant == null) {
log.debug("304 response did not contain ETag matching one sent in If-None-Match");
IOUtils.consume(backendResponse.getEntity());
backendResponse.close();
return callBackend(route, request, context, execAware);
}
final HttpCacheEntry matchedEntry = matchingVariant.getEntry();
if (revalidationResponseIsTooOld(backendResponse, matchedEntry)) {
IOUtils.consume(backendResponse.getEntity());
backendResponse.close();
return retryRequestUnconditionally(route, request, context, execAware, matchedEntry);
}
recordCacheUpdate(context);
final HttpCacheEntry responseEntry = getUpdatedVariantEntry(
context.getTargetHost(), conditionalRequest, requestDate, responseDate,
backendResponse, matchingVariant, matchedEntry);
backendResponse.close();
final CloseableHttpResponse resp = responseGenerator.generateResponse(responseEntry);
tryToUpdateVariantMap(context.getTargetHost(), request, matchingVariant);
if (shouldSendNotModifiedResponse(request, responseEntry)) {
return responseGenerator.generateNotModifiedResponse(responseEntry);
}