HTTPCLIENT-1015: Support only-if-cached directive
Contributed by Michajlo Matijkiw <michajlo_matijkiw at comcast.com> git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1024383 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e4d6204517
commit
de7daf36de
|
@ -407,6 +407,11 @@ public class CachingHttpClient implements HttpClient {
|
||||||
log.debug("Cache miss [host: " + target + "; uri: " + rl.getUri() + "]");
|
log.debug("Cache miss [host: " + target + "; uri: " + rl.getUri() + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mayCallBackend(request)) {
|
||||||
|
return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT,
|
||||||
|
"Gateway Timeout");
|
||||||
|
}
|
||||||
|
|
||||||
Set<HttpCacheEntry> variantEntries = null;
|
Set<HttpCacheEntry> variantEntries = null;
|
||||||
try {
|
try {
|
||||||
responseCache.getVariantCacheEntries(target, request);
|
responseCache.getVariantCacheEntries(target, request);
|
||||||
|
@ -447,6 +452,11 @@ public class CachingHttpClient implements HttpClient {
|
||||||
return cachedResponse;
|
return cachedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mayCallBackend(request)) {
|
||||||
|
return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT,
|
||||||
|
"Gateway Timeout");
|
||||||
|
}
|
||||||
|
|
||||||
if (validityPolicy.isRevalidatable(entry)) {
|
if (validityPolicy.isRevalidatable(entry)) {
|
||||||
log.debug("Revalidating the cache entry");
|
log.debug("Revalidating the cache entry");
|
||||||
|
|
||||||
|
@ -472,6 +482,17 @@ public class CachingHttpClient implements HttpClient {
|
||||||
return callBackend(target, request, context);
|
return callBackend(target, request, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean mayCallBackend(HttpRequest request) {
|
||||||
|
for (Header h: request.getHeaders("Cache-Control")) {
|
||||||
|
for (HeaderElement elt : h.getElements()) {
|
||||||
|
if ("only-if-cached".equals(elt.getName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean explicitFreshnessRequest(HttpRequest request, HttpCacheEntry entry, Date now) {
|
private boolean explicitFreshnessRequest(HttpRequest request, HttpCacheEntry entry, Date now) {
|
||||||
for(Header h : request.getHeaders("Cache-Control")) {
|
for(Header h : request.getHeaders("Cache-Control")) {
|
||||||
for(HeaderElement elt : h.getElements()) {
|
for(HeaderElement elt : h.getElements()) {
|
||||||
|
|
|
@ -1931,6 +1931,59 @@ public class TestCachingHttpClient {
|
||||||
Assert.assertSame(resp, result);
|
Assert.assertSame(resp, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIfOnlyIfCachedAndNoCacheEntryBackendNotCalled() throws IOException {
|
||||||
|
impl = new CachingHttpClient(mockBackend);
|
||||||
|
|
||||||
|
request.addHeader("Cache-Control", "only-if-cached");
|
||||||
|
|
||||||
|
HttpResponse resp = impl.execute(host, request);
|
||||||
|
|
||||||
|
Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIfOnlyIfCachedAndEntryNotSuitableBackendNotCalled() throws Exception {
|
||||||
|
|
||||||
|
request.setHeader("Cache-Control", "only-if-cached");
|
||||||
|
|
||||||
|
entry = HttpTestUtils.makeCacheEntry(new Header[]{new BasicHeader("Cache-Control", "must-revalidate")});
|
||||||
|
|
||||||
|
requestIsFatallyNonCompliant(null);
|
||||||
|
requestProtocolValidationIsCalled();
|
||||||
|
cacheInvalidatorWasCalled();
|
||||||
|
requestPolicyAllowsCaching(true);
|
||||||
|
getCacheEntryReturns(entry);
|
||||||
|
cacheEntrySuitable(false);
|
||||||
|
|
||||||
|
replayMocks();
|
||||||
|
HttpResponse resp = impl.execute(host, request);
|
||||||
|
verifyMocks();
|
||||||
|
|
||||||
|
Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIfOnlyIfCachedAndEntryExistsAndIsSuitableReturnsEntry() throws Exception {
|
||||||
|
|
||||||
|
request.setHeader("Cache-Control", "only-if-cached");
|
||||||
|
|
||||||
|
requestIsFatallyNonCompliant(null);
|
||||||
|
requestProtocolValidationIsCalled();
|
||||||
|
cacheInvalidatorWasCalled();
|
||||||
|
requestPolicyAllowsCaching(true);
|
||||||
|
getCacheEntryReturns(entry);
|
||||||
|
cacheEntrySuitable(true);
|
||||||
|
responseIsGeneratedFromCache();
|
||||||
|
entryHasStaleness(0);
|
||||||
|
|
||||||
|
replayMocks();
|
||||||
|
HttpResponse resp = impl.execute(host, request);
|
||||||
|
verifyMocks();
|
||||||
|
|
||||||
|
Assert.assertSame(mockCachedResponse, resp);
|
||||||
|
}
|
||||||
|
|
||||||
private void getCacheEntryReturns(HttpCacheEntry result) throws IOException {
|
private void getCacheEntryReturns(HttpCacheEntry result) throws IOException {
|
||||||
EasyMock.expect(mockCache.getCacheEntry(host, request)).andReturn(result);
|
EasyMock.expect(mockCache.getCacheEntry(host, request)).andReturn(result);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue