You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2016/12/27 19:48:10 UTC

svn commit: r1776187 [6/21] - in /httpcomponents/httpclient/trunk: ./ httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ httpclient5-cache/src/test/java/org/apache/hc...

Modified: httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java?rev=1776187&r1=1776186&r2=1776187&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java Tue Dec 27 19:48:07 2016
@@ -54,28 +54,29 @@ import org.apache.hc.client5.http.cache.
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.cache.HttpCacheStorage;
 import org.apache.hc.client5.http.impl.sync.ClientExecChain;
-import org.apache.hc.client5.http.methods.CloseableHttpResponse;
 import org.apache.hc.client5.http.methods.HttpExecutionAware;
 import org.apache.hc.client5.http.methods.HttpGet;
 import org.apache.hc.client5.http.methods.HttpOptions;
-import org.apache.hc.client5.http.methods.HttpRequestWrapper;
 import org.apache.hc.client5.http.methods.HttpUriRequest;
+import org.apache.hc.client5.http.methods.RoutedHttpRequest;
 import org.apache.hc.client5.http.protocol.ClientProtocolException;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.sync.ResponseHandler;
 import org.apache.hc.client5.http.utils.DateUtils;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.StatusLine;
-import org.apache.hc.core5.http.entity.EntityUtils;
-import org.apache.hc.core5.http.entity.InputStreamEntity;
+import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.InputStreamEntity;
+import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
 import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.http.message.BasicHttpRequest;
-import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.apache.hc.core5.net.URIAuthority;
 import org.easymock.Capture;
 import org.easymock.EasyMock;
 import org.easymock.IExpectationSetters;
@@ -101,10 +102,9 @@ public abstract class TestCachingExecCha
     protected CachedHttpResponseGenerator mockResponseGenerator;
     private ResponseHandler<Object> mockHandler;
     private HttpUriRequest mockUriRequest;
-    private CloseableHttpResponse mockCachedResponse;
+    private ClassicHttpResponse mockCachedResponse;
     protected ConditionalRequestBuilder mockConditionalRequestBuilder;
     private HttpRequest mockConditionalRequest;
-    private StatusLine mockStatusLine;
     protected ResponseProtocolCompliance mockResponseProtocolCompliance;
     protected RequestProtocolCompliance mockRequestProtocolCompliance;
     protected CacheConfig config;
@@ -112,7 +112,7 @@ public abstract class TestCachingExecCha
 
     protected HttpRoute route;
     protected HttpHost host;
-    protected HttpRequestWrapper request;
+    protected RoutedHttpRequest request;
     protected HttpCacheContext context;
     protected HttpCacheEntry entry;
 
@@ -129,10 +129,9 @@ public abstract class TestCachingExecCha
         mockUriRequest = createNiceMock(HttpUriRequest.class);
         mockCacheEntry = createNiceMock(HttpCacheEntry.class);
         mockResponseGenerator = createNiceMock(CachedHttpResponseGenerator.class);
-        mockCachedResponse = createNiceMock(CloseableHttpResponse.class);
+        mockCachedResponse = createNiceMock(ClassicHttpResponse.class);
         mockConditionalRequestBuilder = createNiceMock(ConditionalRequestBuilder.class);
         mockConditionalRequest = createNiceMock(HttpRequest.class);
-        mockStatusLine = createNiceMock(StatusLine.class);
         mockResponseProtocolCompliance = createNiceMock(ResponseProtocolCompliance.class);
         mockRequestProtocolCompliance = createNiceMock(RequestProtocolCompliance.class);
         mockStorage = createNiceMock(HttpCacheStorage.class);
@@ -141,10 +140,8 @@ public abstract class TestCachingExecCha
 
         host = new HttpHost("foo.example.com", 80);
         route = new HttpRoute(host);
-        request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/stuff",
-            HttpVersion.HTTP_1_1), host);
+        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("GET", "/stuff"), route);
         context = HttpCacheContext.create();
