HTTPCLIENT-997: cache module should handle out-of-order validations properly and unconditionally refresh

Contributed by Jonathan Moore <jonathan_moore at comcast.com> 


git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1000011 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2010-09-22 14:52:44 +00:00
parent 43d6095b81
commit e82184af36
12 changed files with 621 additions and 229 deletions

View File

@ -33,7 +33,6 @@ import java.net.URL;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.annotation.ThreadSafe;
@ -145,45 +144,11 @@ class CacheInvalidator {
protected boolean requestShouldNotBeCached(HttpRequest req) {
String method = req.getRequestLine().getMethod();
return notGetOrHeadRequest(method) || containsCacheControlHeader(req)
|| containsPragmaHeader(req);
return notGetOrHeadRequest(method);
}
private boolean notGetOrHeadRequest(String method) {
return !(HeaderConstants.GET_METHOD.equals(method) || HeaderConstants.HEAD_METHOD
.equals(method));
}
private boolean containsPragmaHeader(HttpRequest req) {
return req.getFirstHeader(HeaderConstants.PRAGMA) != null;
}
private boolean containsCacheControlHeader(HttpRequest request) {
Header[] cacheControlHeaders = request.getHeaders(HeaderConstants.CACHE_CONTROL);
if (cacheControlHeaders == null) {
return false;
}
for (Header cacheControl : cacheControlHeaders) {
HeaderElement[] cacheControlElements = cacheControl.getElements();
if (cacheControlElements == null) {
return false;
}
for (HeaderElement cacheControlElement : cacheControlElements) {
if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equalsIgnoreCase(cacheControlElement
.getName())) {
return true;
}
if (HeaderConstants.CACHE_CONTROL_NO_STORE.equalsIgnoreCase(cacheControlElement
.getName())) {
return true;
}
}
}
return false;
}
}

View File

@ -56,6 +56,8 @@ import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.DateParseException;
import org.apache.http.impl.cookie.DateUtils;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
@ -529,12 +531,34 @@ public class CachingHttpClient implements HttpClient {
HttpContext context,
HttpCacheEntry cacheEntry) throws IOException, ProtocolException {
HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(request, cacheEntry);
Date requestDate = getCurrentDate();
HttpResponse backendResponse = backend.execute(target, conditionalRequest, context);
Date responseDate = getCurrentDate();
final Header entryDateHeader = cacheEntry.getFirstHeader("Date");
final Header responseDateHeader = backendResponse.getFirstHeader("Date");
if (entryDateHeader != null && responseDateHeader != null) {
try {
Date entryDate = DateUtils.parseDate(entryDateHeader.getValue());
Date respDate = DateUtils.parseDate(responseDateHeader.getValue());
if (respDate.before(entryDate)) {
HttpRequest unconditional = conditionalRequestBuilder
.buildUnconditionalRequest(request, cacheEntry);
requestDate = getCurrentDate();
backendResponse = backend.execute(target, unconditional, context);
responseDate = getCurrentDate();
}
} catch (DateParseException e) {
// either backend response or cached entry did not have a valid
// Date header, so we can't tell if they are out of order
// according to the origin clock; thus we can skip the
// unconditional retry recommended in 13.2.6 of RFC 2616.
}
}
int statusCode = backendResponse.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_NOT_MODIFIED || statusCode == HttpStatus.SC_OK) {
cacheUpdates.getAndIncrement();
@ -558,14 +582,32 @@ public class CachingHttpClient implements HttpClient {
responseCompliance.ensureProtocolCompliance(request, backendResponse);
boolean cacheable = responseCachingPolicy.isResponseCacheable(request, backendResponse);
if (cacheable) {
if (cacheable &&
!alreadyHaveNewerCacheEntry(target, request, backendResponse)) {
return responseCache.cacheAndReturnResponse(target, request, backendResponse, requestDate,
responseDate);
}
responseCache.flushCacheEntriesFor(target, request);
if (!cacheable) {
responseCache.flushCacheEntriesFor(target, request);
}
return backendResponse;
}
private boolean alreadyHaveNewerCacheEntry(HttpHost target, HttpRequest request,
HttpResponse backendResponse) throws IOException {
HttpCacheEntry existing = responseCache.getCacheEntry(target, request);
if (existing == null) return false;
Header entryDateHeader = existing.getFirstHeader("Date");
if (entryDateHeader == null) return false;
Header responseDateHeader = backendResponse.getFirstHeader("Date");
if (responseDateHeader == null) return false;
try {
Date entryDate = DateUtils.parseDate(entryDateHeader.getValue());
Date responseDate = DateUtils.parseDate(responseDateHeader.getValue());
return responseDate.before(entryDate);
} catch (DateParseException e) {
}
return false;
}
}

View File

@ -79,4 +79,30 @@ class ConditionalRequestBuilder {
}
/**
* Returns a request to unconditionally validate a cache entry with
* the origin. In certain cases (due to multiple intervening caches)
* our cache may actually receive a response to a normal conditional
* validation where the Date header is actually older than that of
* our current cache entry. In this case, the protocol recommendation
* is to retry the validation and force syncup with the origin.
* @param request client request we are trying to satisfy
* @param entry existing cache entry we are trying to validate
* @return an unconditional validation request
* @throws ProtocolException
*/
public HttpRequest buildUnconditionalRequest(HttpRequest request,
HttpCacheEntry entry) throws ProtocolException {
RequestWrapper wrapped = new RequestWrapper(request);
wrapped.resetHeaders();
wrapped.addHeader("Cache-Control","no-cache");
wrapped.addHeader("Pragma","no-cache");
wrapped.removeHeaders("If-Range");
wrapped.removeHeaders("If-Match");
wrapped.removeHeaders("If-None-Match");
wrapped.removeHeaders("If-Unmodified-Since");
wrapped.removeHeaders("If-Modified-Since");
return wrapped;
}
}

View File

@ -1,18 +1,14 @@
package org.apache.http.impl.client.cache;
import java.util.Date;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.cache.HttpCache;
import org.apache.http.impl.cookie.DateUtils;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.protocol.HttpContext;
import org.easymock.IExpectationSetters;
import org.easymock.classextension.EasyMock;
@ -46,7 +42,7 @@ public abstract class AbstractProtocolTest {
request = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1);
originResponse = make200Response();
originResponse = HttpTestUtils.make200Response();
params = new CacheConfig();
params.setMaxCacheEntries(MAX_ENTRIES);
@ -67,19 +63,6 @@ public abstract class AbstractProtocolTest {
EasyMock.verify(mockCache);
}
protected HttpResponse make200Response() {
HttpResponse out = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
out.setHeader("Date", DateUtils.formatDate(new Date()));
out.setHeader("Server", "MockOrigin/1.0");
out.setHeader("Content-Length", "128");
out.setEntity(makeBody(128));
return out;
}
protected HttpEntity makeBody(int nbytes) {
return HttpTestUtils.makeBody(nbytes);
}
protected IExpectationSetters<HttpResponse> backendExpectsAnyRequest() throws Exception {
HttpResponse resp = mockBackend.execute(EasyMock.isA(HttpHost.class), EasyMock
.isA(HttpRequest.class), (HttpContext) EasyMock.isNull());

View File

@ -44,6 +44,7 @@ import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.cookie.DateUtils;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
public class HttpTestUtils {
@ -288,4 +289,13 @@ public class HttpTestUtils {
Date now = new Date();
return makeCacheEntry(now, now);
}
public static HttpResponse make200Response() {
HttpResponse out = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
out.setHeader("Date", DateUtils.formatDate(new Date()));
out.setHeader("Server", "MockOrigin/1.0");
out.setHeader("Content-Length", "128");
out.setEntity(makeBody(128));
return out;
}
}

View File

@ -208,16 +208,10 @@ public class TestCacheInvalidator {
}
@Test
public void testInvalidatesRequestsWithClientCacheControlHeaders() throws Exception {
public void testDoesNotInvalidateRequestsWithClientCacheControlHeaders() throws Exception {
HttpRequest request = new BasicHttpRequest("GET","/",HTTP_1_1);
request.setHeader("Cache-Control","no-cache");
final String theUri = "http://foo.example.com:80/";
cacheReturnsEntryForUri(theUri);
Set<String> variantURIs = new HashSet<String>();
cacheEntryHasVariantURIs(variantURIs);
entryIsRemoved(theUri);
replayMocks();
impl.flushInvalidatedCacheEntries(host, request);
@ -226,16 +220,10 @@ public class TestCacheInvalidator {
}
@Test
public void testInvalidatesRequestsWithClientPragmaHeaders() throws Exception {
public void testDoesNotInvalidateRequestsWithClientPragmaHeaders() throws Exception {
HttpRequest request = new BasicHttpRequest("GET","/",HTTP_1_1);
request.setHeader("Pragma","no-cache");
final String theUri = "http://foo.example.com:80/";
cacheReturnsEntryForUri(theUri);
Set<String> variantURIs = new HashSet<String>();
cacheEntryHasVariantURIs(variantURIs);
entryIsRemoved(theUri);
replayMocks();
impl.flushInvalidatedCacheEntries(host, request);

View File

@ -32,6 +32,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
@ -49,6 +50,7 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.cookie.DateUtils;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.params.BasicHttpParams;
@ -99,6 +101,7 @@ public class TestCachingHttpClient {
private HttpRequest request;
private HttpContext context;
private HttpParams params;
private HttpCacheEntry entry;
@SuppressWarnings("unchecked")
@Before
@ -128,6 +131,7 @@ public class TestCachingHttpClient {
request = new BasicHttpRequest("GET", "/stuff", HttpVersion.HTTP_1_1);
context = new BasicHttpContext();
params = new BasicHttpParams();
entry = HttpTestUtils.makeCacheEntry();
impl = new CachingHttpClient(
mockBackend,
mockValidityPolicy,
@ -195,6 +199,8 @@ public class TestCachingHttpClient {
responseProtocolValidationIsCalled();
EasyMock.expect(mockCache.getCacheEntry(host, request))
.andReturn(null);
EasyMock.expect(mockCache.cacheAndReturnResponse(host, request, mockBackendResponse, requestDate, responseDate))
.andReturn(mockCachedResponse);
@ -206,6 +212,60 @@ public class TestCachingHttpClient {
Assert.assertSame(mockCachedResponse, result);
}
@Test
public void testOlderCacheableResponsesDoNotGoIntoCache() throws Exception {
responsePolicyAllowsCaching(true);
responseProtocolValidationIsCalled();
Date now = new Date();
Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L);
Header entryDateHeader = new BasicHeader("Date", DateUtils.formatDate(now));
Header[] headers = { entryDateHeader };
entry = HttpTestUtils.makeCacheEntry(headers);
Header responseDateHeader = new BasicHeader("Date", DateUtils.formatDate(fiveSecondsAgo));
EasyMock.expect(mockCache.getCacheEntry(host, request))
.andReturn(entry);
EasyMock.expect(mockBackendResponse.getFirstHeader("Date"))
.andReturn(responseDateHeader).anyTimes();
replayMocks();
HttpResponse result = impl.handleBackendResponse(host, request, requestDate,
responseDate, mockBackendResponse);
verifyMocks();
Assert.assertSame(mockBackendResponse, result);
}
@Test
public void testNewerCacheableResponsesReplaceExistingCacheEntry() throws Exception {
responsePolicyAllowsCaching(true);
responseProtocolValidationIsCalled();
Date now = new Date();
Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L);
Header entryDateHeader = new BasicHeader("Date", DateUtils.formatDate(fiveSecondsAgo));
Header[] headers = { entryDateHeader };
entry = HttpTestUtils.makeCacheEntry(headers);
Header responseDateHeader = new BasicHeader("Date", DateUtils.formatDate(now));
EasyMock.expect(mockCache.getCacheEntry(host, request))
.andReturn(entry);
EasyMock.expect(mockBackendResponse.getFirstHeader("Date"))
.andReturn(responseDateHeader).anyTimes();
EasyMock.expect(mockCache.cacheAndReturnResponse(host, request,
mockBackendResponse, requestDate, responseDate))
.andReturn(mockCachedResponse);
replayMocks();
HttpResponse result = impl.handleBackendResponse(host, request, requestDate,
responseDate, mockBackendResponse);
verifyMocks();
Assert.assertSame(mockCachedResponse, result);
}
@Test
public void testRequestThatCannotBeServedFromCacheCausesBackendRequest() throws Exception {
cacheInvalidatorWasCalled();
@ -302,54 +362,139 @@ public class TestCachingHttpClient {
}
@Test
public void testRevalidationCallsHandleBackEndResponseWhenNot304() throws Exception {
public void testRevalidationCallsHandleBackEndResponseWhenNot200Or304() throws Exception {
mockImplMethods(GET_CURRENT_DATE, HANDLE_BACKEND_RESPONSE);
conditionalRequestBuilderCalled();
HttpRequest validate =
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse originResponse =
new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_NOT_FOUND, "Not Found");
HttpResponse finalResponse = HttpTestUtils.make200Response();
conditionalRequestBuilderReturns(validate);
getCurrentDateReturns(requestDate);
backendCallWasMadeWithRequest(mockConditionalRequest);
backendCall(validate, originResponse);
getCurrentDateReturns(responseDate);
backendResponseCodeIs(HttpStatus.SC_OK);
EasyMock.expect(mockCache.updateCacheEntry(host, request,
mockCacheEntry, mockBackendResponse, requestDate, responseDate))
.andReturn(mockCachedResponse);
EasyMock.expect(impl.handleBackendResponse(host, validate,
requestDate, responseDate, originResponse))
.andReturn(finalResponse);
replayMocks();
HttpResponse result = impl.revalidateCacheEntry(host, request, context,
mockCacheEntry);
HttpResponse result =
impl.revalidateCacheEntry(host, request, context, entry);
verifyMocks();
Assert.assertEquals(mockCachedResponse, result);
Assert.assertEquals(0, impl.getCacheMisses());
Assert.assertEquals(0, impl.getCacheHits());
Assert.assertEquals(1, impl.getCacheUpdates());
Assert.assertSame(finalResponse, result);
}
@Test
public void testRevalidationUpdatesCacheEntryAndPutsItToCacheWhen304ReturningCachedResponse()
throws Exception {
mockImplMethods(GET_CURRENT_DATE);
conditionalRequestBuilderCalled();
HttpRequest validate =
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse originResponse =
new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_NOT_MODIFIED, "Not Modified");
HttpResponse finalResponse = HttpTestUtils.make200Response();
conditionalRequestBuilderReturns(validate);
getCurrentDateReturns(requestDate);
backendCallWasMadeWithRequest(mockConditionalRequest);
backendCall(validate, originResponse);
getCurrentDateReturns(responseDate);
backendResponseCodeIs(HttpStatus.SC_NOT_MODIFIED);
EasyMock.expect(mockCache.updateCacheEntry(host, request,
mockCacheEntry, mockBackendResponse, requestDate, responseDate))
.andReturn(mockCachedResponse);
entry, originResponse, requestDate, responseDate))
.andReturn(finalResponse);
replayMocks();
HttpResponse result = impl.revalidateCacheEntry(host, request, context, mockCacheEntry);
HttpResponse result =
impl.revalidateCacheEntry(host, request, context, entry);
verifyMocks();
Assert.assertEquals(mockCachedResponse, result);
Assert.assertEquals(0, impl.getCacheMisses());
Assert.assertEquals(0, impl.getCacheHits());
Assert.assertEquals(1, impl.getCacheUpdates());
Assert.assertSame(finalResponse, result);
}
@Test
public void testRevalidationUpdatesCacheEntryAndPutsItToCacheWhen200ReturningCachedResponse()
throws Exception {
mockImplMethods(GET_CURRENT_DATE);
HttpRequest validate =
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse originResponse = HttpTestUtils.make200Response();
HttpResponse finalResponse = HttpTestUtils.make200Response();
conditionalRequestBuilderReturns(validate);
getCurrentDateReturns(requestDate);
backendCall(validate, originResponse);
getCurrentDateReturns(responseDate);
EasyMock.expect(mockCache.updateCacheEntry(host, request,
entry, originResponse, requestDate, responseDate))
.andReturn(finalResponse);
replayMocks();
HttpResponse result =
impl.revalidateCacheEntry(host, request, context, entry);
verifyMocks();
Assert.assertSame(finalResponse, result);
}
@Test
public void testRevalidationRetriesUnconditionallyIfOlderResponseReceived()
throws Exception {
// TODO
mockImplMethods(GET_CURRENT_DATE);
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
Date elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L);
Header[] headers = {
new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
new BasicHeader("Cache-Control","max-age=5"),
new BasicHeader("ETag", "\"etag1\"")
};
entry = HttpTestUtils.makeCacheEntry(headers);
HttpRequest validate =
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse originResponse1 =
new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED,
"Not Modified");
originResponse1.setHeader("Date", DateUtils.formatDate(elevenSecondsAgo));
HttpRequest unconditional =
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse originResponse2 = HttpTestUtils.make200Response();
HttpResponse finalResponse = HttpTestUtils.make200Response();
conditionalRequestBuilderReturns(validate);
getCurrentDateReturns(requestDate);
backendCall(validate, originResponse1);
getCurrentDateReturns(responseDate);
EasyMock.expect(mockConditionalRequestBuilder.buildUnconditionalRequest(request, entry))
.andReturn(unconditional);
final Date requestDate2 = new Date();
getCurrentDateReturns(requestDate2);
backendCall(unconditional, originResponse2);
final Date responseDate2 = new Date();
getCurrentDateReturns(responseDate2);
EasyMock.expect(mockCache.updateCacheEntry(host, request,
entry, originResponse2, requestDate2, responseDate2))
.andReturn(finalResponse);
replayMocks();
HttpResponse result =
impl.revalidateCacheEntry(host, request, context, entry);
verifyMocks();
Assert.assertSame(finalResponse, result);
}
@Test
@ -1102,16 +1247,11 @@ public class TestCachingHttpClient {
EasyMock.<HttpCacheEntry>anyObject())).andReturn(b);
}
private void backendResponseCodeIs(int code) {
EasyMock.expect(mockBackendResponse.getStatusLine()).andReturn(mockStatusLine);
EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(code);
}
private void conditionalRequestBuilderCalled() throws ProtocolException {
EasyMock.expect(
mockConditionalRequestBuilder.buildConditionalRequest(
EasyMock.<HttpRequest>anyObject(),
EasyMock.<HttpCacheEntry>anyObject())).andReturn(mockConditionalRequest);
private void conditionalRequestBuilderReturns(HttpRequest validate)
throws Exception {
EasyMock.expect(mockConditionalRequestBuilder
.buildConditionalRequest(request, entry))
.andReturn(validate);
}
private void getCurrentDateReturns(Date date) {
@ -1123,11 +1263,10 @@ public class TestCachingHttpClient {
EasyMock.<HttpRequest>anyObject())).andReturn(allow);
}
private void backendCallWasMadeWithRequest(HttpRequest request) throws IOException {
EasyMock.expect(mockBackend.execute(
EasyMock.<HttpHost>anyObject(),
EasyMock.same(request),
EasyMock.<HttpContext>anyObject())).andReturn(mockBackendResponse);
private void backendCall(HttpRequest req, HttpResponse resp)
throws Exception {
EasyMock.expect(mockBackend.execute(host, req, context))
.andReturn(resp);
}
private void backendCallWasMade(HttpRequest request, HttpResponse response) throws IOException {

View File

@ -44,10 +44,14 @@ import org.junit.Test;
public class TestConditionalRequestBuilder {
private ConditionalRequestBuilder impl;
private HttpRequest request;
private HttpCacheEntry entry;
@Before
public void setUp() throws Exception {
impl = new ConditionalRequestBuilder();
request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
entry = HttpTestUtils.makeCacheEntry();
}
@Test
@ -170,4 +174,107 @@ public class TestConditionalRequestBuilder {
}
Assert.assertTrue(foundMaxAge0);
}
@Test
public void testBuildUnconditionalRequestUsesGETMethod()
throws Exception {
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertEquals("GET", result.getRequestLine().getMethod());
}
@Test
public void testBuildUnconditionalRequestUsesRequestUri()
throws Exception {
final String uri = "/theURI";
request = new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1);
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertEquals(uri, result.getRequestLine().getUri());
}
@Test
public void testBuildUnconditionalRequestUsesHTTP_1_1()
throws Exception {
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertEquals(HttpVersion.HTTP_1_1, result.getProtocolVersion());
}
@Test
public void testBuildUnconditionalRequestAddsCacheControlNoCache()
throws Exception {
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
boolean ccNoCacheFound = false;
for(Header h : result.getHeaders("Cache-Control")) {
for(HeaderElement elt : h.getElements()) {
if ("no-cache".equals(elt.getName())) {
ccNoCacheFound = true;
}
}
}
Assert.assertTrue(ccNoCacheFound);
}
@Test
public void testBuildUnconditionalRequestAddsPragmaNoCache()
throws Exception {
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
boolean ccNoCacheFound = false;
for(Header h : result.getHeaders("Pragma")) {
for(HeaderElement elt : h.getElements()) {
if ("no-cache".equals(elt.getName())) {
ccNoCacheFound = true;
}
}
}
Assert.assertTrue(ccNoCacheFound);
}
@Test
public void testBuildUnconditionalRequestDoesNotUseIfRange()
throws Exception {
request.addHeader("If-Range","\"etag\"");
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertNull(result.getFirstHeader("If-Range"));
}
@Test
public void testBuildUnconditionalRequestDoesNotUseIfMatch()
throws Exception {
request.addHeader("If-Match","\"etag\"");
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertNull(result.getFirstHeader("If-Match"));
}
@Test
public void testBuildUnconditionalRequestDoesNotUseIfNoneMatch()
throws Exception {
request.addHeader("If-None-Match","\"etag\"");
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertNull(result.getFirstHeader("If-None-Match"));
}
@Test
public void testBuildUnconditionalRequestDoesNotUseIfUnmodifiedSince()
throws Exception {
request.addHeader("If-Unmodified-Since", DateUtils.formatDate(new Date()));
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertNull(result.getFirstHeader("If-Unmodified-Since"));
}
@Test
public void testBuildUnconditionalRequestDoesNotUseIfModifiedSince()
throws Exception {
request.addHeader("If-Modified-Since", DateUtils.formatDate(new Date()));
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertNull(result.getFirstHeader("If-Modified-Since"));
}
@Test
public void testBuildUnconditionalRequestCarriesOtherRequestHeaders()
throws Exception {
request.addHeader("User-Agent","MyBrowser/1.0");
HttpRequest result = impl.buildUnconditionalRequest(request, entry);
Assert.assertEquals("MyBrowser/1.0",
result.getFirstHeader("User-Agent").getValue());
}
}

View File

@ -26,6 +26,7 @@
*/
package org.apache.http.impl.client.cache;
import static org.easymock.classextension.EasyMock.*;
import static org.junit.Assert.*;
import java.io.IOException;
@ -33,12 +34,16 @@ import java.util.Date;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.impl.cookie.DateUtils;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.protocol.HttpContext;
import org.easymock.Capture;
import org.junit.Test;
/*
@ -81,7 +86,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
*/
private HttpRequest requestToPopulateStaleCacheEntry() throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
@ -218,7 +223,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
public void testReturnsCachedResponsesAppropriatelyWhenNoOriginCommunication()
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
resp1.setHeader("Cache-Control", "public, max-age=5");
@ -299,4 +304,131 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
assertEquals(warning, result.getFirstHeader("Warning").getValue());
}
/*
* "If an origin server wishes to force a semantically transparent cache
* to validate every request, it MAY assign an explicit expiration time
* in the past. This means that the response is always stale, and so the
* cache SHOULD validate it before using it for subsequent requests."
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.1
*/
@Test
public void testRevalidatesCachedResponseWithExpirationInThePast()
throws Exception {
Date now = new Date();
Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L);
Date oneSecondFromNow = new Date(now.getTime() + 1 * 1000L);
Date twoSecondsFromNow = new Date(now.getTime() + 2 * 1000L);
HttpRequest req1 =
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("Date", DateUtils.formatDate(now));
resp1.setHeader("Expires",DateUtils.formatDate(oneSecondAgo));
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 =
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpRequest revalidate =
new BasicHttpRequest("GET", "/",HttpVersion.HTTP_1_1);
revalidate.setHeader("If-None-Match","\"etag\"");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_NOT_MODIFIED, "Not Modified");
resp2.setHeader("Date", DateUtils.formatDate(twoSecondsFromNow));
resp2.setHeader("Expires", DateUtils.formatDate(oneSecondFromNow));
resp2.setHeader("ETag","\"etag\"");
expect(mockBackend.execute(isA(HttpHost.class),
eqRequest(revalidate), (HttpContext)isNull()))
.andReturn(resp2);
replayMocks();
impl.execute(host, req1);
HttpResponse result = impl.execute(host, req2);
verifyMocks();
assertEquals(HttpStatus.SC_OK,
result.getStatusLine().getStatusCode());
}
/* "When a client tries to revalidate a cache entry, and the response
* it receives contains a Date header that appears to be older than the
* one for the existing entry, then the client SHOULD repeat the
* request unconditionally, and include
* Cache-Control: max-age=0
* to force any intermediate caches to validate their copies directly
* with the origin server, or
* Cache-Control: no-cache
* to force any intermediate caches to obtain a new copy from the
* origin server."
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.6
*/
@Test
public void testRetriesValidationThatResultsInAnOlderDated304Response()
throws Exception {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
Date elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L);
HttpRequest req1 =
new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
resp1.setHeader("Cache-Control","max-age=5");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_NOT_MODIFIED, "Not Modified");
resp2.setHeader("ETag","\"etag\"");
resp2.setHeader("Date", DateUtils.formatDate(elevenSecondsAgo));
backendExpectsAnyRequest().andReturn(resp2);
Capture<HttpRequest> cap = new Capture<HttpRequest>();
HttpResponse resp3 = HttpTestUtils.make200Response();
resp3.setHeader("ETag","\"etag2\"");
resp3.setHeader("Date", DateUtils.formatDate(now));
resp3.setHeader("Cache-Control","max-age=5");
expect(mockBackend.execute(isA(HttpHost.class), capture(cap),
(HttpContext)isNull()))
.andReturn(resp3);
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
verifyMocks();
HttpRequest captured = cap.getValue();
boolean hasMaxAge0 = false;
boolean hasNoCache = false;
for(Header h : captured.getHeaders("Cache-Control")) {
for(HeaderElement elt : h.getElements()) {
if ("max-age".equals(elt.getName())) {
try {
int maxage = Integer.parseInt(elt.getValue());
if (maxage == 0) {
hasMaxAge0 = true;
}
} catch (NumberFormatException nfe) {
// nop
}
} else if ("no-cache".equals(elt.getName())) {
hasNoCache = true;
}
}
}
assertTrue(hasMaxAge0 || hasNoCache);
assertNull(captured.getFirstHeader("If-None-Match"));
assertNull(captured.getFirstHeader("If-Modified-Since"));
assertNull(captured.getFirstHeader("If-Range"));
assertNull(captured.getFirstHeader("If-Match"));
assertNull(captured.getFirstHeader("If-Unmodified-Since"));
}
}

View File

@ -866,21 +866,21 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
// put something cacheable in the cache
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.addHeader("Cache-Control", "max-age=3600");
resp1.setHeader(eHeader, oldVal);
// get a head that penetrates the cache
HttpRequest req2 = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
req2.addHeader("Cache-Control", "no-cache");
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setEntity(null);
resp2.setHeader(eHeader, newVal);
// next request doesn't tolerate stale entry
HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
req3.addHeader("Cache-Control", "max-stale=0");
HttpResponse resp3 = make200Response();
HttpResponse resp3 = HttpTestUtils.make200Response();
resp3.setHeader(eHeader, newVal);
EasyMock.expect(
@ -1136,7 +1136,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag", "\"etag\"");
resp1.setHeader("Cache-Control", "max-age=3600");
@ -1166,7 +1166,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag", "\"etag\"");
resp1.setHeader("Cache-Control", "max-age=3600");
@ -1198,7 +1198,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void test206ResponseGeneratedFromCacheMustHaveDateHeader() throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag", "\"etag\"");
resp1.setHeader("Cache-Control", "max-age=3600");
@ -1307,7 +1307,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date nextSecond = new Date(now.getTime() + 1000L);
Date inTwoHoursPlusASec = new Date(now.getTime() + 2 * 3600 * 1000L + 1000L);
HttpResponse originResponse2 = make200Response();
HttpResponse originResponse2 = HttpTestUtils.make200Response();
originResponse2.setHeader("Date", DateUtils.formatDate(nextSecond));
originResponse2.setHeader("Cache-Control", "max-age=7200");
originResponse2.setHeader("Expires", DateUtils.formatDate(inTwoHoursPlusASec));
@ -1351,7 +1351,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date now = new Date();
Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L);
originResponse = make200Response();
originResponse = HttpTestUtils.make200Response();
originResponse.addHeader("Allow", "GET,HEAD");
originResponse.addHeader("Cache-Control", "max-age=3600");
originResponse.addHeader("Content-Language", "en");
@ -1448,7 +1448,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date now = new Date();
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("ETag", "\"etag1\"");
byte[] bytes1 = new byte[128];
@ -1476,7 +1476,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date inTwoSeconds = new Date(now.getTime() + 2000L);
HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp3 = make200Response();
HttpResponse resp3 = HttpTestUtils.make200Response();
resp3.setHeader("Date", DateUtils.formatDate(inTwoSeconds));
resp3.setHeader("Cache-Control", "max-age=3600");
resp3.setHeader("ETag", "\"etag2\"");
@ -1524,7 +1524,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date now = new Date();
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
Date oneHourAgo = new Date(now.getTime() - 3600L);
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("Last-Modified", DateUtils.formatDate(oneHourAgo));
@ -1553,7 +1553,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date inTwoSeconds = new Date(now.getTime() + 2000L);
HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp3 = make200Response();
HttpResponse resp3 = HttpTestUtils.make200Response();
resp3.setHeader("Date", DateUtils.formatDate(inTwoSeconds));
resp3.setHeader("Cache-Control", "max-age=3600");
resp3.setHeader("ETag", "\"etag2\"");
@ -1812,7 +1812,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
req1.setHeader("Accept-Encoding", "gzip");
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag", "\"v1\"");
resp1.setHeader("Cache-Control", "max-age=7200");
resp1.setHeader("Expires", DateUtils.formatDate(inTwoHours));
@ -1823,7 +1823,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req1.setHeader("Accept-Encoding", "gzip");
req1.setHeader("Cache-Control", "no-cache");
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("ETag", "\"v2\"");
resp2.setHeader("Cache-Control", "max-age=3600");
resp2.setHeader("Expires", DateUtils.formatDate(inTwoHours));
@ -1871,7 +1871,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag", "W/\"v1\"");
resp1.setHeader("Allow", "GET,HEAD");
resp1.setHeader("Content-Encoding", "x-coding");
@ -1920,7 +1920,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
// load cache with cacheable entry
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag", "\"etag1\"");
resp1.setHeader("Cache-Control", "max-age=3600");
@ -1942,7 +1942,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
// unconditional validation doesn't use If-None-Match
HttpRequest unconditionalValidation = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
// new response to unconditional validation provides new body
HttpResponse resp3 = make200Response();
HttpResponse resp3 = HttpTestUtils.make200Response();
resp1.setHeader("ETag", "\"etag2\"");
resp1.setHeader("Cache-Control", "max-age=3600");
@ -1980,7 +1980,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest initialRequest = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse cachedResponse = make200Response();
HttpResponse cachedResponse = HttpTestUtils.make200Response();
cachedResponse.setHeader("Cache-Control", "max-age=3600");
cachedResponse.setHeader("ETag", "\"etag\"");
@ -2000,7 +2000,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
conditionalResponse.setHeader("X-Extra", "junk");
// to be used if the cache generates an unconditional validation
HttpResponse unconditionalResponse = make200Response();
HttpResponse unconditionalResponse = HttpTestUtils.make200Response();
unconditionalResponse.setHeader("Date", DateUtils.formatDate(inFiveSeconds));
unconditionalResponse.setHeader("ETag", "\"etag\"");
@ -2373,7 +2373,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 25 * 1000L);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
resp1.setHeader("ETag", "\"etag\"");
resp1.setHeader("Cache-Control", "max-age=5");
@ -2438,7 +2438,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
resp1.setHeader("ETag", "\"etag\"");
resp1.setHeader("Cache-Control", "max-age=5");
@ -2577,13 +2577,13 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1);
HttpResponse validated = make200Response();
HttpResponse validated = HttpTestUtils.make200Response();
validated.setHeader("Cache-Control", "public");
validated.setHeader("Last-Modified", DateUtils.formatDate(oneYearAgo));
validated.setHeader("Content-Length", "128");
validated.setEntity(new ByteArrayEntity(bytes));
HttpResponse reconstructed = make200Response();
HttpResponse reconstructed = HttpTestUtils.make200Response();
Capture<HttpRequest> cap = new Capture<HttpRequest>();
@ -2633,17 +2633,17 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
// put an entry in the cache
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(inFiveSecond));
resp1.setHeader("ETag", "\"etag1\"");
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("Content-Length", "128");
// force a revalidation
// force another origin hit
HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
req2.setHeader("Cache-Control", "max-age=0,max-stale=0");
req2.setHeader("Cache-Control", "no-cache");
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("Date", DateUtils.formatDate(now)); // older
resp2.setHeader("ETag", "\"etag2\"");
resp2.setHeader("Cache-Control", "max-age=3600");
@ -2761,7 +2761,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testSubrangeGETMustUseStrongComparisonForCachedResponse() throws Exception {
Date now = new Date();
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(now));
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("ETag", "\"etag\"");
@ -2801,7 +2801,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(now));
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
@ -2871,7 +2871,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(now));
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
@ -2901,7 +2901,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(now));
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
@ -2988,7 +2988,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
* already present: - Content-Location - Content-MD5 - ETag - Last-Modified
*/
private void testDoesNotModifyHeaderFromOrigin(String header, String value) throws Exception {
originResponse = make200Response();
originResponse = HttpTestUtils.make200Response();
originResponse.setHeader(header, value);
backendExpectsAnyRequest().andReturn(originResponse);
@ -3061,7 +3061,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
originResponse = make200Response();
originResponse = HttpTestUtils.make200Response();
originResponse.setHeader("Cache-Control", "max-age=3600");
originResponse.setHeader(header, value);
@ -3451,7 +3451,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
*/
public void testCachedEntityBodyIsUsedForResponseAfter304Validation() throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("ETag","\"etag\"");
@ -3509,7 +3509,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testResponseIncludesCacheEntryEndToEndHeadersForResponseAfter304Validation() throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("ETag","\"etag\"");
decorateWithEndToEndHeaders(resp1);
@ -3544,7 +3544,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testUpdatedEndToEndHeadersFrom304ArePassedOnResponseAndUpdatedInCacheEntry() throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("ETag","\"etag\"");
decorateWithEndToEndHeaders(resp1);
@ -3595,7 +3595,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testMultiHeadersAreSuccessfullyReplacedOn304Validation() throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.addHeader("Cache-Control","max-age=3600");
resp1.addHeader("Cache-Control","public");
resp1.setHeader("ETag","\"etag\"");
@ -3654,7 +3654,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L);
HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp1.setEntity(makeBody(50));
resp1.setEntity(HttpTestUtils.makeBody(50));
resp1.setHeader("Server","MockServer/1.0");
resp1.setHeader("Date", DateUtils.formatDate(twoSecondsAgo));
resp1.setHeader("Cache-Control","max-age=3600");
@ -3667,7 +3667,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req2.setHeader("Range","bytes=50-127");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp2.setEntity(makeBody(78));
resp2.setEntity(HttpTestUtils.makeBody(78));
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Content-Range","bytes 50-127/128");
resp2.setHeader("Server","MockServer/1.0");
@ -3678,7 +3678,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
resp3.setEntity(makeBody(128));
resp3.setEntity(HttpTestUtils.makeBody(128));
resp3.setHeader("Server","MockServer/1.0");
resp3.setHeader("Date", DateUtils.formatDate(now));
@ -3703,7 +3703,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req1.setHeader("Range","bytes=0-49");
HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp1.setEntity(makeBody(50));
resp1.setEntity(HttpTestUtils.makeBody(50));
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Content-Range","bytes 0-49/128");
resp1.setHeader("Server","MockServer/1.0");
@ -3715,7 +3715,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req2.setHeader("Range","bytes=50-127");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp2.setEntity(makeBody(78));
resp2.setEntity(HttpTestUtils.makeBody(78));
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Content-Range","bytes 50-127/128");
resp2.setHeader("ETag","\"etag1\"");
@ -3727,7 +3727,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
resp3.setEntity(makeBody(128));
resp3.setEntity(HttpTestUtils.makeBody(128));
resp3.setHeader("Server","MockServer/1.0");
resp3.setHeader("Date", DateUtils.formatDate(now));
@ -3752,7 +3752,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req1.setHeader("Range","bytes=0-49");
HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp1.setEntity(makeBody(50));
resp1.setEntity(HttpTestUtils.makeBody(50));
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Content-Range","bytes 0-49/128");
resp1.setHeader("ETag","\"etag1\"");
@ -3765,7 +3765,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req2.setHeader("Range","bytes=50-127");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp2.setEntity(makeBody(78));
resp2.setEntity(HttpTestUtils.makeBody(78));
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Content-Range","bytes 50-127/128");
resp2.setHeader("ETag","\"etag2\"");
@ -3777,7 +3777,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
resp3.setEntity(makeBody(128));
resp3.setEntity(HttpTestUtils.makeBody(128));
resp3.setHeader("Server","MockServer/1.0");
resp3.setHeader("Date", DateUtils.formatDate(now));
@ -3802,7 +3802,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req1.setHeader("Range","bytes=0-49");
HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp1.setEntity(makeBody(50));
resp1.setEntity(HttpTestUtils.makeBody(50));
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Content-Range","bytes 0-49/128");
resp1.setHeader("ETag","\"etag1\"");
@ -3815,7 +3815,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req2.setHeader("Range","bytes=50-127");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp2.setEntity(makeBody(78));
resp2.setEntity(HttpTestUtils.makeBody(78));
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Content-Range","bytes 50-127/128");
resp2.setHeader("Server","MockServer/1.0");
@ -3827,7 +3827,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req3.setHeader("Range","bytes=0-49");
HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
resp3.setEntity(makeBody(128));
resp3.setEntity(HttpTestUtils.makeBody(128));
resp3.setHeader("Server","MockServer/1.0");
resp3.setHeader("Date", DateUtils.formatDate(now));
@ -3853,7 +3853,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req1.setHeader("Range","bytes=0-49");
HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp1.setEntity(makeBody(50));
resp1.setEntity(HttpTestUtils.makeBody(50));
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Content-Range","bytes 0-49/128");
resp1.setHeader("Server","MockServer/1.0");
@ -3865,7 +3865,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req2.setHeader("Range","bytes=50-127");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp2.setEntity(makeBody(78));
resp2.setEntity(HttpTestUtils.makeBody(78));
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Content-Range","bytes 50-127/128");
resp2.setHeader("ETag","\"etag1\"");
@ -3878,7 +3878,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req3.setHeader("Range","bytes=0-49");
HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
resp3.setEntity(makeBody(128));
resp3.setEntity(HttpTestUtils.makeBody(128));
resp3.setHeader("Server","MockServer/1.0");
resp3.setHeader("Date", DateUtils.formatDate(now));
@ -3904,7 +3904,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req1.setHeader("Range","bytes=0-49");
HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp1.setEntity(makeBody(50));
resp1.setEntity(HttpTestUtils.makeBody(50));
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Content-Range","bytes 0-49/128");
resp1.setHeader("Etag","\"etag1\"");
@ -3917,7 +3917,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req2.setHeader("Range","bytes=50-127");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp2.setEntity(makeBody(78));
resp2.setEntity(HttpTestUtils.makeBody(78));
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Content-Range","bytes 50-127/128");
resp2.setHeader("ETag","\"etag2\"");
@ -3930,7 +3930,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req3.setHeader("Range","bytes=0-49");
HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
resp3.setEntity(makeBody(128));
resp3.setEntity(HttpTestUtils.makeBody(128));
resp3.setHeader("Server","MockServer/1.0");
resp3.setHeader("Date", DateUtils.formatDate(now));
@ -3956,7 +3956,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req1.setHeader("Range","bytes=0-49");
HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp1.setEntity(makeBody(50));
resp1.setEntity(HttpTestUtils.makeBody(50));
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Content-Range","bytes 0-49/128");
resp1.setHeader("Etag","\"etag1\"");
@ -3969,7 +3969,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req2.setHeader("Range","bytes=50-127");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp2.setEntity(makeBody(78));
resp2.setEntity(HttpTestUtils.makeBody(78));
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Content-Range","bytes 50-127/128");
resp2.setHeader("ETag","\"etag2\"");
@ -3982,7 +3982,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req3.setHeader("Range","bytes=50-127");
HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
resp3.setEntity(makeBody(128));
resp3.setEntity(HttpTestUtils.makeBody(128));
resp3.setHeader("Server","MockServer/1.0");
resp3.setHeader("Date", DateUtils.formatDate(now));
@ -4007,7 +4007,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req1.setHeader("Range","bytes=0-49");
HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp1.setEntity(makeBody(50));
resp1.setEntity(HttpTestUtils.makeBody(50));
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Content-Range","bytes 0-49/128");
resp1.setHeader("Etag","\"etag1\"");
@ -4020,7 +4020,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req2.setHeader("Range","bytes=50-127");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
resp2.setEntity(makeBody(78));
resp2.setEntity(HttpTestUtils.makeBody(78));
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Content-Range","bytes 50-127/128");
resp2.setHeader("ETag","\"etag2\"");
@ -4033,7 +4033,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
req3.setHeader("Range","bytes=0-49");
HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
resp3.setEntity(makeBody(128));
resp3.setEntity(HttpTestUtils.makeBody(128));
resp3.setHeader("Server","MockServer/1.0");
resp3.setHeader("Date", DateUtils.formatDate(now));
@ -4063,7 +4063,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
req1.setHeader("Accept-Encoding","gzip");
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag","\"etag1\"");
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Vary","Accept-Encoding");
@ -4073,7 +4073,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
req2.removeHeaders("Accept-Encoding");
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("ETag","\"etag1\"");
resp2.setHeader("Cache-Control","max-age=3600");
@ -4096,7 +4096,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testCannotServeFromCacheForVaryStar() throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag","\"etag1\"");
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Vary","*");
@ -4105,7 +4105,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("ETag","\"etag1\"");
resp2.setHeader("Cache-Control","max-age=3600");
@ -4147,7 +4147,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
req1.setHeader("User-Agent","MyBrowser/1.0");
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag","\"etag1\"");
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Vary","User-Agent");
@ -4162,7 +4162,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
conditional.setHeader("User-Agent","MyBrowser/1.5");
conditional.setHeader("If-None-Match","\"etag1\"");
HttpResponse resp200 = make200Response();
HttpResponse resp200 = HttpTestUtils.make200Response();
resp200.setHeader("ETag","\"etag1\"");
resp200.setHeader("Vary","User-Agent");
@ -4212,7 +4212,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
*/
@Test
public void testIncompleteResponseMustNotBeReturnedToClientWithoutMarkingItAs206() throws Exception {
originResponse.setEntity(makeBody(128));
originResponse.setEntity(HttpTestUtils.makeBody(128));
originResponse.setHeader("Content-Length","256");
backendExpectsAnyRequest().andReturn(originResponse);
@ -4243,7 +4243,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
protected void testUnsafeOperationInvalidatesCacheForThatUri(
HttpRequest unsafeReq) throws Exception, IOException {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","public, max-age=3600");
backendExpectsAnyRequest().andReturn(resp1);
@ -4253,7 +4253,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
backendExpectsAnyRequest().andReturn(resp2);
HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp3 = make200Response();
HttpResponse resp3 = HttpTestUtils.make200Response();
resp3.setHeader("Cache-Control","public, max-age=3600");
// this origin request MUST happen due to invalidation
@ -4287,7 +4287,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
protected void testUnsafeMethodInvalidatesCacheForHeaderUri(
HttpRequest unsafeReq) throws Exception, IOException {
HttpRequest req1 = new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","public, max-age=3600");
backendExpectsAnyRequest().andReturn(resp1);
@ -4297,7 +4297,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
backendExpectsAnyRequest().andReturn(resp2);
HttpRequest req3 = new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1);
HttpResponse resp3 = make200Response();
HttpResponse resp3 = HttpTestUtils.make200Response();
resp3.setHeader("Cache-Control","public, max-age=3600");
// this origin request MUST happen due to invalidation
@ -4393,7 +4393,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpHost otherHost = new HttpHost("bar.example.com");
HttpRequest req1 = new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","public, max-age=3600");
backendExpectsAnyRequest().andReturn(resp1);
@ -4501,7 +4501,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testPOSTRequestsAreWrittenThroughToOrigin()
throws Exception {
HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST","/",HttpVersion.HTTP_1_1);
req.setEntity(makeBody(128));
req.setEntity(HttpTestUtils.makeBody(128));
req.setHeader("Content-Length","128");
testRequestIsWrittenThroughToOrigin(req);
}
@ -4510,7 +4510,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testPUTRequestsAreWrittenThroughToOrigin()
throws Exception {
HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("PUT","/",HttpVersion.HTTP_1_1);
req.setEntity(makeBody(128));
req.setEntity(HttpTestUtils.makeBody(128));
req.setHeader("Content-Length","128");
testRequestIsWrittenThroughToOrigin(req);
}
@ -4621,7 +4621,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
backendExpectsAnyRequest().andReturn(authorizedResponse);
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("Cache-Control","max-age=3600");
if (maxTimes > 0) {
@ -4640,7 +4640,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testSharedCacheMustNotNormallyCacheAuthorizedResponses()
throws Exception {
HttpResponse resp = make200Response();
HttpResponse resp = HttpTestUtils.make200Response();
resp.setHeader("Cache-Control","max-age=3600");
resp.setHeader("ETag","\"etag\"");
testSharedCacheRevalidatesAuthorizedResponse(resp, 1, 1);
@ -4649,7 +4649,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testSharedCacheMayCacheAuthorizedResponsesWithSMaxAgeHeader()
throws Exception {
HttpResponse resp = make200Response();
HttpResponse resp = HttpTestUtils.make200Response();
resp.setHeader("Cache-Control","s-maxage=3600");
resp.setHeader("ETag","\"etag\"");
testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1);
@ -4658,7 +4658,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testSharedCacheMustRevalidateAuthorizedResponsesWhenSMaxAgeIsZero()
throws Exception {
HttpResponse resp = make200Response();
HttpResponse resp = HttpTestUtils.make200Response();
resp.setHeader("Cache-Control","s-maxage=0");
resp.setHeader("ETag","\"etag\"");
testSharedCacheRevalidatesAuthorizedResponse(resp, 1, 1);
@ -4667,7 +4667,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testSharedCacheMayCacheAuthorizedResponsesWithMustRevalidate()
throws Exception {
HttpResponse resp = make200Response();
HttpResponse resp = HttpTestUtils.make200Response();
resp.setHeader("Cache-Control","must-revalidate");
resp.setHeader("ETag","\"etag\"");
testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1);
@ -4676,7 +4676,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testSharedCacheMayCacheAuthorizedResponsesWithCacheControlPublic()
throws Exception {
HttpResponse resp = make200Response();
HttpResponse resp = HttpTestUtils.make200Response();
resp.setHeader("Cache-Control","public");
testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1);
}
@ -4696,7 +4696,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
req2.setHeader("Authorization",authorization2);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
Capture<HttpRequest> cap = new Capture<HttpRequest>();
EasyMock.expect(mockBackend.execute(EasyMock.eq(host),
@ -4720,7 +4720,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
throws Exception {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date",DateUtils.formatDate(tenSecondsAgo));
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("Cache-Control","s-maxage=5");
@ -4733,7 +4733,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
throws Exception {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date",DateUtils.formatDate(tenSecondsAgo));
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("Cache-Control","maxage=5, must-revalidate");
@ -4760,7 +4760,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
resp1.setHeader("Cache-Control","max-age=5");
resp1.setHeader("Etag","\"etag\"");
@ -4769,7 +4769,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
req2.setHeader("Cache-Control","max-stale=60");
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
Capture<HttpRequest> cap = new Capture<HttpRequest>();
EasyMock.expect(mockBackend.execute(EasyMock.eq(host),
@ -4840,13 +4840,13 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
protected void testCacheIsNotUsedWhenRespondingToRequest(HttpRequest req)
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Etag","\"etag\"");
resp1.setHeader("Cache-Control","max-age=3600");
backendExpectsAnyRequest().andReturn(resp1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("Etag","\"etag2\"");
resp2.setHeader("Cache-Control","max-age=1200");
@ -4899,7 +4899,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
req2.setHeader("Cache-Control","max-stale=3600");
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("ETag","\"etag2\"");
resp2.setHeader("Cache-Control","max-age=5, must-revalidate");
@ -4931,7 +4931,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testStaleEntryWithMustRevalidateIsNotUsedWithoutRevalidatingWithOrigin()
throws Exception {
HttpResponse response = make200Response();
HttpResponse response = HttpTestUtils.make200Response();
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
response.setHeader("Date",DateUtils.formatDate(tenSecondsAgo));
@ -4968,7 +4968,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
@Test
public void testGenerates504IfCannotRevalidateAMustRevalidateEntry()
throws Exception {
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
resp1.setHeader("ETag","\"etag\"");
@ -4988,7 +4988,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testStaleEntryWithProxyRevalidateOnSharedCacheIsNotUsedWithoutRevalidatingWithOrigin()
throws Exception {
if (impl.isSharedCache()) {
HttpResponse response = make200Response();
HttpResponse response = HttpTestUtils.make200Response();
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
response.setHeader("Date",DateUtils.formatDate(tenSecondsAgo));
@ -5003,7 +5003,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testGenerates504IfSharedCacheCannotRevalidateAProxyRevalidateEntry()
throws Exception {
if (impl.isSharedCache()) {
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
resp1.setHeader("ETag","\"etag\"");
@ -5025,13 +5025,13 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
throws Exception {
if (impl.isSharedCache()) {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","private,max-age=3600");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
// this backend request MUST happen
backendExpectsAnyRequest().andReturn(resp2);
@ -5047,14 +5047,14 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
throws Exception {
if (impl.isSharedCache()) {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("X-Personal","stuff");
resp1.setHeader("Cache-Control","private=\"X-Personal\",s-maxage=3600");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
// this backend request MAY happen
backendExpectsAnyRequest().andReturn(resp2).times(0,1);
@ -5079,14 +5079,14 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testNoCacheCannotSatisfyASubsequentRequestWithoutRevalidation()
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("Cache-Control","no-cache");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
// this MUST happen
backendExpectsAnyRequest().andReturn(resp2);
@ -5101,7 +5101,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testNoCacheCannotSatisfyASubsequentRequestWithoutRevalidationEvenWithContraryIndications()
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("Cache-Control","no-cache,s-maxage=3600");
@ -5109,7 +5109,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
req2.setHeader("Cache-Control","max-stale=7200");
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
// this MUST happen
backendExpectsAnyRequest().andReturn(resp2);
@ -5130,7 +5130,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testNoCacheOnFieldIsNotReturnedWithoutRevalidation()
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("X-Stuff","things");
resp1.setHeader("Cache-Control","no-cache=\"X-Stuff\", max-age=3600");
@ -5138,7 +5138,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("ETag","\"etag\"");
resp2.setHeader("X-Stuff","things");
resp2.setHeader("Cache-Control","no-cache=\"X-Stuff\",max-age=3600");
@ -5295,13 +5295,13 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testCacheDoesNotAssumeContentLocationHeaderIndicatesAnotherCacheableResource()
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","public,max-age=3600");
resp1.setHeader("Etag","\"etag\"");
resp1.setHeader("Content-Location","http://foo.example.com/bar");
HttpRequest req2 = new BasicHttpRequest("GET", "/bar", HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("Cache-Control","public,max-age=3600");
resp2.setHeader("Etag","\"etag\"");
@ -5345,13 +5345,13 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
private void testInvalidExpiresHeaderIsTreatedAsStale(
final String expiresHeader) throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","public");
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("Expires", expiresHeader);
HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
backendExpectsAnyRequest().andReturn(resp1);
// second request to origin MUST happen
@ -5384,13 +5384,13 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
public void testExpiresHeaderEqualToDateHeaderIsTreatedAsStale()
throws Exception {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","public");
resp1.setHeader("ETag","\"etag\"");
resp1.setHeader("Expires", resp1.getFirstHeader("Date").getValue());
HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp2 = make200Response();
HttpResponse resp2 = HttpTestUtils.make200Response();
backendExpectsAnyRequest().andReturn(resp1);
// second request to origin MUST happen
@ -5692,7 +5692,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Date now = new Date();
Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L);
HttpResponse resp1 = make200Response();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(twentySecondsAgo));
resp1.setHeader("Cache-Control","public,max-age=5");
resp1.setHeader("ETag", "\"etag1\"");

View File

@ -74,7 +74,7 @@ public class TestEhcacheProtocolRequirements extends TestProtocolRequirements{
request = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1);
originResponse = make200Response();
originResponse = HttpTestUtils.make200Response();
params = new CacheConfig();
params.setMaxObjectSizeBytes(MAX_BYTES);