Added cache specific HttpContext adaptor
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1419448 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c98900ebd8
commit
b257aeec70
71
httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheContext.java
vendored
Normal file
71
httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheContext.java
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.client.cache;
|
||||||
|
|
||||||
|
import org.apache.http.annotation.NotThreadSafe;
|
||||||
|
import org.apache.http.client.protocol.HttpClientContext;
|
||||||
|
import org.apache.http.protocol.BasicHttpContext;
|
||||||
|
import org.apache.http.protocol.HttpContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
@NotThreadSafe
|
||||||
|
public class HttpCacheContext extends HttpClientContext {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the name under which the {@link CacheResponseStatus} of a request
|
||||||
|
* (for example, whether it resulted in a cache hit) will be recorded if an
|
||||||
|
* {@link HttpContext} is provided during execution.
|
||||||
|
*/
|
||||||
|
public static final String CACHE_RESPONSE_STATUS = "http.cache.response.status";
|
||||||
|
|
||||||
|
public static HttpCacheContext adapt(final HttpContext context) {
|
||||||
|
if (context instanceof HttpCacheContext) {
|
||||||
|
return (HttpCacheContext) context;
|
||||||
|
} else {
|
||||||
|
return new HttpCacheContext(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpCacheContext create() {
|
||||||
|
return new HttpCacheContext(new BasicHttpContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpCacheContext(final HttpContext context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpCacheContext() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CacheResponseStatus getCacheResponseStatus() {
|
||||||
|
return getAttribute(CACHE_RESPONSE_STATUS, CacheResponseStatus.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ import org.apache.http.RequestLine;
|
||||||
import org.apache.http.annotation.ThreadSafe;
|
import org.apache.http.annotation.ThreadSafe;
|
||||||
import org.apache.http.client.cache.CacheResponseStatus;
|
import org.apache.http.client.cache.CacheResponseStatus;
|
||||||
import org.apache.http.client.cache.HeaderConstants;
|
import org.apache.http.client.cache.HeaderConstants;
|
||||||
|
import org.apache.http.client.cache.HttpCacheContext;
|
||||||
import org.apache.http.client.cache.HttpCacheEntry;
|
import org.apache.http.client.cache.HttpCacheEntry;
|
||||||
import org.apache.http.client.cache.HttpCacheStorage;
|
import org.apache.http.client.cache.HttpCacheStorage;
|
||||||
import org.apache.http.client.cache.ResourceFactory;
|
import org.apache.http.client.cache.ResourceFactory;
|
||||||
|
@ -89,14 +90,6 @@ import org.apache.http.util.VersionInfo;
|
||||||
@ThreadSafe // So long as the responseCache implementation is threadsafe
|
@ThreadSafe // So long as the responseCache implementation is threadsafe
|
||||||
public class CachingExec implements ClientExecChain {
|
public class CachingExec implements ClientExecChain {
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the name under which the {@link
|
|
||||||
* org.apache.http.client.cache.CacheResponseStatus} of a request
|
|
||||||
* (for example, whether it resulted in a cache hit) will be recorded if an
|
|
||||||
* {@link HttpContext} is provided during execution.
|
|
||||||
*/
|
|
||||||
public static final String CACHE_RESPONSE_STATUS = "http.cache.response.status";
|
|
||||||
|
|
||||||
private final static boolean SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS = false;
|
private final static boolean SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS = false;
|
||||||
|
|
||||||
private final AtomicLong cacheHits = new AtomicLong();
|
private final AtomicLong cacheHits = new AtomicLong();
|
||||||
|
@ -532,7 +525,7 @@ public class CachingExec implements ClientExecChain {
|
||||||
|
|
||||||
private void setResponseStatus(final HttpContext context, final CacheResponseStatus value) {
|
private void setResponseStatus(final HttpContext context, final CacheResponseStatus value) {
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.setAttribute(CACHE_RESPONSE_STATUS, value);
|
context.setAttribute(HttpCacheContext.CACHE_RESPONSE_STATUS, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ import org.apache.http.StatusLine;
|
||||||
import org.apache.http.client.ClientProtocolException;
|
import org.apache.http.client.ClientProtocolException;
|
||||||
import org.apache.http.client.ResponseHandler;
|
import org.apache.http.client.ResponseHandler;
|
||||||
import org.apache.http.client.cache.CacheResponseStatus;
|
import org.apache.http.client.cache.CacheResponseStatus;
|
||||||
|
import org.apache.http.client.cache.HttpCacheContext;
|
||||||
import org.apache.http.client.cache.HttpCacheEntry;
|
import org.apache.http.client.cache.HttpCacheEntry;
|
||||||
import org.apache.http.client.cache.HttpCacheStorage;
|
import org.apache.http.client.cache.HttpCacheStorage;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
@ -73,7 +74,6 @@ import org.apache.http.impl.cookie.DateUtils;
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
import org.apache.http.message.BasicHttpRequest;
|
import org.apache.http.message.BasicHttpRequest;
|
||||||
import org.apache.http.message.BasicHttpResponse;
|
import org.apache.http.message.BasicHttpResponse;
|
||||||
import org.apache.http.protocol.ExecutionContext;
|
|
||||||
import org.easymock.Capture;
|
import org.easymock.Capture;
|
||||||
import org.easymock.IExpectationSetters;
|
import org.easymock.IExpectationSetters;
|
||||||
import org.easymock.classextension.EasyMock;
|
import org.easymock.classextension.EasyMock;
|
||||||
|
@ -119,7 +119,7 @@ public class TestCachingExec {
|
||||||
private HttpRoute route;
|
private HttpRoute route;
|
||||||
private HttpHost host;
|
private HttpHost host;
|
||||||
private HttpRequestWrapper request;
|
private HttpRequestWrapper request;
|
||||||
private HttpClientContext context;
|
private HttpCacheContext context;
|
||||||
private HttpCacheEntry entry;
|
private HttpCacheEntry entry;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -151,7 +151,7 @@ public class TestCachingExec {
|
||||||
route = new HttpRoute(host);
|
route = new HttpRoute(host);
|
||||||
request = HttpRequestWrapper.wrap(
|
request = HttpRequestWrapper.wrap(
|
||||||
new BasicHttpRequest("GET", "/stuff", HttpVersion.HTTP_1_1));
|
new BasicHttpRequest("GET", "/stuff", HttpVersion.HTTP_1_1));
|
||||||
context = HttpClientContext.create();
|
context = HttpCacheContext.create();
|
||||||
entry = HttpTestUtils.makeCacheEntry();
|
entry = HttpTestUtils.makeCacheEntry();
|
||||||
impl = new CachingExec(
|
impl = new CachingExec(
|
||||||
mockBackend,
|
mockBackend,
|
||||||
|
@ -569,7 +569,7 @@ public class TestCachingExec {
|
||||||
|
|
||||||
impl.execute(route, req, context);
|
impl.execute(route, req, context);
|
||||||
Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
|
Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
|
||||||
context.getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS));
|
context.getCacheResponseStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -582,7 +582,7 @@ public class TestCachingExec {
|
||||||
|
|
||||||
impl.execute(route, req, context);
|
impl.execute(route, req, context);
|
||||||
Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
|
Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
|
||||||
context.getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS));
|
context.getCacheResponseStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -622,7 +622,7 @@ public class TestCachingExec {
|
||||||
impl.execute(route, req, context);
|
impl.execute(route, req, context);
|
||||||
verifyMocks();
|
verifyMocks();
|
||||||
Assert.assertEquals(CacheResponseStatus.CACHE_MISS,
|
Assert.assertEquals(CacheResponseStatus.CACHE_MISS,
|
||||||
context.getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS));
|
context.getCacheResponseStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -681,7 +681,7 @@ public class TestCachingExec {
|
||||||
impl.execute(route, req2, context);
|
impl.execute(route, req2, context);
|
||||||
verifyMocks();
|
verifyMocks();
|
||||||
Assert.assertEquals(CacheResponseStatus.CACHE_HIT,
|
Assert.assertEquals(CacheResponseStatus.CACHE_HIT,
|
||||||
context.getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS));
|
context.getCacheResponseStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -947,7 +947,7 @@ public class TestCachingExec {
|
||||||
impl.execute(route, req2, context);
|
impl.execute(route, req2, context);
|
||||||
verifyMocks();
|
verifyMocks();
|
||||||
Assert.assertEquals(CacheResponseStatus.VALIDATED,
|
Assert.assertEquals(CacheResponseStatus.VALIDATED,
|
||||||
context.getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS));
|
context.getCacheResponseStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1010,7 +1010,7 @@ public class TestCachingExec {
|
||||||
impl.execute(route, req2, context);
|
impl.execute(route, req2, context);
|
||||||
verifyMocks();
|
verifyMocks();
|
||||||
Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
|
Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
|
||||||
context.getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS));
|
context.getCacheResponseStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1038,7 +1038,7 @@ public class TestCachingExec {
|
||||||
impl.execute(route, req2, context);
|
impl.execute(route, req2, context);
|
||||||
verifyMocks();
|
verifyMocks();
|
||||||
Assert.assertEquals(CacheResponseStatus.CACHE_HIT,
|
Assert.assertEquals(CacheResponseStatus.CACHE_HIT,
|
||||||
context.getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS));
|
context.getCacheResponseStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1446,20 +1446,7 @@ public class TestCachingExec {
|
||||||
HttpClientContext ctx = HttpClientContext.create();
|
HttpClientContext ctx = HttpClientContext.create();
|
||||||
impl.execute(route, request);
|
impl.execute(route, request);
|
||||||
impl.execute(route, request, ctx);
|
impl.execute(route, request, ctx);
|
||||||
assertNull(ctx.getAttribute(ExecutionContext.HTTP_CONNECTION));
|
assertNull(ctx.getConnection());
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDoesNotSetProxyHostInContextOnCacheHit() throws Exception {
|
|
||||||
DummyBackend backend = new DummyBackend();
|
|
||||||
HttpResponse response = HttpTestUtils.make200Response();
|
|
||||||
response.setHeader("Cache-Control", "max-age=3600");
|
|
||||||
backend.setResponse(response);
|
|
||||||
impl = new CachingExec(backend);
|
|
||||||
HttpClientContext ctx = HttpClientContext.create();
|
|
||||||
impl.execute(route, request);
|
|
||||||
impl.execute(route, request, ctx);
|
|
||||||
assertNull(ctx.getAttribute(ExecutionContext.HTTP_PROXY_HOST));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1472,7 +1459,20 @@ public class TestCachingExec {
|
||||||
HttpClientContext ctx = HttpClientContext.create();
|
HttpClientContext ctx = HttpClientContext.create();
|
||||||
impl.execute(route, request);
|
impl.execute(route, request);
|
||||||
impl.execute(route, request, ctx);
|
impl.execute(route, request, ctx);
|
||||||
assertSame(host, ctx.getAttribute(ExecutionContext.HTTP_TARGET_HOST));
|
assertSame(host, ctx.getTargetHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetsRouteInContextOnCacheHit() throws Exception {
|
||||||
|
DummyBackend backend = new DummyBackend();
|
||||||
|
HttpResponse response = HttpTestUtils.make200Response();
|
||||||
|
response.setHeader("Cache-Control", "max-age=3600");
|
||||||
|
backend.setResponse(response);
|
||||||
|
impl = new CachingExec(backend);
|
||||||
|
HttpClientContext ctx = HttpClientContext.create();
|
||||||
|
impl.execute(route, request);
|
||||||
|
impl.execute(route, request, ctx);
|
||||||
|
assertSame(route, ctx.getHttpRoute());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1485,7 +1485,7 @@ public class TestCachingExec {
|
||||||
HttpClientContext ctx = HttpClientContext.create();
|
HttpClientContext ctx = HttpClientContext.create();
|
||||||
impl.execute(route, request);
|
impl.execute(route, request);
|
||||||
impl.execute(route, request, ctx);
|
impl.execute(route, request, ctx);
|
||||||
assertSame(request, ctx.getAttribute(ExecutionContext.HTTP_REQUEST));
|
assertSame(request, ctx.getRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1498,7 +1498,7 @@ public class TestCachingExec {
|
||||||
HttpClientContext ctx = HttpClientContext.create();
|
HttpClientContext ctx = HttpClientContext.create();
|
||||||
impl.execute(route, request);
|
impl.execute(route, request);
|
||||||
HttpResponse result = impl.execute(route, request, ctx);
|
HttpResponse result = impl.execute(route, request, ctx);
|
||||||
assertSame(result, ctx.getAttribute(ExecutionContext.HTTP_RESPONSE));
|
assertSame(result, ctx.getResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1511,7 +1511,7 @@ public class TestCachingExec {
|
||||||
HttpClientContext ctx = HttpClientContext.create();
|
HttpClientContext ctx = HttpClientContext.create();
|
||||||
impl.execute(route, request);
|
impl.execute(route, request);
|
||||||
impl.execute(route, request, ctx);
|
impl.execute(route, request, ctx);
|
||||||
assertEquals(Boolean.TRUE, ctx.getAttribute(ExecutionContext.HTTP_REQ_SENT));
|
assertTrue(ctx.isRequestSent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue