You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by jo...@apache.org on 2012/06/01 20:09:50 UTC

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

Author: jonm
Date: Fri Jun  1 18:09:49 2012
New Revision: 1345297

URL: http://svn.apache.org/viewvc?rev=1345297&view=rev
Log:
HTTPCLIENT-1198: HttpHost is not set in HttpContext in CachingHttpClient.
This patch (with tests) primarily just needs to figure out how to set
appropriate context variables in the event of a pure cache hit--in the
event of a cache miss or a cache validation, we actually make an origin
request, and the "backend" client sets these context variables.

Added:
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyHttpClient.java   (with props)
Modified:
    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/TestCachingHttpClient.java

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=1345297&r1=1345296&r2=1345297&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 Fri Jun  1 18:09:49 2012
@@ -65,6 +65,7 @@ import org.apache.http.impl.cookie.DateP
 import org.apache.http.impl.cookie.DateUtils;
 import org.apache.http.message.BasicHttpResponse;
 import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.EntityUtils;
@@ -440,20 +441,24 @@ public class CachingHttpClient implement
             HttpContext context, HttpCacheEntry entry)
             throws ClientProtocolException, IOException {
         recordCacheHit(target, request);
-
+        HttpResponse out = null;
         Date now = getCurrentDate();
         if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) {
-            return generateCachedResponse(request, context, entry, now);
-        }
-
-        if (!mayCallBackend(request)) {
-            return generateGatewayTimeout(context);
-        }
-
-        if (validityPolicy.isRevalidatable(entry)) {
+            out = generateCachedResponse(request, context, entry, now);
+        } else if (!mayCallBackend(request)) {
+            out = generateGatewayTimeout(context);
+        } else if (validityPolicy.isRevalidatable(entry)) {
             return revalidateCacheEntry(target, request, context, entry, now);
+        } else {
+        	return callBackend(target, request, context);
         }
-        return callBackend(target, request, context);
+        if (context != null) {
+        	context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
+        	context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+        	context.setAttribute(ExecutionContext.HTTP_RESPONSE, out);
+        	context.setAttribute(ExecutionContext.HTTP_REQ_SENT, true);
+        }
+        return out;
     }
 
     private HttpResponse revalidateCacheEntry(HttpHost target,

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyHttpClient.java?rev=1345297&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyHttpClient.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyHttpClient.java Fri Jun  1 18:09:49 2012
@@ -0,0 +1,130 @@
+/*
+ * ====================================================================
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.client.cache;
+
+import java.io.IOException;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.ProtocolVersion;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.impl.conn.SingleClientConnManager;
+import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+
+@SuppressWarnings("deprecation")
+public class DummyHttpClient implements HttpClient {
+
+    private HttpParams params = new BasicHttpParams();
+    private ClientConnectionManager connManager = new SingleClientConnManager();
+    private HttpRequest request;
+    private HttpResponse response = new BasicHttpResponse(new ProtocolVersion("HTTP",1,1), HttpStatus.SC_OK, "OK");
+    
+    public void setParams(HttpParams params) {
+        this.params = params;
+    }
+    
+    public HttpParams getParams() {
+        return params;
+    }
+
+    public ClientConnectionManager getConnectionManager() {
+        return connManager;
+    }
+    
+    public void setConnectionManager(ClientConnectionManager ccm) {
+        connManager = ccm;
+    }
+    
+    public void setResponse(HttpResponse resp) {
+        response = resp;
+    }
+    
+    public HttpRequest getCapturedRequest() {
+        return request;
+    }
+
+    public HttpResponse execute(HttpUriRequest request) throws IOException,
+            ClientProtocolException {
+        this.request = request;
+        return response;
+    }
+
+    public HttpResponse execute(HttpUriRequest request, HttpContext context)
+            throws IOException, ClientProtocolException {
+        this.request = request;
+        return response;
+    }
+
+    public HttpResponse execute(HttpHost target, HttpRequest request)
+            throws IOException, ClientProtocolException {
+        this.request = request;
+        return response;
+    }
+
+    public HttpResponse execute(HttpHost target, HttpRequest request,
+            HttpContext context) throws IOException, ClientProtocolException {
+        this.request = request;
+        return response;
+    }
+
+    public <T> T execute(HttpUriRequest request,
+            ResponseHandler<? extends T> responseHandler) throws IOException,
+            ClientProtocolException {
+        this.request = request;
+        return responseHandler.handleResponse(response);
+    }
+
+    public <T> T execute(HttpUriRequest request,
+            ResponseHandler<? extends T> responseHandler, HttpContext context)
+            throws IOException, ClientProtocolException {
+        this.request = request;
+        return responseHandler.handleResponse(response);
+    }
+
+    public <T> T execute(HttpHost target, HttpRequest request,
+            ResponseHandler<? extends T> responseHandler) throws IOException,
+            ClientProtocolException {
+        this.request = request;
+        return responseHandler.handleResponse(response);
+    }
+
+    public <T> T execute(HttpHost target, HttpRequest request,
+            ResponseHandler<? extends T> responseHandler, HttpContext context)
+            throws IOException, ClientProtocolException {
+        this.request = request;
+        return responseHandler.handleResponse(response);
+    }
+
+}

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyHttpClient.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java?rev=1345297&r1=1345296&r2=1345297&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java Fri Jun  1 18:09:49 2012
@@ -60,6 +60,7 @@ import org.apache.http.message.BasicHttp
 import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
 import org.easymock.Capture;
 import static org.easymock.classextension.EasyMock.*;
@@ -1871,7 +1872,137 @@ public class TestCachingHttpClient {
 
         Assert.assertSame(mockCachedResponse, resp);
     }
-
+    
+    private DummyHttpClient getContextSettingBackend(final Object value, final HttpResponse response) {
+    	return new DummyHttpClient() {
+    		@Override
+    		public HttpResponse execute(HttpHost target, HttpRequest request,
+    	            HttpContext context) throws IOException, ClientProtocolException {
+    			if (context != null) {
+    				context.setAttribute(ExecutionContext.HTTP_CONNECTION, value);
+    				context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, value);
+    				context.setAttribute(ExecutionContext.HTTP_REQ_SENT, value);
+    				context.setAttribute(ExecutionContext.HTTP_REQUEST, value);
+    				context.setAttribute(ExecutionContext.HTTP_RESPONSE, value);
+    				context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, value);
+    			}
+    			return response;
+    	    }
+    	};
+    }
+    
+	private void assertAllContextVariablesAreEqualTo(HttpContext ctx,
+			final Object value) {
+		assertSame(value, ctx.getAttribute(ExecutionContext.HTTP_CONNECTION));
+    	assertSame(value, ctx.getAttribute(ExecutionContext.HTTP_PROXY_HOST));
+    	assertSame(value, ctx.getAttribute(ExecutionContext.HTTP_REQ_SENT));
+    	assertSame(value, ctx.getAttribute(ExecutionContext.HTTP_REQUEST));
+    	assertSame(value, ctx.getAttribute(ExecutionContext.HTTP_RESPONSE));
+    	assertSame(value, ctx.getAttribute(ExecutionContext.HTTP_TARGET_HOST));
+	}
+
+	@Test
+	public void testAllowsBackendToSetHttpContextVariablesOnCacheMiss() throws Exception {
+		final Object value = new Object(); 
+		impl = new CachingHttpClient(getContextSettingBackend(value, HttpTestUtils.make200Response()));
+		HttpContext ctx = new BasicHttpContext();
+		impl.execute(host, request, ctx);
+		assertAllContextVariablesAreEqualTo(ctx, value);
+	}
+	
+	@Test
+	public void testDoesNotSetConnectionInContextOnCacheHit() throws Exception {
+		DummyHttpClient backend = new DummyHttpClient();
+		HttpResponse response = HttpTestUtils.make200Response();
+		response.setHeader("Cache-Control", "max-age=3600");
+		backend.setResponse(response);
+		impl = new CachingHttpClient(backend);
+		HttpContext ctx = new BasicHttpContext();
+		impl.execute(host, request);
+		impl.execute(host, request, ctx);
+		assertNull(ctx.getAttribute(ExecutionContext.HTTP_CONNECTION));
+	}
+	
+	@Test
+	public void testDoesNotSetProxyHostInContextOnCacheHit() throws Exception {
+		DummyHttpClient backend = new DummyHttpClient();
+		HttpResponse response = HttpTestUtils.make200Response();
+		response.setHeader("Cache-Control", "max-age=3600");
+		backend.setResponse(response);
+		impl = new CachingHttpClient(backend);
+		HttpContext ctx = new BasicHttpContext();
+		impl.execute(host, request);
+		impl.execute(host, request, ctx);
+		assertNull(ctx.getAttribute(ExecutionContext.HTTP_PROXY_HOST));
+	}
+	
+	@Test
+	public void testSetsTargetHostInContextOnCacheHit() throws Exception {
+		DummyHttpClient backend = new DummyHttpClient();
+		HttpResponse response = HttpTestUtils.make200Response();
+		response.setHeader("Cache-Control", "max-age=3600");
+		backend.setResponse(response);
+		impl = new CachingHttpClient(backend);
+		HttpContext ctx = new BasicHttpContext();
+		impl.execute(host, request);
+		impl.execute(host, request, ctx);
+		assertSame(host, ctx.getAttribute(ExecutionContext.HTTP_TARGET_HOST));
+	}
+
+	@Test
+	public void testSetsRequestInContextOnCacheHit() throws Exception {
+		DummyHttpClient backend = new DummyHttpClient();
+		HttpResponse response = HttpTestUtils.make200Response();
+		response.setHeader("Cache-Control", "max-age=3600");
+		backend.setResponse(response);
+		impl = new CachingHttpClient(backend);
+		HttpContext ctx = new BasicHttpContext();
+		impl.execute(host, request);
+		impl.execute(host, request, ctx);
+		assertSame(request, ctx.getAttribute(ExecutionContext.HTTP_REQUEST));
+	}
+
+	@Test
+	public void testSetsResponseInContextOnCacheHit() throws Exception {
+		DummyHttpClient backend = new DummyHttpClient();
+		HttpResponse response = HttpTestUtils.make200Response();
+		response.setHeader("Cache-Control", "max-age=3600");
+		backend.setResponse(response);
+		impl = new CachingHttpClient(backend);
+		HttpContext ctx = new BasicHttpContext();
+		impl.execute(host, request);
+		HttpResponse result = impl.execute(host, request, ctx);
+		assertSame(result, ctx.getAttribute(ExecutionContext.HTTP_RESPONSE));
+	}
+	
+	@Test
+	public void testSetsRequestSentInContextOnCacheHit() throws Exception {
+		DummyHttpClient backend = new DummyHttpClient();
+		HttpResponse response = HttpTestUtils.make200Response();
+		response.setHeader("Cache-Control", "max-age=3600");
+		backend.setResponse(response);
+		impl = new CachingHttpClient(backend);
+		HttpContext ctx = new BasicHttpContext();
+		impl.execute(host, request);
+		impl.execute(host, request, ctx);
+		assertTrue((Boolean)ctx.getAttribute(ExecutionContext.HTTP_REQ_SENT));
+	}
+	
+	@Test
+	public void testAllowsBackendToSetContextVariablesOnRevalidation() throws Exception {
+		final Object value = new Object(); 
+		HttpResponse response = HttpTestUtils.make200Response();
+		response.setHeader("Cache-Control","public");
+		response.setHeader("Etag", "\"v1\"");
+		DummyHttpClient backend = getContextSettingBackend(value, response);
+		backend.setResponse(response);
+		impl = new CachingHttpClient(backend);
+		HttpContext ctx = new BasicHttpContext();
+		impl.execute(host, request);
+		impl.execute(host, request, ctx);
+		assertAllContextVariablesAreEqualTo(ctx, value);
+	}
+	
     private void getCacheEntryReturns(HttpCacheEntry result) throws IOException {
         expect(mockCache.getCacheEntry(host, request)).andReturn(result);
     }