HTTPCLIENT-1001: cacheEntryUpdater does not properly update cache entry resource

Contributed by Michajlo Matijkiw <michajlo_matijkiw at comcast.com>


git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1003455 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2010-10-01 09:49:15 +00:00
parent e5596fb025
commit 0b2189222b
6 changed files with 26 additions and 14 deletions

View File

@ -35,6 +35,7 @@ import java.util.ListIterator;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.annotation.Immutable;
import org.apache.http.client.cache.HeaderConstants;
import org.apache.http.client.cache.HttpCacheEntry;
@ -46,7 +47,7 @@ import org.apache.http.protocol.HTTP;
/**
* Update a {@link HttpCacheEntry} with new or updated information based on the latest
* 200 or 304 status responses from the Server. Use the {@link HttpResponse} to perform
* 304 status response from the Server. Use the {@link HttpResponse} to perform
* the update.
*
* @since 4.1
@ -66,7 +67,8 @@ class CacheEntryUpdater {
}
/**
* Update the entry with the new information from the response.
* Update the entry with the new information from the response. Should only be used for
* 304 responses.
*
* @param request id
* @param entry The cache Entry to be updated
@ -82,7 +84,8 @@ class CacheEntryUpdater {
Date requestDate,
Date responseDate,
HttpResponse response) throws IOException {
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_NOT_MODIFIED)
throw new IllegalArgumentException("Response must have 304 status code");
Header[] mergedHeaders = mergeHeaders(entry, response);
Resource resource = resourceFactory.copy(requestId, entry.getResource());
return new HttpCacheEntry(

View File

@ -147,7 +147,7 @@ class CachedResponseSuitabilityChecker {
}
if (HeaderConstants.CACHE_CONTROL_NO_STORE.equals(elt.getName())) {
log.debug("Response contained NO SORE directive, cache was not suitable");
log.debug("Response contained NO STORE directive, cache was not suitable");
return false;
}

View File

@ -558,13 +558,16 @@ public class CachingHttpClient implements HttpClient {
}
}
backendResponse.addHeader("Via", generateViaHeader(backendResponse));
int statusCode = backendResponse.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_NOT_MODIFIED || statusCode == HttpStatus.SC_OK) {
cacheUpdates.getAndIncrement();
setResponseStatus(context, CacheResponseStatus.VALIDATED);
return responseCache.updateCacheEntry(target, request, cacheEntry,
backendResponse, requestDate, responseDate);
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
return responseCache.updateCacheEntry(target, request, cacheEntry,
backendResponse, requestDate, responseDate);
}
}
return handleBackendResponse(target, conditionalRequest, requestDate, responseDate,

View File

@ -65,7 +65,7 @@ public class TestCacheEntryUpdater {
public void testUpdateCacheEntryReturnsDifferentEntryInstance() throws IOException {
HttpCacheEntry entry =HttpTestUtils.makeCacheEntry();
BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "");
HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry, requestDate, responseDate, response);
@ -162,7 +162,7 @@ public class TestCacheEntryUpdater {
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo);
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "");
HttpCacheEntry updated = impl.updateCacheEntry(null, entry, twoSecondsAgo, oneSecondAgo, response);

View File

@ -432,8 +432,10 @@ public class TestCachingHttpClient {
getCurrentDateReturns(requestDate);
backendCall(validate, originResponse);
getCurrentDateReturns(responseDate);
EasyMock.expect(mockCache.updateCacheEntry(host, request,
entry, originResponse, requestDate, responseDate))
responsePolicyAllowsCaching(true);
responseProtocolValidationIsCalled();
EasyMock.expect(mockCache.getCacheEntry(host, validate)).andReturn(null);
EasyMock.expect(mockCache.cacheAndReturnResponse(host, validate, originResponse, requestDate, responseDate))
.andReturn(finalResponse);
replayMocks();
@ -484,8 +486,10 @@ public class TestCachingHttpClient {
final Date responseDate2 = new Date();
getCurrentDateReturns(responseDate2);
EasyMock.expect(mockCache.updateCacheEntry(host, request,
entry, originResponse2, requestDate2, responseDate2))
responsePolicyAllowsCaching(true);
responseProtocolValidationIsCalled();
EasyMock.expect(mockCache.getCacheEntry(host, validate)).andReturn(null);
EasyMock.expect(mockCache.cacheAndReturnResponse(host, validate, originResponse2, requestDate2, responseDate2))
.andReturn(finalResponse);
replayMocks();

View File

@ -2592,9 +2592,11 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
EasyMock.expect(
mockBackend.execute(EasyMock.isA(HttpHost.class), EasyMock.capture(cap),
(HttpContext) EasyMock.isNull())).andReturn(validated).times(0, 1);
EasyMock.expect(mockCache.updateCacheEntry(EasyMock.same(host), EasyMock.same(request), EasyMock.same(entry),
EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
.andReturn(entry).times(0, 1);
EasyMock.expect(mockCache.cacheAndReturnResponse(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class),
EasyMock.same(validated), EasyMock.isA(Date.class), EasyMock.isA(Date.class)))
.andReturn(reconstructed).times(0, 1);
.andReturn(reconstructed).times(0, 1);
replayMocks();
HttpResponse result = impl.execute(host, request);