-        context.setTargetHost(host);
         entry = HttpTestUtils.makeCacheEntry();
         impl = createCachingExecChain(mockBackend, mockCache, mockValidityPolicy,
             mockResponsePolicy, mockResponseGenerator, mockRequestPolicy, mockSuitabilityChecker,
@@ -164,7 +161,7 @@ public abstract class TestCachingExecCha
     public abstract ClientExecChain createCachingExecChain(ClientExecChain backend,
         HttpCache cache, CacheConfig config);
 
-    public static HttpRequestWrapper eqRequest(final HttpRequestWrapper in) {
+    public static RoutedHttpRequest eqRequest(final RoutedHttpRequest in) {
         EasyMock.reportMatcher(new RequestEquivalent(in));
         return null;
     }
@@ -188,7 +185,6 @@ public abstract class TestCachingExecCha
         replay(mockCachedResponse);
         replay(mockConditionalRequestBuilder);
         replay(mockConditionalRequest);
-        replay(mockStatusLine);
         replay(mockResponseProtocolCompliance);
         replay(mockRequestProtocolCompliance);
         replay(mockStorage);
@@ -208,7 +204,6 @@ public abstract class TestCachingExecCha
         verify(mockCachedResponse);
         verify(mockConditionalRequestBuilder);
         verify(mockConditionalRequest);
-        verify(mockStatusLine);
         verify(mockResponseProtocolCompliance);
         verify(mockRequestProtocolCompliance);
         verify(mockStorage);
@@ -218,17 +213,17 @@ public abstract class TestCachingExecCha
     public void testCacheableResponsesGoIntoCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
-        final HttpResponse resp1 = HttpTestUtils.make200Response();
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
+        final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("Cache-Control", "max-age=3600");
 
         backendExpectsAnyRequestAndReturn(resp1);
 
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        impl.execute(req2, context, null);
         verifyMocks();
     }
 
@@ -238,29 +233,29 @@ public abstract class TestCachingExecCha
         final Date now = new Date();
         final Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
-        final HttpResponse resp1 = HttpTestUtils.make200Response();
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
+        final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("Date", DateUtils.formatDate(now));
         resp1.setHeader("Cache-Control", "max-age=3600");
         resp1.setHeader("Etag", "\"new-etag\"");
 
         backendExpectsAnyRequestAndReturn(resp1);
 
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
         req2.setHeader("Cache-Control", "no-cache");
-        final HttpResponse resp2 = HttpTestUtils.make200Response();
+        final ClassicHttpResponse resp2 = HttpTestUtils.make200Response();
         resp2.setHeader("ETag", "\"old-etag\"");
         resp2.setHeader("Date", DateUtils.formatDate(fiveSecondsAgo));
         resp2.setHeader("Cache-Control", "max-age=3600");
 
         backendExpectsAnyRequestAndReturn(resp2);
 
-        final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
+        final RoutedHttpRequest req3 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        impl.execute(route, req2, context, null);
-        final HttpResponse result = impl.execute(route, req3, context, null);
+        impl.execute(req1, context, null);
+        impl.execute(req2, context, null);
+        final ClassicHttpResponse result = impl.execute(req3, context, null);
         verifyMocks();
 
         assertEquals("\"new-etag\"", result.getFirstHeader("ETag").getValue());
@@ -272,29 +267,29 @@ public abstract class TestCachingExecCha
         final Date now = new Date();
         final Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
-        final HttpResponse resp1 = HttpTestUtils.make200Response();
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
+        final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("Date", DateUtils.formatDate(fiveSecondsAgo));
         resp1.setHeader("Cache-Control", "max-age=3600");
         resp1.setHeader("Etag", "\"old-etag\"");
 
         backendExpectsAnyRequestAndReturn(resp1);
 
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
         req2.setHeader("Cache-Control", "max-age=0");
-        final HttpResponse resp2 = HttpTestUtils.make200Response();
+        final ClassicHttpResponse resp2 = HttpTestUtils.make200Response();
         resp2.setHeader("ETag", "\"new-etag\"");
         resp2.setHeader("Date", DateUtils.formatDate(now));
         resp2.setHeader("Cache-Control", "max-age=3600");
 
         backendExpectsAnyRequestAndReturn(resp2);
 
-        final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
+        final RoutedHttpRequest req3 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        impl.execute(route, req2, context, null);
-        final HttpResponse result = impl.execute(route, req3, context, null);
+        impl.execute(req1, context, null);
+        impl.execute(req2, context, null);
+        final ClassicHttpResponse result = impl.execute(req3, context, null);
         verifyMocks();
 
         assertEquals("\"new-etag\"", result.getFirstHeader("ETag").getValue());
@@ -320,7 +315,7 @@ public abstract class TestCachingExecCha
         entryHasStaleness(0L);
 
         replayMocks();
-        final HttpResponse result = impl.execute(route, request, context, null);
+        final ClassicHttpResponse result = impl.execute(request, context, null);
         verifyMocks();
 
         Assert.assertSame(mockCachedResponse, result);
@@ -332,8 +327,8 @@ public abstract class TestCachingExecCha
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(new HeapResourceFactory(),
             mockStorage, configDefault), configDefault);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest(), host);
-        final HttpResponse resp1 = HttpTestUtils.make200Response();
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(HttpTestUtils.makeDefaultRequest(), route);
+        final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("Cache-Control", "no-cache");
 
         expect(mockStorage.getEntry(isA(String.class))).andReturn(null).anyTimes();
@@ -342,7 +337,7 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
 
         replayMocks();
-        final HttpResponse result = impl.execute(route, req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req1, context, null);
         verifyMocks();
 
         assertTrue(HttpTestUtils.semanticallyTransparent(resp1, result));
@@ -360,7 +355,7 @@ public abstract class TestCachingExecCha
         entryHasStaleness(0L);
 
         replayMocks();
-        impl.execute(route, request, context, null);
+        impl.execute(request, context, null);
         verifyMocks();
     }
 
@@ -370,13 +365,13 @@ public abstract class TestCachingExecCha
         final ClientProtocolException expected = new ClientProtocolException("ouch");
 
         requestIsFatallyNonCompliant(null);
-        mockRequestProtocolCompliance.makeRequestCompliant((HttpRequestWrapper) anyObject());
+        mockRequestProtocolCompliance.makeRequestCompliant((RoutedHttpRequest) anyObject());
         expectLastCall().andThrow(expected);
 
         boolean gotException = false;
         replayMocks();
         try {
-            impl.execute(route, request, context, null);
+            impl.execute(request, context, null);
         } catch (final ClientProtocolException ex) {
             Assert.assertSame(expected, ex);
             gotException = true;
@@ -388,44 +383,41 @@ public abstract class TestCachingExecCha
     @Test
     public void testSetsModuleGeneratedResponseContextForCacheOptionsResponse() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("OPTIONS", "*",
-            HttpVersion.HTTP_1_1), host);
+        final RoutedHttpRequest req = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("OPTIONS", "*"), route);
         req.setHeader("Max-Forwards", "0");
 
-        impl.execute(route, req, context, null);
+        impl.execute(req, context, null);
         Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
             context.getCacheResponseStatus());
     }
 
     @Test
-    public void testSetsModuleGeneratedResponseContextForFatallyNoncompliantRequest()
-        throws Exception {
+    public void testSetsModuleGeneratedResponseContextForFatallyNoncompliantRequest() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req.setHeader("Range", "bytes=0-50");
         req.setHeader("If-Range", "W/\"weak-etag\"");
 
-        impl.execute(route, req, context, null);
+        impl.execute(req, context, null);
         Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
             context.getCacheResponseStatus());
     }
 
     @Test
