You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by fx...@apache.org on 2013/07/03 20:11:35 UTC

svn commit: r1499502 - in /httpcomponents/httpclient/trunk/httpclient-cache/src: main/java/org/apache/http/impl/client/cache/ test/java/org/apache/http/impl/client/cache/

Author: fx
Date: Wed Jul  3 18:11:35 2013
New Revision: 1499502

URL: http://svn.apache.org/r1499502
Log:
HTTPCLIENT-1361: stale-while-revalidate should work also without last-modified nor etag
HTTPCLIENT-1368: stale-if-error request cache directive should also apply to non-revalidatable cache entries

Modified:
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExecChain.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRFC5861Compliance.java

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java?rev=1499502&r1=1499501&r2=1499502&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java Wed Jul  3 18:11:35 2013
@@ -279,8 +279,7 @@ public class CachingExec implements Clie
         } else if (!mayCallBackend(request)) {
             log.debug("Cache entry not suitable but only-if-cached requested");
             out = Proxies.enhanceResponse(generateGatewayTimeout(context));
-        } else if (validityPolicy.isRevalidatable(entry)
-                && !(entry.getStatusCode() == HttpStatus.SC_NOT_MODIFIED
+        } else if (!(entry.getStatusCode() == HttpStatus.SC_NOT_MODIFIED
                 && !suitabilityChecker.isConditional(request))) {
             log.debug("Revalidating cache entry");
             return revalidateCacheEntry(route, request, context, execAware, entry, now);

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java?rev=1499502&r1=1499501&r2=1499502&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java Wed Jul  3 18:11:35 2013
@@ -467,12 +467,9 @@ public class CachingHttpClient implement
         } else if (!mayCallBackend(request)) {
             log.debug("Cache entry not suitable but only-if-cached requested");
             out = generateGatewayTimeout(context);
-        } else if (validityPolicy.isRevalidatable(entry)) {
+        } else {
             log.debug("Revalidating cache entry");
             return revalidateCacheEntry(target, request, context, entry, now);
-        } else {
-            log.debug("Cache entry not usable; calling backend");
-            return callBackend(target, request, context);
         }
         if (context != null) {
             context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java?rev=1499502&r1=1499501&r2=1499502&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java Wed Jul  3 18:11:35 2013
@@ -56,6 +56,7 @@ import org.apache.http.conn.routing.Http
 import org.apache.http.impl.execchain.ClientExecChain;
 import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.message.BasicStatusLine;
 import org.easymock.IExpectationSetters;
 import org.easymock.classextension.EasyMock;
 import org.junit.Assert;
@@ -187,7 +188,12 @@ public class TestCachingExec extends Tes
         getCacheEntryReturns(mockCacheEntry);
         cacheEntrySuitable(false);
         cacheEntryValidatable(false);
-        implExpectsAnyRequestAndReturn(mockBackendResponse);
+        expect(mockConditionalRequestBuilder.buildConditionalRequest(request, mockCacheEntry))
+            .andReturn(request);
+        backendExpectsRequestAndReturn(request, mockBackendResponse);
+        expect(mockBackendResponse.getProtocolVersion()).andReturn(HttpVersion.HTTP_1_1);
+        expect(mockBackendResponse.getStatusLine()).andReturn(
+            new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "Ok"));
 
         replayMocks();
         final HttpResponse result = impl.execute(route, request, context);
@@ -196,7 +202,7 @@ public class TestCachingExec extends Tes
         Assert.assertSame(mockBackendResponse, result);
         Assert.assertEquals(0, impl.getCacheMisses());
         Assert.assertEquals(1, impl.getCacheHits());
-        Assert.assertEquals(0, impl.getCacheUpdates());
+        Assert.assertEquals(1, impl.getCacheUpdates());
     }
 
     @Test

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExecChain.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExecChain.java?rev=1499502&r1=1499501&r2=1499502&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExecChain.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExecChain.java Wed Jul  3 18:11:35 2013
@@ -1650,7 +1650,7 @@ public abstract class TestCachingExecCha
 
     protected void cacheEntryValidatable(final boolean b) {
         expect(mockValidityPolicy.isRevalidatable(
-                (HttpCacheEntry)anyObject())).andReturn(b);
+                (HttpCacheEntry)anyObject())).andReturn(b).anyTimes();
     }
 
     protected void cacheEntryMustRevalidate(final boolean b) {

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRFC5861Compliance.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRFC5861Compliance.java?rev=1499502&r1=1499501&r2=1499502&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRFC5861Compliance.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRFC5861Compliance.java Wed Jul  3 18:11:35 2013
@@ -240,6 +240,31 @@ public class TestRFC5861Compliance exten
     }
 
     @Test
+    public void testStaleIfErrorInRequestIsTrueReturnsStaleNonRevalidatableEntryWithWarning()
+        throws Exception {
+        final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L);
+        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
+        final HttpResponse resp1 = HttpTestUtils.make200Response();
+        resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
+        resp1.setHeader("Cache-Control", "public, max-age=5");
+
+        backendExpectsAnyRequestAndReturn(resp1);
+
+        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
+        req2.setHeader("Cache-Control", "public, stale-if-error=60");
+        final HttpResponse resp2 = HttpTestUtils.make500Response();
+
+        backendExpectsAnyRequestAndReturn(resp2);
+
+        replayMocks();
+        impl.execute(route, req1, context, null);
+        final HttpResponse result = impl.execute(route, req2, context, null);
+        verifyMocks();
+
+        HttpTestUtils.assert110WarningFound(result);
+    }
+
+    @Test
     public void testStaleIfErrorInResponseIsFalseReturnsError()
             throws Exception{
         final Date now = new Date();
@@ -342,6 +367,45 @@ public class TestRFC5861Compliance exten
     }
 
     @Test
+    public void testStaleWhileRevalidateReturnsStaleNonRevalidatableEntryWithWarning()
+        throws Exception {
+        config = CacheConfig.custom().setMaxCacheEntries(MAX_ENTRIES).setMaxObjectSize(MAX_BYTES)
+            .setAsynchronousWorkersMax(1).build();
+
+        impl = new CachingExec(mockBackend, cache, config, new AsynchronousValidator(config));
+
+        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/",
+            HttpVersion.HTTP_1_1));
+        final HttpResponse resp1 = HttpTestUtils.make200Response();
+        final Date now = new Date();
+        final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
+        resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15");
+        resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
+
+        backendExpectsAnyRequestAndReturn(resp1).times(1, 2);
+
+        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/",
+            HttpVersion.HTTP_1_1));
+
+        replayMocks();
+        impl.execute(route, req1, context, null);
+        final HttpResponse result = impl.execute(route, req2, context, null);
+        verifyMocks();
+
+        assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
+        boolean warning110Found = false;
+        for (final Header h : result.getHeaders("Warning")) {
+            for (final WarningValue wv : WarningValue.getWarningValues(h)) {
+                if (wv.getWarnCode() == 110) {
+                    warning110Found = true;
+                    break;
+                }
+            }
+        }
+        assertTrue(warning110Found);
+    }
+
+    @Test
     public void testCanAlsoServeStale304sWhileRevalidating()
         throws Exception {