HTTPCLIENT-975: stale-if-error now yields to higher-priority
directives, like must-revalidate, proxy-revalidate, and requests with explicit freshness constraints. git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1051206 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7573bf8284
commit
df577a7e8f
|
@ -506,11 +506,16 @@ public class CachingHttpClient implements HttpClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordCacheHit(HttpHost target, HttpRequest request) {
|
private void recordCacheHit(HttpHost target, HttpRequest request) {
|
||||||
|
cacheHits.getAndIncrement();
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
RequestLine rl = request.getRequestLine();
|
RequestLine rl = request.getRequestLine();
|
||||||
log.debug("Cache hit [host: " + target + "; uri: " + rl.getUri() + "]");
|
log.debug("Cache hit [host: " + target + "; uri: " + rl.getUri() + "]");
|
||||||
}
|
}
|
||||||
cacheHits.getAndIncrement();
|
}
|
||||||
|
|
||||||
|
private void recordCacheUpdate(HttpContext context) {
|
||||||
|
cacheUpdates.getAndIncrement();
|
||||||
|
setResponseStatus(context, CacheResponseStatus.VALIDATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flushEntriesInvalidatedByRequest(HttpHost target,
|
private void flushEntriesInvalidatedByRequest(HttpHost target,
|
||||||
|
@ -737,11 +742,6 @@ public class CachingHttpClient implements HttpClient {
|
||||||
return callBackend(target, unconditional, context);
|
return callBackend(target, unconditional, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordCacheUpdate(HttpContext context) {
|
|
||||||
cacheUpdates.getAndIncrement();
|
|
||||||
setResponseStatus(context, CacheResponseStatus.VALIDATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpCacheEntry getUpdatedVariantEntry(HttpHost target,
|
private HttpCacheEntry getUpdatedVariantEntry(HttpHost target,
|
||||||
HttpRequest conditionalRequest, Date requestDate,
|
HttpRequest conditionalRequest, Date requestDate,
|
||||||
Date responseDate, HttpResponse backendResponse,
|
Date responseDate, HttpResponse backendResponse,
|
||||||
|
@ -809,6 +809,7 @@ public class CachingHttpClient implements HttpClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (staleIfErrorAppliesTo(statusCode)
|
if (staleIfErrorAppliesTo(statusCode)
|
||||||
|
&& !staleResponseNotAllowed(request, cacheEntry, getCurrentDate())
|
||||||
&& validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
|
&& validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
|
||||||
final HttpResponse cachedResponse = responseGenerator.generateResponse(cacheEntry);
|
final HttpResponse cachedResponse = responseGenerator.generateResponse(cacheEntry);
|
||||||
cachedResponse.addHeader(HeaderConstants.WARNING, "110 localhost \"Response is stale\"");
|
cachedResponse.addHeader(HeaderConstants.WARNING, "110 localhost \"Response is stale\"");
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.http.impl.client.cache;
|
package org.apache.http.impl.client.cache;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
|
@ -84,7 +82,105 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
|
||||||
|
|
||||||
HttpTestUtils.assert110WarningFound(result);
|
HttpTestUtils.assert110WarningFound(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStaleIfErrorInResponseYieldsToMustRevalidate()
|
||||||
|
throws Exception{
|
||||||
|
Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L);
|
||||||
|
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
|
||||||
|
"public, max-age=5, stale-if-error=60, must-revalidate");
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp1);
|
||||||
|
|
||||||
|
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp2 = HttpTestUtils.make500Response();
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp2);
|
||||||
|
|
||||||
|
replayMocks();
|
||||||
|
impl.execute(host,req1);
|
||||||
|
HttpResponse result = impl.execute(host,req2);
|
||||||
|
verifyMocks();
|
||||||
|
|
||||||
|
assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStaleIfErrorInResponseYieldsToProxyRevalidateForSharedCache()
|
||||||
|
throws Exception{
|
||||||
|
assertTrue(impl.isSharedCache());
|
||||||
|
Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L);
|
||||||
|
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
|
||||||
|
"public, max-age=5, stale-if-error=60, proxy-revalidate");
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp1);
|
||||||
|
|
||||||
|
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp2 = HttpTestUtils.make500Response();
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp2);
|
||||||
|
|
||||||
|
replayMocks();
|
||||||
|
impl.execute(host,req1);
|
||||||
|
HttpResponse result = impl.execute(host,req2);
|
||||||
|
verifyMocks();
|
||||||
|
|
||||||
|
assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStaleIfErrorInResponseNeedNotYieldToProxyRevalidateForPrivateCache()
|
||||||
|
throws Exception{
|
||||||
|
CacheConfig config = new CacheConfig();
|
||||||
|
config.setSharedCache(false);
|
||||||
|
impl = new CachingHttpClient(mockBackend, config);
|
||||||
|
|
||||||
|
Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L);
|
||||||
|
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
|
||||||
|
"public, max-age=5, stale-if-error=60, proxy-revalidate");
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp1);
|
||||||
|
|
||||||
|
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp2 = HttpTestUtils.make500Response();
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp2);
|
||||||
|
|
||||||
|
replayMocks();
|
||||||
|
impl.execute(host,req1);
|
||||||
|
HttpResponse result = impl.execute(host,req2);
|
||||||
|
verifyMocks();
|
||||||
|
|
||||||
|
HttpTestUtils.assert110WarningFound(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStaleIfErrorInResponseYieldsToExplicitFreshnessRequest()
|
||||||
|
throws Exception{
|
||||||
|
Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L);
|
||||||
|
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
|
||||||
|
"public, max-age=5, stale-if-error=60");
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp1);
|
||||||
|
|
||||||
|
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
|
||||||
|
req2.setHeader("Cache-Control","min-fresh=2");
|
||||||
|
HttpResponse resp2 = HttpTestUtils.make500Response();
|
||||||
|
|
||||||
|
backendExpectsAnyRequest().andReturn(resp2);
|
||||||
|
|
||||||
|
replayMocks();
|
||||||
|
impl.execute(host,req1);
|
||||||
|
HttpResponse result = impl.execute(host,req2);
|
||||||
|
verifyMocks();
|
||||||
|
|
||||||
|
assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStaleIfErrorInRequestIsTrueReturnsStaleEntryWithWarning()
|
public void testStaleIfErrorInRequestIsTrueReturnsStaleEntryWithWarning()
|
||||||
throws Exception{
|
throws Exception{
|
||||||
|
@ -96,7 +192,7 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
|
||||||
backendExpectsAnyRequest().andReturn(resp1);
|
backendExpectsAnyRequest().andReturn(resp1);
|
||||||
|
|
||||||
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
|
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
|
||||||
req2.setHeader("Cache-Control","public, max-age=5, stale-if-error=60");
|
req2.setHeader("Cache-Control","public, stale-if-error=60");
|
||||||
HttpResponse resp2 = HttpTestUtils.make500Response();
|
HttpResponse resp2 = HttpTestUtils.make500Response();
|
||||||
|
|
||||||
backendExpectsAnyRequest().andReturn(resp2);
|
backendExpectsAnyRequest().andReturn(resp2);
|
||||||
|
|
Loading…
Reference in New Issue