-    public void testRecordsClientProtocolInViaHeaderIfRequestNotServableFromCache()
-        throws Exception {
+    public void testRecordsClientProtocolInViaHeaderIfRequestNotServableFromCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/",
-            HttpVersion.HTTP_1_0), host);
+        final ClassicHttpRequest originalRequest = new BasicClassicHttpRequest("GET", "/");
+        originalRequest.setVersion(HttpVersion.HTTP_1_0);
+        final RoutedHttpRequest req = RoutedHttpRequest.adapt(originalRequest, route);
         req.setHeader("Cache-Control", "no-cache");
-        final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NO_CONTENT, "No Content");
-        final Capture<HttpRequestWrapper> cap = new Capture<>();
+        final ClassicHttpResponse resp = new BasicClassicHttpResponse(HttpStatus.SC_NO_CONTENT, "No Content");
+        final Capture<RoutedHttpRequest> cap = new Capture<>();
 
         backendCaptureRequestAndReturn(cap, resp);
 
         replayMocks();
-        impl.execute(route, req, context, null);
+        impl.execute(req, context, null);
         verifyMocks();
 
         final HttpRequest captured = cap.getValue();
@@ -437,16 +429,15 @@ public abstract class TestCachingExecCha
     @Test
     public void testSetsCacheMissContextIfRequestNotServableFromCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req.setHeader("Cache-Control", "no-cache");
-        final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NO_CONTENT, "No Content");
+        final ClassicHttpResponse resp = new BasicClassicHttpResponse(HttpStatus.SC_NO_CONTENT, "No Content");
 
         backendExpectsAnyRequestAndReturn(resp);
 
         replayMocks();
-        impl.execute(route, req, context, null);
+        impl.execute(req, context, null);
         verifyMocks();
         Assert.assertEquals(CacheResponseStatus.CACHE_MISS, context.getCacheResponseStatus());
     }
@@ -454,16 +445,15 @@ public abstract class TestCachingExecCha
     @Test
     public void testSetsViaHeaderOnResponseIfRequestNotServableFromCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req.setHeader("Cache-Control", "no-cache");
-        final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NO_CONTENT, "No Content");
+        final ClassicHttpResponse resp = new BasicClassicHttpResponse(HttpStatus.SC_NO_CONTENT, "No Content");
 
         backendExpectsAnyRequestAndReturn(resp);
 
         replayMocks();
-        final HttpResponse result = impl.execute(route, req, context, null);
+        final ClassicHttpResponse result = impl.execute(req, context, null);
         verifyMocks();
         Assert.assertNotNull(result.getFirstHeader("Via"));
     }
@@ -471,9 +461,9 @@ public abstract class TestCachingExecCha
     @Test
     public void testSetsViaHeaderOnResponseForCacheMiss() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -484,7 +474,7 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
 
         replayMocks();
-        final HttpResponse result = impl.execute(route, req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req1, context, null);
         verifyMocks();
         Assert.assertNotNull(result.getFirstHeader("Via"));
     }
@@ -492,11 +482,11 @@ public abstract class TestCachingExecCha
     @Test
     public void testSetsCacheHitContextIfRequestServedFromCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -507,8 +497,8 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        impl.execute(req2, context, null);
         verifyMocks();
         Assert.assertEquals(CacheResponseStatus.CACHE_HIT, context.getCacheResponseStatus());
     }
@@ -516,11 +506,11 @@ public abstract class TestCachingExecCha
     @Test
     public void testSetsViaHeaderOnResponseIfRequestServedFromCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -531,8 +521,8 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
         Assert.assertNotNull(result.getFirstHeader("Via"));
     }
@@ -542,12 +532,12 @@ public abstract class TestCachingExecCha
         final Date now = new Date();
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req2.addHeader("If-Modified-Since", DateUtils.formatDate(now));
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -559,10 +549,10 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getCode());
 
     }
 
@@ -572,34 +562,32 @@ public abstract class TestCachingExecCha
         final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L);
         final Date inTenMinutes = new Date(now.getTime() + 600 * 1000L);
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req1.addHeader("If-Modified-Since", DateUtils.formatDate(oneHourAgo));
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req2.addHeader("If-Modified-Since", DateUtils.formatDate(oneHourAgo));
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not modified");
+        final ClassicHttpResponse resp1 = HttpTestUtils.make304Response();
         resp1.setHeader("Date", DateUtils.formatDate(now));
         resp1.setHeader("Cache-control", "max-age=600");
         resp1.setHeader("Expires", DateUtils.formatDate(inTenMinutes));
 
         expect(
-            mockBackend.execute(eq(route), isA(HttpRequestWrapper.class),
-                isA(HttpClientContext.class), (HttpExecutionAware) isNull())).andReturn(
-            Proxies.enhanceResponse(resp1)).once();
+            mockBackend.execute(isA(RoutedHttpRequest.class),
+                isA(HttpClientContext.class), (HttpExecutionAware) isNull())).andReturn(resp1).once();
 
         expect(
-            mockBackend.execute(eq(route), isA(HttpRequestWrapper.class),
+            mockBackend.execute(isA(RoutedHttpRequest.class),
                 isA(HttpClientContext.class), (HttpExecutionAware) isNull())).andThrow(
             new AssertionFailedError("Should have reused cached 304 response")).anyTimes();
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getCode());
         Assert.assertFalse(result.containsHeader("Last-Modified"));
     }
 
@@ -608,12 +596,12 @@ public abstract class TestCachingExecCha
         final Date now = new Date();
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -625,16 +613,16 @@ public abstract class TestCachingExecCha
         // The variant has been modified since this date
         req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo));
 
-        final HttpResponse resp2 = HttpTestUtils.make200Response();
+        final ClassicHttpResponse resp2 = HttpTestUtils.make200Response();
 
         backendExpectsAnyRequestAndReturn(resp1);
         backendExpectsAnyRequestAndReturn(resp2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result.getCode());
 
     }
 
@@ -643,12 +631,12 @@ public abstract class TestCachingExecCha
         final Date now = new Date();
         final Date tenSecondsAfter = new Date(now.getTime() + 10 * 1000L);
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -663,22 +651,22 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1).times(2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result.getCode());
 
     }
 
     @Test
     public void testReturns304ForIfNoneMatchHeaderIfRequestServedFromCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req2.addHeader("If-None-Match", "*");
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -689,22 +677,22 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getCode());
 
     }
 
     @Test
     public void testReturns200ForIfNoneMatchHeaderFails() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -714,31 +702,30 @@ public abstract class TestCachingExecCha
 
         req2.addHeader("If-None-Match", "\"abc\"");
 
-        final HttpResponse resp2 = HttpTestUtils.make200Response();
+        final ClassicHttpResponse resp2 = HttpTestUtils.make200Response();
 
         backendExpectsAnyRequestAndReturn(resp1);
         backendExpectsAnyRequestAndReturn(resp2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(200, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(200, result.getCode());
 
     }
 
     @Test
-    public void testReturns304ForIfNoneMatchHeaderAndIfModifiedSinceIfRequestServedFromCache()
-        throws Exception {
+    public void testReturns304ForIfNoneMatchHeaderAndIfModifiedSinceIfRequestServedFromCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final Date now = new Date();
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -753,10 +740,10 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getCode());
 
     }
 
@@ -765,13 +752,13 @@ public abstract class TestCachingExecCha
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final Date now = new Date();
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req2.addHeader("If-None-Match", "\"abc\"");
         req2.addHeader("If-Modified-Since", DateUtils.formatDate(now));
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -784,33 +771,31 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(200, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(200, result.getCode());
 
     }
 
     @Test
-    public void testReturns200ForOptionsFollowedByGetIfAuthorizationHeaderAndSharedCache()
-        throws Exception {
+    public void testReturns200ForOptionsFollowedByGetIfAuthorizationHeaderAndSharedCache() throws Exception {
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.custom()
             .setSharedCache(true).build());
         final Date now = new Date();
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpOptions(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpOptions(
+            "http://foo.example.com/"), route);
         req1.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req2.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NO_CONTENT, "No Content");
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_NO_CONTENT, "No Content");
         resp1.setHeader("Content-Length", "0");
         resp1.setHeader("ETag", "\"options-etag\"");
         resp1.setHeader("Date", DateUtils.formatDate(now));
         resp1.setHeader("Cache-Control", "public, max-age=3600");
         resp1.setHeader("Last-Modified", DateUtils.formatDate(now));
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp2 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -823,10 +808,10 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
-        Assert.assertEquals(200, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(200, result.getCode());
     }
 
     @Test
@@ -835,12 +820,12 @@ public abstract class TestCachingExecCha
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -848,7 +833,7 @@ public abstract class TestCachingExecCha
         resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
         resp1.setHeader("Cache-Control", "public, max-age=5");
 
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp2 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp2.setEntity(HttpTestUtils.makeBody(128));
         resp2.setHeader("Content-Length", "128");
@@ -860,8 +845,8 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        impl.execute(req2, context, null);
         verifyMocks();
         Assert.assertEquals(CacheResponseStatus.VALIDATED, context.getCacheResponseStatus());
     }
@@ -872,12 +857,12 @@ public abstract class TestCachingExecCha
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -885,7 +870,7 @@ public abstract class TestCachingExecCha
         resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
         resp1.setHeader("Cache-Control", "public, max-age=5");
 
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp2 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp2.setEntity(HttpTestUtils.makeBody(128));
         resp2.setHeader("Content-Length", "128");
@@ -897,8 +882,8 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
         Assert.assertNotNull(result.getFirstHeader("Via"));
     }
@@ -909,12 +894,12 @@ public abstract class TestCachingExecCha
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -926,8 +911,8 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndThrows(new IOException());
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        impl.execute(req2, context, null);
         verifyMocks();
         Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
             context.getCacheResponseStatus());
@@ -939,12 +924,12 @@ public abstract class TestCachingExecCha
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -956,8 +941,8 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndThrows(new IOException());
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        impl.execute(req2, context, null);
         verifyMocks();
         Assert.assertEquals(CacheResponseStatus.CACHE_HIT, context.getCacheResponseStatus());
     }
@@ -968,12 +953,12 @@ public abstract class TestCachingExecCha
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -985,8 +970,8 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndThrows(new IOException());
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
         Assert.assertNotNull(result.getFirstHeader("Via"));
     }
@@ -998,12 +983,12 @@ public abstract class TestCachingExecCha
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -1012,8 +997,7 @@ public abstract class TestCachingExecCha
         resp1.setHeader("Cache-Control", "public, max-age=5");
 
         req2.addHeader("If-None-Match", "\"etag\"");
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not Modified");
+        final ClassicHttpResponse resp2 = HttpTestUtils.make304Response();
         resp2.setHeader("ETag", "\"etag\"");
         resp2.setHeader("Date", DateUtils.formatDate(now));
         resp2.setHeader("Cache-Control", "public, max-age=5");
@@ -1021,11 +1005,11 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
         backendExpectsAnyRequestAndReturn(resp2);
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
 
-        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getCode());
     }
 
     @Test
@@ -1035,12 +1019,12 @@ public abstract class TestCachingExecCha
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -1049,7 +1033,7 @@ public abstract class TestCachingExecCha
         resp1.setHeader("Cache-Control", "public, max-age=5");
 
         req2.addHeader("If-None-Match", "\"etag\"");
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp2 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp2.setEntity(HttpTestUtils.makeBody(128));
         resp2.setHeader("Content-Length", "128");
@@ -1061,11 +1045,11 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
 
-        Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result.getCode());
     }
 
     @Test
@@ -1075,12 +1059,12 @@ public abstract class TestCachingExecCha
         final Date now = new Date();
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -1090,8 +1074,7 @@ public abstract class TestCachingExecCha
         resp1.setHeader("Cache-Control", "public, max-age=5");
 
         req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo));
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not Modified");
+        final ClassicHttpResponse resp2 = HttpTestUtils.make304Response();
         resp2.setHeader("ETag", "\"etag\"");
         resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
         resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
@@ -1101,11 +1084,11 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
 
-        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getCode());
     }
 
     @Test
@@ -1114,12 +1097,12 @@ public abstract class TestCachingExecCha
         final Date now = new Date();
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -1129,7 +1112,7 @@ public abstract class TestCachingExecCha
         resp1.setHeader("Cache-Control", "public, max-age=5");
 
         req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo));
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp2 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp2.setEntity(HttpTestUtils.makeBody(128));
         resp2.setHeader("Content-Length", "128");
@@ -1142,11 +1125,11 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp2);
 
         replayMocks();
-        impl.execute(route, req1, context, null);
-        final HttpResponse result = impl.execute(route, req2, context, null);
+        impl.execute(req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req2, context, null);
         verifyMocks();
 
-        Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result.getCode());
     }
 
     @Test
@@ -1154,11 +1137,11 @@ public abstract class TestCachingExecCha
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final Date now = new Date();
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req1.addHeader("Accept-Encoding", "gzip");
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -1167,16 +1150,16 @@ public abstract class TestCachingExecCha
         resp1.setHeader("Vary", "Accept-Encoding");
         resp1.setHeader("Cache-Control", "public, max-age=3600");
 
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req2.addHeader("Accept-Encoding", "deflate");
 
-        final HttpRequestWrapper req2Server = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req2Server = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req2Server.addHeader("Accept-Encoding", "deflate");
         req2Server.addHeader("If-None-Match", "\"gzip_etag\"");
 
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp2 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp2.setEntity(HttpTestUtils.makeBody(128));
         resp2.setHeader("Content-Length", "128");
@@ -1185,16 +1168,16 @@ public abstract class TestCachingExecCha
         resp2.setHeader("Vary", "Accept-Encoding");
         resp2.setHeader("Cache-Control", "public, max-age=3600");
 
-        final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req3 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req3.addHeader("Accept-Encoding", "gzip,deflate");
 
-        final HttpRequestWrapper req3Server = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req3Server = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req3Server.addHeader("Accept-Encoding", "gzip,deflate");
         req3Server.addHeader("If-None-Match", "\"gzip_etag\",\"deflate_etag\"");
 
-        final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp3 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp3.setEntity(HttpTestUtils.makeBody(128));
         resp3.setHeader("Content-Length", "128");
@@ -1208,16 +1191,16 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp3);
 
         replayMocks();
-        final HttpResponse result1 = impl.execute(route, req1, context, null);
+        final ClassicHttpResponse result1 = impl.execute(req1, context, null);
 
-        final HttpResponse result2 = impl.execute(route, req2, context, null);
+        final ClassicHttpResponse result2 = impl.execute(req2, context, null);
 
-        final HttpResponse result3 = impl.execute(route, req3, context, null);
+        final ClassicHttpResponse result3 = impl.execute(req3, context, null);
 
         verifyMocks();
-        Assert.assertEquals(HttpStatus.SC_OK, result1.getStatusLine().getStatusCode());
-        Assert.assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode());
-        Assert.assertEquals(HttpStatus.SC_OK, result3.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result1.getCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result2.getCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result3.getCode());
     }
 
     @Test
@@ -1225,11 +1208,11 @@ public abstract class TestCachingExecCha
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final Date now = new Date();
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req1.addHeader("Accept-Encoding", "gzip");
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(HttpTestUtils.makeBody(128));
         resp1.setHeader("Content-Length", "128");
@@ -1238,16 +1221,16 @@ public abstract class TestCachingExecCha
         resp1.setHeader("Vary", "Accept-Encoding");
         resp1.setHeader("Cache-Control", "public, max-age=3600");
 
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req2.addHeader("Accept-Encoding", "deflate");
 
-        final HttpRequestWrapper req2Server = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req2Server = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req2Server.addHeader("Accept-Encoding", "deflate");
         req2Server.addHeader("If-None-Match", "\"gzip_etag\"");
 
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp2 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp2.setEntity(HttpTestUtils.makeBody(128));
         resp2.setHeader("Content-Length", "128");
@@ -1256,18 +1239,17 @@ public abstract class TestCachingExecCha
         resp2.setHeader("Vary", "Accept-Encoding");
         resp2.setHeader("Cache-Control", "public, max-age=3600");
 
-        final HttpRequestWrapper req4 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req4 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req4.addHeader("Accept-Encoding", "gzip,identity");
         req4.addHeader("If-None-Match", "\"gzip_etag\"");
 
-        final HttpRequestWrapper req4Server = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req4Server = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
         req4Server.addHeader("Accept-Encoding", "gzip,identity");
         req4Server.addHeader("If-None-Match", "\"gzip_etag\"");
 
-        final HttpResponse resp4 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not Modified");
+        final ClassicHttpResponse resp4 = HttpTestUtils.make304Response();
         resp4.setHeader("Etag", "\"gzip_etag\"");
         resp4.setHeader("Date", DateUtils.formatDate(now));
         resp4.setHeader("Vary", "Accept-Encoding");
@@ -1278,15 +1260,15 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp4);
 
         replayMocks();
-        final HttpResponse result1 = impl.execute(route, req1, context, null);
+        final ClassicHttpResponse result1 = impl.execute(req1, context, null);
 
-        final HttpResponse result2 = impl.execute(route, req2, context, null);
+        final ClassicHttpResponse result2 = impl.execute(req2, context, null);
 
-        final HttpResponse result4 = impl.execute(route, req4, context, null);
+        final ClassicHttpResponse result4 = impl.execute(req4, context, null);
         verifyMocks();
-        Assert.assertEquals(HttpStatus.SC_OK, result1.getStatusLine().getStatusCode());
-        Assert.assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode());
-        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result4.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result1.getCode());
+        Assert.assertEquals(HttpStatus.SC_OK, result2.getCode());
+        Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result4.getCode());
 
     }
 
@@ -1295,10 +1277,10 @@ public abstract class TestCachingExecCha
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final Date now = new Date();
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp1 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "OK");
         resp1.setEntity(new InputStreamEntity(new InputStream() {
             private boolean closed = false;
@@ -1322,7 +1304,7 @@ public abstract class TestCachingExecCha
 
         replayMocks();
         try {
-            final HttpResponse result1 = impl.execute(route, req1, context, null);
+            final ClassicHttpResponse result1 = impl.execute(req1, context, null);
             EntityUtils.toString(result1.getEntity());
             Assert.fail("We should have had a SocketTimeoutException");
         } catch (final SocketTimeoutException e) {
@@ -1340,7 +1322,7 @@ public abstract class TestCachingExecCha
     public void testTreatsCacheIOExceptionsAsCacheMiss() throws Exception {
 
         impl = createCachingExecChain(mockBackend, mockCache, CacheConfig.DEFAULT);
-        final CloseableHttpResponse resp = Proxies.enhanceResponse(HttpTestUtils.make200Response());
+        final ClassicHttpResponse resp = HttpTestUtils.make200Response();
 
         mockCache.flushInvalidatedCacheEntriesFor(host, request);
         expectLastCall().andThrow(new IOException()).anyTimes();
@@ -1353,14 +1335,14 @@ public abstract class TestCachingExecCha
             .andThrow(new IOException()).anyTimes();
         expect(
             mockCache.cacheAndReturnResponse(eq(host), isA(HttpRequest.class),
-                isA(CloseableHttpResponse.class), isA(Date.class), isA(Date.class)))
+                isA(ClassicHttpResponse.class), isA(Date.class), isA(Date.class)))
             .andReturn(resp).anyTimes();
         expect(
-            mockBackend.execute(eq(route), isA(HttpRequestWrapper.class),
+            mockBackend.execute(isA(RoutedHttpRequest.class),
                 isA(HttpClientContext.class), (HttpExecutionAware) isNull())).andReturn(resp);
 
         replayMocks();
-        final HttpResponse result = impl.execute(route, request, context, null);
+        final ClassicHttpResponse result = impl.execute(request, context, null);
         verifyMocks();
         Assert.assertSame(resp, result);
     }
@@ -1371,9 +1353,9 @@ public abstract class TestCachingExecCha
 
         request.addHeader("Cache-Control", "only-if-cached");
 
-        final HttpResponse resp = impl.execute(route, request, context, null);
+        final ClassicHttpResponse resp = impl.execute(request, context, null);
 
-        Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getCode());
     }
 
     @Test
@@ -1391,10 +1373,10 @@ public abstract class TestCachingExecCha
         cacheEntrySuitable(false);
 
         replayMocks();
-        final HttpResponse resp = impl.execute(route, request, context, null);
+        final ClassicHttpResponse resp = impl.execute(request, context, null);
         verifyMocks();
 
-        Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getStatusLine().getStatusCode());
+        Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getCode());
     }
 
     @Test
@@ -1411,7 +1393,7 @@ public abstract class TestCachingExecCha
         entryHasStaleness(0);
 
         replayMocks();
-        final HttpResponse resp = impl.execute(route, request, context, null);
+        final ClassicHttpResponse resp = impl.execute(request, context, null);
         verifyMocks();
 
         Assert.assertSame(mockCachedResponse, resp);
@@ -1420,56 +1402,51 @@ public abstract class TestCachingExecCha
     @Test
     public void testDoesNotSetConnectionInContextOnCacheHit() throws Exception {
         final DummyBackend backend = new DummyBackend();
-        final HttpResponse response = HttpTestUtils.make200Response();
+        final ClassicHttpResponse response = HttpTestUtils.make200Response();
         response.setHeader("Cache-Control", "max-age=3600");
         backend.setResponse(response);
         impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final HttpClientContext ctx = HttpClientContext.create();
-        ctx.setTargetHost(host);
-        impl.execute(route, request, context, null);
-        impl.execute(route, request, ctx, null);
+        impl.execute(request, context, null);
+        impl.execute(request, ctx, null);
         assertNull(ctx.getConnection());
     }
 
     @Test
     public void testSetsTargetHostInContextOnCacheHit() throws Exception {
         final DummyBackend backend = new DummyBackend();
-        final HttpResponse response = HttpTestUtils.make200Response();
+        final ClassicHttpResponse response = HttpTestUtils.make200Response();
         response.setHeader("Cache-Control", "max-age=3600");
         backend.setResponse(response);
         impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final HttpClientContext ctx = HttpClientContext.create();
-        ctx.setTargetHost(host);
-        impl.execute(route, request, context, null);
-        impl.execute(route, request, ctx, null);
-        assertSame(host, ctx.getTargetHost());
+        impl.execute(request, context, null);
+        impl.execute(request, ctx, null);
     }
 
     @Test
     public void testSetsRouteInContextOnCacheHit() throws Exception {
         final DummyBackend backend = new DummyBackend();
-        final HttpResponse response = HttpTestUtils.make200Response();
+        final ClassicHttpResponse response = HttpTestUtils.make200Response();
         response.setHeader("Cache-Control", "max-age=3600");
         backend.setResponse(response);
         impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final HttpClientContext ctx = HttpClientContext.create();
-        ctx.setTargetHost(host);
-        impl.execute(route, request, context, null);
-        impl.execute(route, request, ctx, null);
+        impl.execute(request, context, null);
+        impl.execute(request, ctx, null);
         assertEquals(route, ctx.getHttpRoute());
     }
 
     @Test
     public void testSetsRequestInContextOnCacheHit() throws Exception {
         final DummyBackend backend = new DummyBackend();
-        final HttpResponse response = HttpTestUtils.make200Response();
+        final ClassicHttpResponse response = HttpTestUtils.make200Response();
         response.setHeader("Cache-Control", "max-age=3600");
         backend.setResponse(response);
         impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final HttpClientContext ctx = HttpClientContext.create();
-        ctx.setTargetHost(host);
-        impl.execute(route, request, context, null);
-        impl.execute(route, request, ctx, null);
+        impl.execute(request, context, null);
+        impl.execute(request, ctx, null);
         if (!HttpTestUtils.equivalent(request, ctx.getRequest())) {
             assertSame(request, ctx.getRequest());
         }
@@ -1478,14 +1455,13 @@ public abstract class TestCachingExecCha
     @Test
     public void testSetsResponseInContextOnCacheHit() throws Exception {
         final DummyBackend backend = new DummyBackend();
-        final HttpResponse response = HttpTestUtils.make200Response();
+        final ClassicHttpResponse response = HttpTestUtils.make200Response();
         response.setHeader("Cache-Control", "max-age=3600");
         backend.setResponse(response);
         impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final HttpClientContext ctx = HttpClientContext.create();
-        ctx.setTargetHost(host);
-        impl.execute(route, request, context, null);
-        final HttpResponse result = impl.execute(route, request, ctx, null);
+        impl.execute(request, context, null);
+        final ClassicHttpResponse result = impl.execute(request, ctx, null);
         if (!HttpTestUtils.equivalent(result, ctx.getResponse())) {
             assertSame(result, ctx.getResponse());
         }
@@ -1494,27 +1470,25 @@ public abstract class TestCachingExecCha
     @Test
     public void testSetsRequestSentInContextOnCacheHit() throws Exception {
         final DummyBackend backend = new DummyBackend();
-        final HttpResponse response = HttpTestUtils.make200Response();
+        final ClassicHttpResponse response = HttpTestUtils.make200Response();
         response.setHeader("Cache-Control", "max-age=3600");
         backend.setResponse(response);
         impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT);
         final HttpClientContext ctx = HttpClientContext.create();
-        ctx.setTargetHost(host);
-        impl.execute(route, request, context, null);
-        impl.execute(route, request, ctx, null);
+        impl.execute(request, context, null);
+        impl.execute(request, ctx, null);
     }
 
     @Test
     public void testCanCacheAResponseWithoutABody() throws Exception {
-        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NO_CONTENT, "No Content");
+        final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_NO_CONTENT, "No Content");
         response.setHeader("Date", DateUtils.formatDate(new Date()));
         response.setHeader("Cache-Control", "max-age=300");
         final DummyBackend backend = new DummyBackend();
         backend.setResponse(response);
         impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        impl.execute(route, request, context, null);
-        impl.execute(route, request, context, null);
+        impl.execute(request, context, null);
+        impl.execute(request, context, null);
         assertEquals(1, backend.getExecutions());
     }
 
@@ -1525,12 +1499,11 @@ public abstract class TestCachingExecCha
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req1.addHeader("If-None-Match", "\"etag\"");
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not modified");
+        final ClassicHttpResponse resp1 = HttpTestUtils.make304Response();
         resp1.setHeader("Content-Length", "128");
         resp1.setHeader("ETag", "\"etag\"");
         resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
@@ -1538,10 +1511,10 @@ public abstract class TestCachingExecCha
 
         backendExpectsAnyRequestAndReturn(resp1);
         replayMocks();
-        final HttpResponse result = impl.execute(route, req1, context, null);
+        final ClassicHttpResponse result = impl.execute(req1, context, null);
         verifyMocks();
 
-        assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
+        assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getCode());
         assertNull("The 304 response messages MUST NOT contain a message-body", result.getEntity());
     }
 
@@ -1552,22 +1525,20 @@ public abstract class TestCachingExecCha
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req1.addHeader("If-None-Match", "etag");
 
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req2.addHeader("If-None-Match", "etag");
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not modified");
+        final ClassicHttpResponse resp1 = HttpTestUtils.make304Response();
         resp1.setHeader("Date", DateUtils.formatDate(now));
         resp1.setHeader("Cache-Control", "max-age=0");
         resp1.setHeader("Etag", "etag");
 
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not modified");
+        final ClassicHttpResponse resp2 = HttpTestUtils.make304Response();
         resp2.setHeader("Date", DateUtils.formatDate(now));
         resp2.setHeader("Cache-Control", "max-age=0");
         resp1.setHeader("Etag", "etag");
@@ -1575,13 +1546,13 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
         backendExpectsAnyRequestAndReturn(resp2);
         replayMocks();
-        final HttpResponse result1 = impl.execute(route, req1, context, null);
-        final HttpResponse result2 = impl.execute(route, req2, context, null);
+        final ClassicHttpResponse result1 = impl.execute(req1, context, null);
+        final ClassicHttpResponse result2 = impl.execute(req2, context, null);
         verifyMocks();
 
-        assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode());
+        assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getCode());
         assertEquals("etag", result1.getFirstHeader("Etag").getValue());
-        assertEquals(HttpStatus.SC_NOT_MODIFIED, result2.getStatusLine().getStatusCode());
+        assertEquals(HttpStatus.SC_NOT_MODIFIED, result2.getCode());
         assertEquals("etag", result2.getFirstHeader("Etag").getValue());
     }
 
@@ -1592,23 +1563,21 @@ public abstract class TestCachingExecCha
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req1.addHeader("If-None-Match", "etag");
 
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req2.addHeader("If-None-Match", "etag");
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not modified");
+        final ClassicHttpResponse resp1 = HttpTestUtils.make304Response();
         resp1.setHeader("Date", DateUtils.formatDate(now));
         resp1.setHeader("Cache-Control", "max-age=0");
         resp1.setHeader("Etag", "etag");
         resp1.setHeader("Vary", "Accept-Encoding");
 
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not modified");
+        final ClassicHttpResponse resp2 = HttpTestUtils.make304Response();
         resp2.setHeader("Date", DateUtils.formatDate(now));
         resp2.setHeader("Cache-Control", "max-age=0");
         resp1.setHeader("Etag", "etag");
@@ -1617,13 +1586,13 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
         backendExpectsAnyRequestAndReturn(resp2);
         replayMocks();
-        final HttpResponse result1 = impl.execute(route, req1, context, null);
-        final HttpResponse result2 = impl.execute(route, req2, context, null);
+        final ClassicHttpResponse result1 = impl.execute(req1, context, null);
+        final ClassicHttpResponse result2 = impl.execute(req2, context, null);
         verifyMocks();
 
-        assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode());
+        assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getCode());
         assertEquals("etag", result1.getFirstHeader("Etag").getValue());
-        assertEquals(HttpStatus.SC_NOT_MODIFIED, result2.getStatusLine().getStatusCode());
+        assertEquals(HttpStatus.SC_NOT_MODIFIED, result2.getCode());
         assertEquals("etag", result2.getFirstHeader("Etag").getValue());
     }
 
@@ -1635,22 +1604,21 @@ public abstract class TestCachingExecCha
 
         impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
 
-        final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
         req1.addHeader("If-None-Match", "etag");
 
-        final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet(
-            "http://foo.example.com/"), host);
+        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(new HttpGet(
+            "http://foo.example.com/"), route);
 
-        final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-            HttpStatus.SC_NOT_MODIFIED, "Not modified");
+        final ClassicHttpResponse resp1 = HttpTestUtils.make304Response();
         resp1.setHeader("Date", DateUtils.formatDate(now));
         resp1.setHeader("Cache-Control", "public, max-age=60");
         resp1.setHeader("Expires", DateUtils.formatDate(inOneMinute));
         resp1.setHeader("Etag", "etag");
         resp1.setHeader("Vary", "Accept-Encoding");
 
-        final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK,
+        final ClassicHttpResponse resp2 = new BasicClassicHttpResponse(HttpStatus.SC_OK,
             "Ok");
         resp2.setHeader("Date", DateUtils.formatDate(now));
         resp2.setHeader("Cache-Control", "public, max-age=60");
@@ -1662,70 +1630,62 @@ public abstract class TestCachingExecCha
         backendExpectsAnyRequestAndReturn(resp1);
         backendExpectsAnyRequestAndReturn(resp2).anyTimes();
         replayMocks();
-        final HttpResponse result1 = impl.execute(route, req1, context, null);
-        final HttpResponse result2 = impl.execute(route, req2, context, null);
+        final ClassicHttpResponse result1 = impl.execute(req1, context, null);
+        final ClassicHttpResponse result2 = impl.execute(req2, context, null);
         verifyMocks();
 
-        assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode());
+        assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getCode());
         assertNull(result1.getEntity());
-        assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode());
+        assertEquals(HttpStatus.SC_OK, result2.getCode());
         Assert.assertNotNull(result2.getEntity());
     }
 
     @Test
     public void testUsesVirtualHostForCacheKey() throws Exception {
         final DummyBackend backend = new DummyBackend();
-        final HttpResponse response = HttpTestUtils.make200Response();
+        final ClassicHttpResponse response = HttpTestUtils.make200Response();
         response.setHeader("Cache-Control", "max-age=3600");
         backend.setResponse(response);
         impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT);
-        impl.execute(route, request, context, null);
+        impl.execute(request, context, null);
         assertEquals(1, backend.getExecutions());
-        context.setTargetHost(new HttpHost("bar.example.com"));
-        impl.execute(route, request, context, null);
+        request.setAuthority(new URIAuthority("bar.example.com"));
+        impl.execute(request, context, null);
         assertEquals(2, backend.getExecutions());
-        impl.execute(route, request, context, null);
+        impl.execute(request, context, null);
         assertEquals(2, backend.getExecutions());
     }
 
-    private IExpectationSetters<CloseableHttpResponse> backendExpectsAnyRequestAndReturn(
-        final HttpResponse response) throws Exception {
-        final CloseableHttpResponse resp = mockBackend.execute(EasyMock.isA(HttpRoute.class),
-            EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class),
-            EasyMock.<HttpExecutionAware> isNull());
-        return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(response));
-    }
-
-    protected IExpectationSetters<CloseableHttpResponse> backendExpectsRequestAndReturn(
-        final HttpRequestWrapper request, final HttpResponse response) throws Exception {
-        final CloseableHttpResponse resp = mockBackend.execute(EasyMock.isA(HttpRoute.class),
-            EasyMock.eq(request), EasyMock.isA(HttpClientContext.class),
-            EasyMock.<HttpExecutionAware> isNull());
-        return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(response));
+    protected IExpectationSetters<ClassicHttpResponse> backendExpectsRequestAndReturn(
+            final RoutedHttpRequest request, final ClassicHttpResponse response) throws Exception {
+        final ClassicHttpResponse resp = mockBackend.execute(

[... 61 lines stripped ...]