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. git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1345297 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2451e5dec7
commit
218823fa4e
|
@ -65,6 +65,7 @@ import org.apache.http.impl.cookie.DateParseException;
|
|||
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 implements HttpClient {
|
|||
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,
|
||||
|
|
130
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyHttpClient.java
vendored
Normal file
130
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyHttpClient.java
vendored
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -60,6 +60,7 @@ import org.apache.http.message.BasicHttpResponse;
|
|||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue