TABS -> SPACES

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1172301 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2011-09-18 16:20:20 +00:00
parent f5cb5f9e19
commit e5ea32b76d
82 changed files with 652 additions and 654 deletions

View File

@ -28,7 +28,7 @@ package org.apache.http.client.cache;
/**
* This enumeration represents the various ways a response can be generated
* by the {@link org.apache.http.impl.client.cache.CachingHttpClient};
* by the {@link org.apache.http.impl.client.cache.CachingHttpClient};
* if a request is executed with an {@link org.apache.http.protocol.HttpContext}
* then a parameter with one of these values will be registered in the
* context under the key

View File

@ -110,7 +110,7 @@ public class HttpCacheEntry implements Serializable {
? new HashMap<String,String>(variantMap)
: null;
}
/**
* Create a new {@link HttpCacheEntry}.
*
@ -207,7 +207,7 @@ public class HttpCacheEntry implements Serializable {
public Resource getResource() {
return this.resource;
}
/**
* Indicates whether the origin response indicated the associated
* resource had variants (i.e. that the Vary header was set on the

View File

@ -33,7 +33,7 @@ import java.io.OutputStream;
/**
* Used by some {@link HttpCacheStorage} implementations to serialize
* {@link HttpCacheEntry} instances to a byte representation before
* storage.
* storage.
*/
public interface HttpCacheEntrySerializer {

View File

@ -33,7 +33,7 @@ import java.io.IOException;
* interface. They can then be plugged into the existing
* {@link org.apache.http.impl.client.cache.CachingHttpClient}
* implementation.
*
*
* @since 4.1
*/
public interface HttpCacheStorage {
@ -68,7 +68,7 @@ public interface HttpCacheStorage {
* Atomically applies the given callback to update an existing cache
* entry under a given key.
* @param key indicates which entry to modify
* @param callback performs the update; see
* @param callback performs the update; see
* {@link HttpCacheUpdateCallback} for details, but roughly the
* callback expects to be handed the current entry and will return
* the new value for the entry.

View File

@ -49,4 +49,4 @@ public interface HttpCacheUpdateCallback {
*/
HttpCacheEntry update(HttpCacheEntry existing) throws IOException;
}
}

View File

@ -45,4 +45,4 @@ public class HttpCacheUpdateException extends Exception {
initCause(cause);
}
}
}

View File

@ -31,7 +31,7 @@ import org.apache.http.annotation.NotThreadSafe;
/**
* Used to limiting the size of an incoming response body of
* unknown size that is optimistically being read in anticipation
* of caching it.
* of caching it.
* @since 4.1
*/
@NotThreadSafe // reached

View File

@ -12,7 +12,7 @@ to you under the Apache License, Version 2.0 (the
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -51,7 +51,7 @@ the {@code CachingHttpClient} to indicate how the request was
processed by the caching module itself.
</p>
<p>
New storage backends will need to implement the
New storage backends will need to implement the
{@link org.apache.http.client.cache.HttpCacheStorage}
interface; they can then be passed to one of the {@code CachingHttpClient}
constructors, which will happily make use of the new storage mechanism.

View File

@ -37,7 +37,7 @@ import org.apache.http.protocol.HttpContext;
/**
* Class used to represent an asynchronous revalidation event, such as with
* "stale-while-revalidate"
* "stale-while-revalidate"
*/
class AsynchronousValidationRequest implements Runnable {
private final AsynchronousValidator parent;
@ -47,12 +47,12 @@ class AsynchronousValidationRequest implements Runnable {
private final HttpContext context;
private final HttpCacheEntry cacheEntry;
private final String identifier;
private final Log log = LogFactory.getLog(getClass());
/**
* Used internally by {@link AsynchronousValidator} to schedule a
* revalidation.
* revalidation.
* @param cachingClient
* @param target
* @param request
@ -74,7 +74,7 @@ class AsynchronousValidationRequest implements Runnable {
this.cacheEntry = cacheEntry;
this.identifier = identifier;
}
public void run() {
try {
cachingClient.revalidateCacheEntry(target, request, context, cacheEntry);
@ -90,5 +90,5 @@ class AsynchronousValidationRequest implements Runnable {
String getIdentifier() {
return identifier;
}
}

View File

@ -51,20 +51,20 @@ class AsynchronousValidator {
private final ExecutorService executor;
private final Set<String> queued;
private final CacheKeyGenerator cacheKeyGenerator;
private final Log log = LogFactory.getLog(getClass());
/**
* Create AsynchronousValidator which will make revalidation requests
* using the supplied {@link CachingHttpClient}, and
* using the supplied {@link CachingHttpClient}, and
* a {@link ThreadPoolExecutor} generated according to the thread
* pool settings provided in the given {@link CacheConfig}.
* pool settings provided in the given {@link CacheConfig}.
* @param cachingClient used to execute asynchronous requests
* @param config specifies thread pool settings. See
* {@link CacheConfig#getAsynchronousWorkersMax()},
* {@link CacheConfig#getAsynchronousWorkersCore()},
* {@link CacheConfig#getAsynchronousWorkerIdleLifetimeSecs()},
* and {@link CacheConfig#getRevalidationQueueSize()}.
* and {@link CacheConfig#getRevalidationQueueSize()}.
*/
public AsynchronousValidator(CachingHttpClient cachingClient,
CacheConfig config) {
@ -76,7 +76,7 @@ class AsynchronousValidator {
new ArrayBlockingQueue<Runnable>(config.getRevalidationQueueSize()))
);
}
/**
* Create AsynchronousValidator which will make revalidation requests
* using the supplied {@link CachingHttpClient} and
@ -91,10 +91,10 @@ class AsynchronousValidator {
this.queued = new HashSet<String>();
this.cacheKeyGenerator = new CacheKeyGenerator();
}
/**
* Schedules an asynchronous revalidation
*
*
* @param target
* @param request
* @param context
@ -104,7 +104,7 @@ class AsynchronousValidator {
HttpRequest request, HttpContext context, HttpCacheEntry entry) {
// getVariantURI will fall back on getURI if no variants exist
String uri = cacheKeyGenerator.getVariantURI(target, request, entry);
if (!queued.contains(uri)) {
AsynchronousValidationRequest revalidationRequest =
new AsynchronousValidationRequest(this, cachingClient, target,
@ -121,7 +121,7 @@ class AsynchronousValidator {
/**
* Removes an identifier from the internal list of revalidation jobs in
* progress. This is meant to be called by
* progress. This is meant to be called by
* {@link AsynchronousValidationRequest#run()} once the revalidation is
* complete, using the identifier passed in during constructions.
* @param identifier
@ -129,11 +129,11 @@ class AsynchronousValidator {
synchronized void markComplete(String identifier) {
queued.remove(identifier);
}
Set<String> getScheduledIdentifiers() {
return Collections.unmodifiableSet(queued);
}
ExecutorService getExecutor() {
return executor;
}

View File

@ -83,7 +83,7 @@ class BasicHttpCache implements HttpCache {
String uri = uriExtractor.getURI(host, request);
storage.removeEntry(uri);
}
public void flushInvalidatedCacheEntriesFor(HttpHost host, HttpRequest request, HttpResponse response) {
cacheInvalidator.flushInvalidatedCacheEntries(host, request, response);
}
@ -193,7 +193,7 @@ class BasicHttpCache implements HttpCache {
if (src == null) {
src = entry;
}
Resource resource = resourceFactory.copy(requestId, src.getResource());
Map<String,String> variantMap = new HashMap<String,String>(src.getVariantMap());
variantMap.put(variantKey, variantCacheKey);
@ -231,7 +231,7 @@ class BasicHttpCache implements HttpCache {
storage.putEntry(cacheKey, updatedEntry);
return updatedEntry;
}
public HttpResponse cacheAndReturnResponse(HttpHost host, HttpRequest request,
HttpResponse originResponse, Date requestSent, Date responseReceived)
throws IOException {
@ -300,4 +300,4 @@ class BasicHttpCache implements HttpCache {
variants.put(etagHeader.getValue(), new Variant(variantKey, variantCacheKey, entry));
}
}
}

View File

@ -82,4 +82,4 @@ class BasicIdGenerator {
return buffer.toString();
}
}
}

View File

@ -33,19 +33,19 @@ package org.apache.http.impl.client.cache;
* {@code CacheConfig} instance has sane and conservative defaults, so the
* easiest way to specify options is to get an instance and then set just
* the options you want to modify from their defaults.</p>
*
*
* <p><b>N.B.</b> This class is only for caching-specific configuration; to
* configure the behavior of the rest of the client, configure the
* configure the behavior of the rest of the client, configure the
* {@link org.apache.http.client.HttpClient} used as the &quot;backend&quot;
* for the {@code CachingHttpClient}.</p>
*
*
* <p>Cache configuration can be grouped into the following categories:</p>
*
*
* <p><b>Cache size.</b> If the backend storage supports these limits, you
* can specify the {@link CacheConfig#setMaxCacheEntries maximum number of
* cache entries} as well as the {@link CacheConfig#setMaxObjectSizeBytes
* maximum cacheable response body size}.</p>
*
*
* <p><b>Public/private caching.</b> By default, the caching module considers
* itself to be a shared (public) cache, and will not, for example, cache
* responses to requests with {@code Authorization} headers or responses
@ -53,7 +53,7 @@ package org.apache.http.impl.client.cache;
* is only going to be used by one logical "user" (behaving similarly to a
* browser cache), then you will want to {@link
* CacheConfig#setSharedCache(boolean) turn off the shared cache setting}.</p>
*
*
* <p><b>Heuristic caching</b>. Per RFC2616, a cache may cache certain cache
* entries even if no explicit cache control headers are set by the origin.
* This behavior is off by default, but you may want to turn this on if you
@ -67,7 +67,7 @@ package org.apache.http.impl.client.cache;
* <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.2">
* 13.2.2</a> and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.4">
* 13.2.4</a> of the HTTP/1.1 RFC for more details on heuristic caching.</p>
*
*
* <p><b>Background validation</b>. The cache module supports the
* {@code stale-while-revalidate} directive of
* <a href="http://tools.ietf.org/html/rfc5861">RFC5861</a>, which allows
@ -79,7 +79,7 @@ package org.apache.http.impl.client.cache;
* CacheConfig#setAsynchronousWorkerIdleLifetimeSecs(int) maximum time they
* can be idle before being reclaimed}. You can also control the {@link
* CacheConfig#setRevalidationQueueSize(int) size of the queue} used for
* revalidations when there aren't enough workers to keep up with demand.</b>
* revalidations when there aren't enough workers to keep up with demand.</b>
*/
public class CacheConfig {
@ -115,22 +115,22 @@ public class CacheConfig {
/** Default number of worker threads to allow for background revalidations
* resulting from the stale-while-revalidate directive.
*/
public static final int DEFAULT_ASYNCHRONOUS_WORKERS_MAX = 1;
public static final int DEFAULT_ASYNCHRONOUS_WORKERS_MAX = 1;
/** Default minimum number of worker threads to allow for background
* revalidations resulting from the stale-while-revalidate directive.
*/
public static final int DEFAULT_ASYNCHRONOUS_WORKERS_CORE = 1;
/** Default maximum idle lifetime for a background revalidation thread
* before it gets reclaimed.
*/
public static final int DEFAULT_ASYNCHRONOUS_WORKER_IDLE_LIFETIME_SECS = 60;
/** Default maximum queue length for background revalidation requests.
/** Default maximum queue length for background revalidation requests.
*/
public static final int DEFAULT_REVALIDATION_QUEUE_SIZE = 100;
private int maxObjectSizeBytes = DEFAULT_MAX_OBJECT_SIZE_BYTES;
private int maxCacheEntries = DEFAULT_MAX_CACHE_ENTRIES;
private int maxUpdateRetries = DEFAULT_MAX_UPDATE_RETRIES;
@ -236,7 +236,7 @@ public class CacheConfig {
* and {@code Date} headers of a cached response during which the cached
* response will be considered heuristically fresh.
* @param heuristicCoefficient should be between {@code 0.0} and
* {@code 1.0}.
* {@code 1.0}.
*/
public void setHeuristicCoefficient(float heuristicCoefficient) {
this.heuristicCoefficient = heuristicCoefficient;
@ -255,7 +255,7 @@ public class CacheConfig {
* calculation is not possible. Explicit cache control directives on
* either the request or origin response will override this, as will
* the heuristic {@code Last-Modified} freshness calculation if it is
* available.
* available.
* @param heuristicDefaultLifetimeSecs is the number of seconds to
* consider a cache-eligible response fresh in the absence of other
* information. Set this to {@code 0} to disable this style of
@ -276,9 +276,9 @@ public class CacheConfig {
/**
* Sets the maximum number of threads to allow for background
* revalidations due to the {@code stale-while-revalidate} directive.
* revalidations due to the {@code stale-while-revalidate} directive.
* @param max number of threads; a value of 0 disables background
* revalidations.
* revalidations.
*/
public void setAsynchronousWorkersMax(int max) {
this.asynchronousWorkersMax = max;
@ -286,7 +286,7 @@ public class CacheConfig {
/**
* Returns the minimum number of threads to keep alive for background
* revalidations due to the {@code stale-while-revalidate} directive.
* revalidations due to the {@code stale-while-revalidate} directive.
*/
public int getAsynchronousWorkersCore() {
return asynchronousWorkersCore;
@ -296,7 +296,7 @@ public class CacheConfig {
* Sets the minimum number of threads to keep alive for background
* revalidations due to the {@code stale-while-revalidate} directive.
* @param min should be greater than zero and less than or equal
* to <code>getAsynchronousWorkersMax()</code>
* to <code>getAsynchronousWorkersMax()</code>
*/
public void setAsynchronousWorkersCore(int min) {
this.asynchronousWorkersCore = min;
@ -337,5 +337,5 @@ public class CacheConfig {
this.revalidationQueueSize = size;
}
}

View File

@ -172,7 +172,7 @@ class CacheInvalidator {
}
return relURL;
}
protected boolean requestShouldNotBeCached(HttpRequest req) {
String method = req.getRequestLine().getMethod();
return notGetOrHeadRequest(method);
@ -184,7 +184,7 @@ class CacheInvalidator {
}
/** Flushes entries that were invalidated by the given response
* received for the given host/request pair.
* received for the given host/request pair.
*/
public void flushInvalidatedCacheEntries(HttpHost host,
HttpRequest request, HttpResponse response) {
@ -200,7 +200,7 @@ class CacheInvalidator {
if (!responseDateNewerThanEntryDate(response, entry)) return;
if (!responseAndEntryEtagsDiffer(response, entry)) return;
flushUriIfSameHost(reqURL, canonURL);
}
@ -210,7 +210,7 @@ class CacheInvalidator {
String contentLocation = clHeader.getValue();
URL canonURL = getAbsoluteURL(contentLocation);
if (canonURL != null) return canonURL;
return getRelativeURL(reqURL, contentLocation);
return getRelativeURL(reqURL, contentLocation);
}
private boolean responseAndEntryEtagsDiffer(HttpResponse response,

View File

@ -144,7 +144,7 @@ class CacheKeyGenerator {
* Compute a "variant key" from the headers of a given request that are
* covered by the Vary header of a given cache entry. Any request whose
* varying headers match those of this request should have the same
* variant key.
* variant key.
* @param req originating request
* @param entry cache entry in question that has variants
* @return a <code>String</code> variant key
@ -179,4 +179,4 @@ class CacheKeyGenerator {
return buf.toString();
}
}
}

View File

@ -47,4 +47,4 @@ final class CacheMap extends LinkedHashMap<String, HttpCacheEntry> {
return size() > this.maxEntries;
}
}
}

View File

@ -119,7 +119,7 @@ class CacheValidityPolicy {
public boolean proxyRevalidate(final HttpCacheEntry entry) {
return hasCacheControlDirective(entry, "proxy-revalidate");
}
public boolean mayReturnStaleWhileRevalidating(final HttpCacheEntry entry, Date now) {
for (Header h : entry.getHeaders("Cache-Control")) {
for(HeaderElement elt : h.getElements()) {
@ -135,10 +135,10 @@ class CacheValidityPolicy {
}
}
}
return false;
}
public boolean mayReturnStaleIfError(HttpRequest request,
HttpCacheEntry entry, Date now) {
long stalenessSecs = getStalenessSecs(entry, now);
@ -147,7 +147,7 @@ class CacheValidityPolicy {
|| mayReturnStaleIfError(entry.getHeaders("Cache-Control"),
stalenessSecs);
}
private boolean mayReturnStaleIfError(Header[] headers, long stalenessSecs) {
boolean result = false;
for(Header h : headers) {
@ -206,8 +206,8 @@ class CacheValidityPolicy {
protected boolean hasContentLengthHeader(HttpCacheEntry entry) {
return null != entry.getFirstHeader(HTTP.CONTENT_LEN);
}
}
/**
* This matters for deciding whether the cache entry is valid to serve as a
* response. If these values do not match, we might have a partial response

View File

@ -79,7 +79,7 @@ import org.apache.http.util.VersionInfo;
* related configuration you want to do vis-a-vis timeouts and connection
* pools should be done on this backend client before constructing a {@code
* CachingHttpClient} from it.</p>
*
*
* <p>Generally speaking, the {@code CachingHttpClient} is implemented as a
* <a href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</a>
* of the backend client; for any incoming request it attempts to satisfy
@ -92,7 +92,7 @@ import org.apache.http.util.VersionInfo;
* This notion of "semantic transparency" means you should be able to drop
* a {@link CachingHttpClient} into an existing application without breaking
* anything.</p>
*
*
* <p>Folks that would like to experiment with alternative storage backends
* should look at the {@link HttpCacheStorage} interface and the related
* package documentation there. You may also be interested in the provided
@ -137,7 +137,7 @@ public class CachingHttpClient implements HttpClient {
private final RequestProtocolCompliance requestCompliance;
private final AsynchronousValidator asynchRevalidator;
private final Log log = LogFactory.getLog(getClass());
CachingHttpClient(
@ -226,7 +226,7 @@ public class CachingHttpClient implements HttpClient {
* response bodies are managed using the given {@link ResourceFactory}.
* @param client used to make origin requests
* @param resourceFactory how to manage cached response bodies
* @param storage where to store cache entries
* @param storage where to store cache entries
* @param config cache module options
*/
public CachingHttpClient(
@ -244,7 +244,7 @@ public class CachingHttpClient implements HttpClient {
* that stores cache entries in the provided storage backend and uses
* the given {@link HttpClient} for backend requests.
* @param client used to make origin requests
* @param storage where to store cache entries
* @param storage where to store cache entries
* @param config cache module options
*/
public CachingHttpClient(
@ -282,7 +282,7 @@ public class CachingHttpClient implements HttpClient {
this.requestCompliance = requestCompliance;
this.asynchRevalidator = makeAsynchronousValidator(config);
}
private AsynchronousValidator makeAsynchronousValidator(
CacheConfig config) {
if (config.getAsynchronousWorkersMax() > 0) {
@ -292,7 +292,7 @@ public class CachingHttpClient implements HttpClient {
}
/**
* Reports the number of times that the cache successfully responded
* Reports the number of times that the cache successfully responded
* to an {@link HttpRequest} without contacting the origin server.
* @return the number of cache hits
*/
@ -395,7 +395,7 @@ public class CachingHttpClient implements HttpClient {
return handleCacheMiss(target, request, context);
}
return handleCacheHit(target, request, context, entry);
return handleCacheHit(target, request, context, entry);
}
private HttpResponse handleCacheHit(HttpHost target, HttpRequest request,
@ -428,9 +428,9 @@ public class CachingHttpClient implements HttpClient {
&& !staleResponseNotAllowed(request, entry, now)
&& validityPolicy.mayReturnStaleWhileRevalidating(entry, now)) {
final HttpResponse resp = generateCachedResponse(request, context, entry, now);
asynchRevalidator.revalidateCacheEntry(target, request, context, entry);
return resp;
}
return revalidateCacheEntry(target, request, context, entry);
@ -468,12 +468,12 @@ public class CachingHttpClient implements HttpClient {
}
return entry;
}
private HttpResponse getFatallyNoncompliantResponse(HttpRequest request,
HttpContext context) {
HttpResponse fatalErrorResponse = null;
List<RequestProtocolError> fatalError = requestCompliance.requestIsFatallyNonCompliant(request);
for (RequestProtocolError error : fatalError) {
setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE);
fatalErrorResponse = requestCompliance.getErrorForRequest(error);
@ -507,7 +507,7 @@ public class CachingHttpClient implements HttpClient {
log.trace("Cache hit [host: " + target + "; uri: " + rl.getUri() + "]");
}
}
private void recordCacheUpdate(HttpContext context) {
cacheUpdates.getAndIncrement();
setResponseStatus(context, CacheResponseStatus.VALIDATED);
@ -599,7 +599,7 @@ public class CachingHttpClient implements HttpClient {
}
return false;
}
private String generateViaHeader(HttpMessage msg) {
final VersionInfo vi = VersionInfo.loadVersionInfo("org.apache.http.client", getClass().getClassLoader());
final String release = (vi != null) ? vi.getRelease() : VersionInfo.UNAVAILABLE;
@ -690,7 +690,7 @@ public class CachingHttpClient implements HttpClient {
}
return false;
}
HttpResponse negotiateResponseFromVariants(HttpHost target,
HttpRequest request, HttpContext context,
Map<String, Variant> variants) throws IOException {
@ -720,12 +720,12 @@ public class CachingHttpClient implements HttpClient {
}
HttpCacheEntry matchedEntry = matchingVariant.getEntry();
if (revalidationResponseIsTooOld(backendResponse, matchedEntry)) {
return retryRequestUnconditionally(target, request, context,
matchedEntry);
}
recordCacheUpdate(context);
HttpCacheEntry responseEntry = getUpdatedVariantEntry(target,
@ -815,13 +815,13 @@ public class CachingHttpClient implements HttpClient {
}
return responseGenerator.generateResponse(updatedEntry);
}
if (staleIfErrorAppliesTo(statusCode)
&& !staleResponseNotAllowed(request, cacheEntry, getCurrentDate())
&& validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
final HttpResponse cachedResponse = responseGenerator.generateResponse(cacheEntry);
cachedResponse.addHeader(HeaderConstants.WARNING, "110 localhost \"Response is stale\"");
return cachedResponse;
return cachedResponse;
}
return handleBackendResponse(target, conditionalRequest, requestDate, responseDate,
@ -829,9 +829,9 @@ public class CachingHttpClient implements HttpClient {
}
private boolean staleIfErrorAppliesTo(int statusCode) {
return statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR
|| statusCode == HttpStatus.SC_BAD_GATEWAY
|| statusCode == HttpStatus.SC_SERVICE_UNAVAILABLE
return statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR
|| statusCode == HttpStatus.SC_BAD_GATEWAY
|| statusCode == HttpStatus.SC_SERVICE_UNAVAILABLE
|| statusCode == HttpStatus.SC_GATEWAY_TIMEOUT;
}

View File

@ -46,7 +46,7 @@ import org.apache.http.impl.client.RequestWrapper;
class ConditionalRequestBuilder {
private static final Log log = LogFactory.getLog(ConditionalRequestBuilder.class);
/**
* When a {@link HttpCacheEntry} is stale but 'might' be used as a response
* to an {@link HttpRequest} we will attempt to revalidate the entry with
@ -117,7 +117,7 @@ class ConditionalRequestBuilder {
first = false;
etags.append(etag);
}
wrapperRequest.setHeader(HeaderConstants.IF_NONE_MATCH, etags.toString());
return wrapperRequest;
}
@ -134,7 +134,7 @@ class ConditionalRequestBuilder {
* @return an unconditional validation request
*/
public HttpRequest buildUnconditionalRequest(HttpRequest request,
HttpCacheEntry entry) {
HttpCacheEntry entry) {
RequestWrapper wrapped;
try {
wrapped = new RequestWrapper(request);

View File

@ -56,9 +56,9 @@ interface HttpCache {
*/
void flushInvalidatedCacheEntriesFor(HttpHost host, HttpRequest request)
throws IOException;
/** Clear any entries that may be invalidated by the given response to
* a particular request.
* a particular request.
* @param host
* @param request
* @param response
@ -122,7 +122,7 @@ interface HttpCache {
* Update a specific {@link HttpCacheEntry} representing a cached variant
* using a 304 {@link HttpResponse}.
* @param target host for client request
* @param request actual request from upstream client
* @param request actual request from upstream client
* @param stale current variant cache entry
* @param originResponse 304 response received from origin
* @param requestSent when the validating request was sent

View File

@ -96,7 +96,7 @@ class RequestProtocolCompliance {
*/
public HttpRequest makeRequestCompliant(HttpRequest request)
throws ClientProtocolException {
if (requestMustNotHaveEntity(request)) {
((HttpEntityEnclosingRequest) request).setEntity(null);
}
@ -116,7 +116,7 @@ class RequestProtocolCompliance {
return request;
}
private void stripOtherFreshnessDirectivesWithNoCache(HttpRequest request) {
List<HeaderElement> outElts = new ArrayList<HeaderElement>();
boolean shouldStrip = false;

View File

@ -198,13 +198,13 @@ class ResponseCachingPolicy {
log.debug("Response was not cacheable.");
return false;
}
String[] uncacheableRequestDirectives = { "no-store" };
if (hasCacheControlParameterFrom(request,uncacheableRequestDirectives)) {
return false;
}
if (request.getRequestLine().getUri().contains("?") &&
if (request.getRequestLine().getUri().contains("?") &&
(!isExplicitlyCacheable(response) || from1_0Origin(response))) {
log.debug("Response was not cacheable.");
return false;
@ -213,7 +213,7 @@ class ResponseCachingPolicy {
if (expiresHeaderLessOrEqualToDateHeaderAndNoCacheControl(response)) {
return false;
}
if (sharedCache) {
Header[] authNHeaders = request.getHeaders("Authorization");
if (authNHeaders != null && authNHeaders.length > 0) {
@ -249,7 +249,7 @@ class ResponseCachingPolicy {
for(HeaderElement elt : via.getElements()) {
String proto = elt.toString().split("\\s")[0];
if (proto.contains("/")) {
return proto.equals("HTTP/1.0");
return proto.equals("HTTP/1.0");
} else {
return proto.equals("1.0");
}

View File

@ -67,7 +67,7 @@ class ResponseProtocolCompliance {
*
* @param request The {@link HttpRequest} that generated an origin hit and response
* @param response The {@link HttpResponse} from the origin server
* @throws IOException
* @throws IOException
*/
public void ensureProtocolCompliance(HttpRequest request, HttpResponse response)
throws IOException {
@ -85,7 +85,7 @@ class ResponseProtocolCompliance {
ensure200ForOPTIONSRequestWithNoBodyHasContentLengthZero(request, response);
ensure206ContainsDateHeader(response);
ensure304DoesNotContainExtraEntityHeaders(response);
identityIsNotUsedInContentEncoding(response);
@ -167,9 +167,9 @@ class ResponseProtocolCompliance {
private void ensurePartialContentIsNotSentToAClientThatDidNotRequestIt(HttpRequest request,
HttpResponse response) throws IOException {
if (request.getFirstHeader(HeaderConstants.RANGE) != null
|| response.getStatusLine().getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT)
|| response.getStatusLine().getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT)
return;
consumeBody(response);
throw new ClientProtocolException(UNEXPECTED_PARTIAL_CONTENT);
}
@ -213,8 +213,8 @@ class ResponseProtocolCompliance {
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CONTINUE) {
return;
}
HttpRequest originalRequest = requestWasWrapped(request) ?
HttpRequest originalRequest = requestWasWrapped(request) ?
((RequestWrapper)request).getOriginal() : request;
if (originalRequest instanceof HttpEntityEnclosingRequest) {
if (((HttpEntityEnclosingRequest)originalRequest).expectContinue()) return;

View File

@ -44,11 +44,11 @@ class Variant {
public String getVariantKey() {
return variantKey;
}
public String getCacheKey() {
return cacheKey;
}
public HttpCacheEntry getEntry() {
return entry;
}

View File

@ -47,12 +47,12 @@ import org.apache.http.impl.client.cache.DefaultHttpCacheEntrySerializer;
* In particular, this backend allows for spillover to disk, where the
* cache can be effectively larger than memory, and cached responses are
* paged into and out of memory from disk as needed.</p>
*
*
* <p><b>N.B.</b> Since the Ehcache is configured ahead of time with a
* maximum number of cache entries, this effectively ignores the
* {@link CacheConfig#setMaxCacheEntries(int) maximum cache entries}
* specified by a provided {@link CacheConfig}.</p>
*
*
* <p>Please refer to the <a href="http://ehcache.org/documentation/index.html">
* Ehcache documentation</a> for details on how to configure the Ehcache
* itself.</p>
@ -154,4 +154,4 @@ public class EhcacheHttpCacheStorage implements HttpCacheStorage {
}while(numRetries <= maxUpdateRetries);
throw new HttpCacheUpdateException("Failed to update");
}
}
}

View File

@ -12,7 +12,7 @@ to you under the Apache License, Version 2.0 (the
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -31,7 +31,7 @@ information on the Apache Software Foundation, please see
<p>
This package contains a storage backend based on
<a href="http://ehcache.org/">Ehcache</a>
<a href="http://ehcache.org/">Ehcache</a>
that can be plugged into
a {@link org.apache.http.impl.client.cache.CachingHttpClient} and
used for storing cache entries.

View File

@ -58,18 +58,18 @@ import org.apache.http.impl.client.cache.DefaultHttpCacheEntrySerializer;
* peering of a sort</li>
* </ol>
* Note that in a shared memcached pool setting you may wish to make use
* of the Ketama consistent hashing algorithm to reduce the number of
* of the Ketama consistent hashing algorithm to reduce the number of
* cache misses that might result if one of the memcached cluster members
* fails (see the <a href="http://dustin.github.com/java-memcached-client/apidocs/net/spy/memcached/KetamaConnectionFactory.html">
* KetamaConnectionFactory</a>).
* </p>
*
*
* <p>Please refer to the <a href="http://code.google.com/p/memcached/wiki/NewStart">
* memcached documentation</a> and in particular to the documentation for
* the <a href="http://code.google.com/p/spymemcached/">spymemcached
* documentation</a> for details about how to set up and configure memcached
* and the Java client used here, respectively.</p>
*
*
* @since 4.1
*/
public class MemcachedHttpCacheStorage implements HttpCacheStorage {
@ -166,4 +166,4 @@ public class MemcachedHttpCacheStorage implements HttpCacheStorage {
} while(numRetries <= maxUpdateRetries);
throw new HttpCacheUpdateException("Failed to update");
}
}
}

View File

@ -12,7 +12,7 @@ to you under the Apache License, Version 2.0 (the
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -31,7 +31,7 @@ information on the Apache Software Foundation, please see
<p>
This package contains a storage backend based on
<a href="http://memcached.org/">memcached</a>
<a href="http://memcached.org/">memcached</a>
that can be plugged into
a {@link org.apache.http.impl.client.cache.CachingHttpClient} and
used for storing cache entries.

View File

@ -12,7 +12,7 @@ to you under the Apache License, Version 2.0 (the
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

View File

@ -199,21 +199,21 @@ public class TestHttpCacheEntry {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource);
assertSame(statusLine.getProtocolVersion(),
entry.getProtocolVersion());
entry.getProtocolVersion());
}
@Test
public void reasonPhraseComesFromOriginalStatusLine() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource);
assertSame(statusLine.getReasonPhrase(), entry.getReasonPhrase());
assertSame(statusLine.getReasonPhrase(), entry.getReasonPhrase());
}
@Test
public void statusCodeComesFromOriginalStatusLine() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource);
assertEquals(statusLine.getStatusCode(), entry.getStatusCode());
assertEquals(statusLine.getStatusCode(), entry.getStatusCode());
}
@Test
@ -221,7 +221,7 @@ public class TestHttpCacheEntry {
final Date requestDate = new Date();
entry = new HttpCacheEntry(requestDate, new Date(), statusLine,
new Header[]{}, mockResource);
assertSame(requestDate, entry.getRequestDate());
assertSame(requestDate, entry.getRequestDate());
}
@Test
@ -229,14 +229,14 @@ public class TestHttpCacheEntry {
final Date responseDate = new Date();
entry = new HttpCacheEntry(new Date(), responseDate, statusLine,
new Header[]{}, mockResource);
assertSame(responseDate, entry.getResponseDate());
assertSame(responseDate, entry.getResponseDate());
}
@Test
public void canGetOriginalResource() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
new Header[]{}, mockResource);
assertSame(mockResource, entry.getResource());
assertSame(mockResource, entry.getResource());
}
@Test
@ -253,7 +253,7 @@ public class TestHttpCacheEntry {
assertEquals(headers[i], result[i]);
}
}
@Test
public void canConstructWithoutVariants() {
new HttpCacheEntry(new Date(), new Date(), statusLine,
@ -266,7 +266,7 @@ public class TestHttpCacheEntry {
new Header[]{}, mockResource,
new HashMap<String,String>());
}
@Test
public void canRetrieveOriginalVariantMap() {
Map<String,String> variantMap = new HashMap<String,String>();
@ -280,7 +280,7 @@ public class TestHttpCacheEntry {
assertEquals("B", result.get("A"));
assertEquals("D", result.get("C"));
}
@Test
public void retrievedVariantMapIsNotModifiable() {
Map<String,String> variantMap = new HashMap<String,String>();
@ -301,7 +301,7 @@ public class TestHttpCacheEntry {
} catch (UnsupportedOperationException expected) {
}
}
@Test
public void canConvertToString() {
entry = new HttpCacheEntry(new Date(), new Date(), statusLine,

View File

@ -113,7 +113,7 @@ public abstract class AbstractProtocolTest {
mockCache.flushInvalidatedCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
EasyMock.expectLastCall().anyTimes();
mockCache.flushInvalidatedCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class), EasyMock.isA(HttpResponse.class));
EasyMock.expectLastCall().anyTimes();
}
@ -127,4 +127,4 @@ public abstract class AbstractProtocolTest {
super();
}
}
}

View File

@ -38,4 +38,4 @@ public class Counter {
return count;
}
}
}

View File

@ -76,11 +76,11 @@ public class HttpTestUtils {
"If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified", "Location",
"Max-Forwards", "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server",
"User-Agent", "Vary" };
/*
* "Entity-header fields define metainformation about the entity-body or,
* if no body is present, about the resource identified by the request."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1
*/
public static final String[] ENTITY_HEADERS = { "Allow", "Content-Encoding",
@ -341,4 +341,4 @@ public class HttpTestUtils {
return new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
}
}
}

View File

@ -38,4 +38,4 @@ public class OKStatus extends BasicStatusLine {
super(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
}
}
}

View File

@ -50,4 +50,4 @@ public class RequestEquivalent implements IArgumentMatcher {
buf.append(")");
}
}
}

View File

@ -46,7 +46,7 @@ public class TestAsynchronousValidationRequest {
private HttpRequest request;
private HttpContext mockContext;
private HttpCacheEntry mockCacheEntry;
@Before
public void setUp() {
mockParent = EasyMock.createMock(AsynchronousValidator.class);
@ -56,68 +56,68 @@ public class TestAsynchronousValidationRequest {
mockContext = EasyMock.createMock(HttpContext.class);
mockCacheEntry = EasyMock.createMock(HttpCacheEntry.class);
}
@Test
public void testRunCallsCachingClientAndRemovesIdentifier() throws ProtocolException, IOException {
String identifier = "foo";
AsynchronousValidationRequest asynchRequest = new AsynchronousValidationRequest(
mockParent, mockClient, target, request, mockContext, mockCacheEntry,
identifier);
// response not used
EasyMock.expect(mockClient.revalidateCacheEntry(target, request, mockContext, mockCacheEntry)).andReturn(null);
mockParent.markComplete(identifier);
replayMocks();
asynchRequest.run();
verifyMocks();
}
@Test
public void testRunGracefullyHandlesProtocolException() throws IOException, ProtocolException {
String identifier = "foo";
AsynchronousValidationRequest impl = new AsynchronousValidationRequest(
mockParent, mockClient, target, request, mockContext, mockCacheEntry,
identifier);
// response not used
EasyMock.expect(
mockClient.revalidateCacheEntry(target, request, mockContext,
mockCacheEntry)).andThrow(new ProtocolException());
mockParent.markComplete(identifier);
replayMocks();
impl.run();
verifyMocks();
}
@Test
public void testRunGracefullyHandlesIOException() throws IOException, ProtocolException {
String identifier = "foo";
AsynchronousValidationRequest impl = new AsynchronousValidationRequest(
mockParent, mockClient, target, request, mockContext, mockCacheEntry,
identifier);
// response not used
EasyMock.expect(
mockClient.revalidateCacheEntry(target, request, mockContext,
mockCacheEntry)).andThrow(new IOException());
mockParent.markComplete(identifier);
replayMocks();
impl.run();
verifyMocks();
}
public void replayMocks() {
EasyMock.replay(mockClient);
EasyMock.replay(mockContext);
EasyMock.replay(mockCacheEntry);
}
public void verifyMocks() {
EasyMock.verify(mockClient);
EasyMock.verify(mockContext);

View File

@ -48,17 +48,17 @@ import org.junit.Before;
import org.junit.Test;
public class TestAsynchronousValidator {
private AsynchronousValidator impl;
private CachingHttpClient mockClient;
private HttpHost target;
private HttpRequest request;
private HttpContext mockContext;
private HttpCacheEntry mockCacheEntry;
private ExecutorService mockExecutor;
@Before
public void setUp() {
mockClient = EasyMock.createMock(CachingHttpClient.class);
@ -66,138 +66,138 @@ public class TestAsynchronousValidator {
request = new HttpGet("/");
mockContext = EasyMock.createMock(HttpContext.class);
mockCacheEntry = EasyMock.createMock(HttpCacheEntry.class);
mockExecutor = EasyMock.createMock(ExecutorService.class);
}
@Test
public void testRevalidateCacheEntrySchedulesExecutionAndPopulatesIdentifier() {
impl = new AsynchronousValidator(mockClient, mockExecutor);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
mockExecutor.execute(EasyMock.isA(AsynchronousValidationRequest.class));
replayMocks();
impl.revalidateCacheEntry(target, request, mockContext, mockCacheEntry);
verifyMocks();
Assert.assertEquals(1, impl.getScheduledIdentifiers().size());
}
@Test
public void testMarkCompleteRemovesIdentifier() {
impl = new AsynchronousValidator(mockClient, mockExecutor);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
Capture<AsynchronousValidationRequest> cap = new Capture<AsynchronousValidationRequest>();
mockExecutor.execute(EasyMock.capture(cap));
replayMocks();
impl.revalidateCacheEntry(target, request, mockContext, mockCacheEntry);
verifyMocks();
Assert.assertEquals(1, impl.getScheduledIdentifiers().size());
impl.markComplete(cap.getValue().getIdentifier());
Assert.assertEquals(0, impl.getScheduledIdentifiers().size());
}
@Test
public void testRevalidateCacheEntryDoesNotPopulateIdentifierOnRejectedExecutionException() {
impl = new AsynchronousValidator(mockClient, mockExecutor);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
mockExecutor.execute(EasyMock.isA(AsynchronousValidationRequest.class));
EasyMock.expectLastCall().andThrow(new RejectedExecutionException());
replayMocks();
impl.revalidateCacheEntry(target, request, mockContext, mockCacheEntry);
verifyMocks();
Assert.assertEquals(0, impl.getScheduledIdentifiers().size());
}
@Test
public void testRevalidateCacheEntryProperlyCollapsesRequest() {
impl = new AsynchronousValidator(mockClient, mockExecutor);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
mockExecutor.execute(EasyMock.isA(AsynchronousValidationRequest.class));
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
replayMocks();
impl.revalidateCacheEntry(target, request, mockContext, mockCacheEntry);
impl.revalidateCacheEntry(target, request, mockContext, mockCacheEntry);
verifyMocks();
Assert.assertEquals(1, impl.getScheduledIdentifiers().size());
}
@Test
public void testVariantsBothRevalidated() {
impl = new AsynchronousValidator(mockClient, mockExecutor);
HttpRequest req1 = new HttpGet("/");
req1.addHeader(new BasicHeader("Accept-Encoding", "identity"));
HttpRequest req2 = new HttpGet("/");
req2.addHeader(new BasicHeader("Accept-Encoding", "gzip"));
Header[] variantHeaders = new Header[] {
new BasicHeader(HeaderConstants.VARY, "Accept-Encoding")
};
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(true).times(2);
EasyMock.expect(mockCacheEntry.getHeaders(HeaderConstants.VARY)).andReturn(variantHeaders).times(2);
mockExecutor.execute(EasyMock.isA(AsynchronousValidationRequest.class));
EasyMock.expectLastCall().times(2);
replayMocks();
impl.revalidateCacheEntry(target, req1, mockContext, mockCacheEntry);
impl.revalidateCacheEntry(target, req2, mockContext, mockCacheEntry);
verifyMocks();
Assert.assertEquals(2, impl.getScheduledIdentifiers().size());
}
@Test
public void testRevalidateCacheEntryEndToEnd() throws ProtocolException, IOException {
CacheConfig config = new CacheConfig();
config.setAsynchronousWorkersMax(1);
config.setAsynchronousWorkersCore(1);
impl = new AsynchronousValidator(mockClient, config);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
EasyMock.expect(mockClient.revalidateCacheEntry(target, request, mockContext, mockCacheEntry)).andReturn(null);
replayMocks();
impl.revalidateCacheEntry(target, request, mockContext, mockCacheEntry);
try {
// shut down backend executor and make sure all finishes properly, 1 second should be sufficient
ExecutorService implExecutor = impl.getExecutor();
implExecutor.shutdown();
implExecutor.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException ie) {
} finally {
verifyMocks();
Assert.assertEquals(0, impl.getScheduledIdentifiers().size());
}
}
public void replayMocks() {
EasyMock.replay(mockExecutor);
EasyMock.replay(mockClient);
EasyMock.replay(mockContext);
EasyMock.replay(mockCacheEntry);
}
public void verifyMocks() {
EasyMock.verify(mockExecutor);
EasyMock.verify(mockClient);

View File

@ -94,7 +94,7 @@ public class TestCacheEntryUpdater {
HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
new Date(), new Date(), response);
Header[] updatedHeaders = updatedEntry.getAllHeaders();
assertEquals(2, updatedHeaders.length);
headersContain(updatedHeaders, "Date", formatDate(responseDate));
@ -159,7 +159,7 @@ public class TestCacheEntryUpdater {
new BasicHeader("Date", formatDate(oneSecondAgo)),
new BasicHeader("ETag", "\"new-etag\"")
};
entry = HttpTestUtils.makeCacheEntry(twoSecondsAgo, now, headers);
entry = HttpTestUtils.makeCacheEntry(twoSecondsAgo, now, headers);
response.setHeader("Date", formatDate(tenSecondsAgo));
response.setHeader("ETag", "\"old-etag\"");
HttpCacheEntry result = impl.updateCacheEntry("A", entry, new Date(),
@ -179,7 +179,7 @@ public class TestCacheEntryUpdater {
assertEquals(twoSecondsAgo, updated.getRequestDate());
assertEquals(oneSecondAgo, updated.getResponseDate());
}
@Test
public void entry1xxWarningsAreRemovedOnUpdate() throws Exception {
Header[] headers = {
@ -195,7 +195,7 @@ public class TestCacheEntryUpdater {
assertEquals(0, updated.getHeaders("Warning").length);
}
@Test
public void entryWithMalformedDateIsStillUpdated() throws Exception {
Header[] headers = {
@ -225,7 +225,7 @@ public class TestCacheEntryUpdater {
assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue());
}
@Test
public void cannotUpdateFromANon304OriginResponse() throws Exception {
entry = HttpTestUtils.makeCacheEntry();

View File

@ -71,7 +71,7 @@ public class TestCacheInvalidator {
public void setUp() {
now = new Date();
tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
host = new HttpHost("foo.example.com");
mockStorage = createMock(HttpCacheStorage.class);
cacheKeyGenerator = new CacheKeyGenerator();
@ -265,7 +265,7 @@ public class TestCacheInvalidator {
impl.flushInvalidatedCacheEntries(host, request);
verifyMocks();
}
@Test
public void doesNotFlushForResponsesWithoutContentLocation()
throws Exception {
@ -273,7 +273,7 @@ public class TestCacheInvalidator {
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
@Test
public void flushesEntryIfFresherAndSpecifiedByContentLocation()
throws Exception {
@ -281,20 +281,20 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(tenSecondsAgo)),
new BasicHeader("ETag", "\"old-etag\"")
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
mockStorage.removeEntry(theURI);
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
@Test
public void doesNotFlushEntryForUnsuccessfulResponse()
throws Exception {
@ -303,14 +303,14 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(tenSecondsAgo)),
new BasicHeader("ETag", "\"old-etag\"")
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
@ -323,15 +323,15 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String cacheKey = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", "http://foo.example.com/bar");
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(tenSecondsAgo)),
new BasicHeader("ETag", "\"old-etag\"")
});
expect(mockStorage.getEntry(cacheKey)).andReturn(entry).anyTimes();
mockStorage.removeEntry(cacheKey);
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
@ -344,15 +344,15 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String cacheKey = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", "/bar");
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(tenSecondsAgo)),
new BasicHeader("ETag", "\"old-etag\"")
});
expect(mockStorage.getEntry(cacheKey)).andReturn(entry).anyTimes();
mockStorage.removeEntry(cacheKey);
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
@ -365,21 +365,21 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String cacheKey = "http://baz.example.com:80/bar";
response.setHeader("Content-Location", cacheKey);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(tenSecondsAgo)),
new BasicHeader("ETag", "\"old-etag\"")
});
expect(mockStorage.getEntry(cacheKey)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
@Test
public void doesNotFlushEntrySpecifiedByContentLocationIfEtagsMatch()
throws Exception {
@ -387,14 +387,14 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(tenSecondsAgo)),
new BasicHeader("ETag", "\"same-etag\"")
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
@ -407,19 +407,19 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(now)),
new BasicHeader("ETag", "\"old-etag\"")
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
@Test
public void doesNotFlushEntryIfNotInCache()
throws Exception {
@ -427,14 +427,14 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
expect(mockStorage.getEntry(theURI)).andReturn(null).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
@Test
public void doesNotFlushEntrySpecifiedByContentLocationIfResponseHasNoEtag()
throws Exception {
@ -442,19 +442,19 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(tenSecondsAgo)),
new BasicHeader("ETag", "\"old-etag\"")
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
@Test
public void doesNotFlushEntrySpecifiedByContentLocationIfEntryHasNoEtag()
throws Exception {
@ -462,13 +462,13 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("Date", formatDate(tenSecondsAgo)),
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
@ -481,19 +481,19 @@ public class TestCacheInvalidator {
response.removeHeaders("Date");
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("ETag", "\"old-etag\""),
new BasicHeader("Date", formatDate(tenSecondsAgo)),
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
@Test
public void doesNotFlushEntrySpecifiedByContentLocationIfEntryHasNoDate()
throws Exception {
@ -501,13 +501,13 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("ETag", "\"old-etag\"")
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
@ -520,19 +520,19 @@ public class TestCacheInvalidator {
response.setHeader("Date", "blarg");
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("ETag", "\"old-etag\""),
new BasicHeader("Date", formatDate(tenSecondsAgo))
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
@Test
public void doesNotFlushEntrySpecifiedByContentLocationIfEntryHasMalformedDate()
throws Exception {
@ -540,20 +540,20 @@ public class TestCacheInvalidator {
response.setHeader("Date", formatDate(now));
String theURI = "http://foo.example.com:80/bar";
response.setHeader("Content-Location", theURI);
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] {
new BasicHeader("ETag", "\"old-etag\""),
new BasicHeader("Date", "foo")
});
expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes();
replayMocks();
impl.flushInvalidatedCacheEntries(host, request, response);
verifyMocks();
}
// Expectations
private void cacheEntryHasVariantMap(Map<String,String> variantMap) {
expect(mockEntry.getVariantMap()).andReturn(variantMap);
@ -572,4 +572,4 @@ public class TestCacheInvalidator {
mockStorage.removeEntry(theUri);
}
}
}

View File

@ -331,7 +331,7 @@ public class TestCacheValidityPolicy {
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
assertFalse(impl.isRevalidatable(entry));
}
@Test
public void testMissingContentLengthDoesntInvalidateEntry() {
final int contentLength = 128;
@ -339,7 +339,7 @@ public class TestCacheValidityPolicy {
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers, HttpTestUtils.getRandomBytes(contentLength));
assertTrue(impl.contentLengthHeaderMatchesActualLength(entry));
}
@Test
public void testCorrectContentLengthDoesntInvalidateEntry() {
final int contentLength = 128;
@ -347,7 +347,7 @@ public class TestCacheValidityPolicy {
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers, HttpTestUtils.getRandomBytes(contentLength));
assertTrue(impl.contentLengthHeaderMatchesActualLength(entry));
}
@Test
public void testWrongContentLengthInvalidatesEntry() {
final int contentLength = 128;
@ -436,7 +436,7 @@ public class TestCacheValidityPolicy {
HttpRequest req = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
assertTrue(impl.mayReturnStaleIfError(req, entry, now));
}
@Test
public void testMayReturnStaleIfErrorInRequestIsTrueWithinStaleness(){
Header[] headers = new Header[] {
@ -475,15 +475,15 @@ public class TestCacheValidityPolicy {
@Test
public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveIsAbsent() {
Date now = new Date();
Header[] headers = new Header[] { new BasicHeader("Cache-control", "public") };
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
CacheValidityPolicy impl = new CacheValidityPolicy();
assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
}
@Test
public void testMayReturnStaleWhileRevalidatingIsTrueWhenWithinStaleness() {
Date now = new Date();
@ -493,12 +493,12 @@ public class TestCacheValidityPolicy {
new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=15")
};
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
CacheValidityPolicy impl = new CacheValidityPolicy();
assertTrue(impl.mayReturnStaleWhileRevalidating(entry, now));
}
@Test
public void testMayReturnStaleWhileRevalidatingIsFalseWhenPastStaleness() {
Date now = new Date();
@ -508,12 +508,12 @@ public class TestCacheValidityPolicy {
new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=15")
};
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
CacheValidityPolicy impl = new CacheValidityPolicy();
assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
}
@Test
public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveEmpty() {
Date now = new Date();
@ -523,9 +523,9 @@ public class TestCacheValidityPolicy {
new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=")
};
HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
CacheValidityPolicy impl = new CacheValidityPolicy();
assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
}
}

View File

@ -260,4 +260,4 @@ public class TestCachedResponseSuitabilityChecker {
Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
}
}
}

View File

@ -203,16 +203,16 @@ public class TestCachingHttpClient {
@Test
public void testCacheableResponsesGoIntoCache() throws Exception {
impl = new CachingHttpClient(mockBackend);
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","max-age=3600");
expect(mockBackend.execute(isA(HttpHost.class), isA(HttpRequest.class),
(HttpContext)isNull())).andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
@ -224,7 +224,7 @@ public class TestCachingHttpClient {
impl = new CachingHttpClient(mockBackend);
Date now = new Date();
Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L);
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(now));
@ -233,7 +233,7 @@ public class TestCachingHttpClient {
expect(mockBackend.execute(isA(HttpHost.class), isA(HttpRequest.class),
(HttpContext)isNull())).andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control","no-cache");
HttpResponse resp2 = HttpTestUtils.make200Response();
@ -260,7 +260,7 @@ public class TestCachingHttpClient {
impl = new CachingHttpClient(mockBackend);
Date now = new Date();
Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L);
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", DateUtils.formatDate(fiveSecondsAgo));
@ -269,7 +269,7 @@ public class TestCachingHttpClient {
expect(mockBackend.execute(isA(HttpHost.class), isA(HttpRequest.class),
(HttpContext)isNull())).andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control","max-age=0");
HttpResponse resp2 = HttpTestUtils.make200Response();
@ -486,7 +486,7 @@ public class TestCachingHttpClient {
impl = new CachingHttpClient(mockBackend,
new BasicHttpCache(new HeapResourceFactory(), mockStorage, config),
config);
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","no-cache");
@ -1012,8 +1012,8 @@ public class TestCachingHttpClient {
resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
replayMocks();
@ -1048,8 +1048,8 @@ public class TestCachingHttpClient {
HttpResponse resp2 = HttpTestUtils.make200Response();
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
@ -1088,8 +1088,8 @@ public class TestCachingHttpClient {
.formatDate(tenSecondsAfter));
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1).times(2);
replayMocks();
@ -1116,8 +1116,8 @@ public class TestCachingHttpClient {
resp1.setHeader("Cache-Control", "public, max-age=3600");
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
replayMocks();
@ -1147,12 +1147,12 @@ public class TestCachingHttpClient {
HttpResponse resp2 = HttpTestUtils.make200Response();
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp2);
replayMocks();
@ -1185,8 +1185,8 @@ public class TestCachingHttpClient {
req2.addHeader("If-Modified-Since", DateUtils.formatDate(now));
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
replayMocks();
@ -1217,12 +1217,12 @@ public class TestCachingHttpClient {
resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
replayMocks();
@ -1432,13 +1432,13 @@ public class TestCachingHttpClient {
resp2.setHeader("Date", DateUtils.formatDate(now));
resp2.setHeader("Cache-Control", "public, max-age=5");
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp2);
replayMocks();
impl.execute(host, req1);
@ -1476,13 +1476,13 @@ public class TestCachingHttpClient {
resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
resp2.setHeader("Cache-Control", "public, max-age=5");
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp2);
replayMocks();
impl.execute(host, req1);
@ -1520,13 +1520,13 @@ public class TestCachingHttpClient {
resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
resp2.setHeader("Cache-Control", "public, max-age=5");
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp2);
replayMocks();
impl.execute(host, req1);
@ -1565,13 +1565,13 @@ public class TestCachingHttpClient {
resp1.setHeader("Last-Modified", DateUtils.formatDate(now));
resp2.setHeader("Cache-Control", "public, max-age=5");
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp2);
replayMocks();
impl.execute(host, req1);
@ -1628,18 +1628,18 @@ public class TestCachingHttpClient {
resp3.setHeader("Cache-Control", "public, max-age=3600");
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp2);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp3);
@ -1702,18 +1702,18 @@ public class TestCachingHttpClient {
resp4.setHeader("Cache-Control", "public, max-age=3600");
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp1);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp2);
expect(
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
mockBackend.execute(isA(HttpHost.class),
isA(HttpRequest.class), (HttpContext)
isNull())).andReturn(resp4);
replayMocks();
@ -1744,7 +1744,7 @@ public class TestCachingHttpClient {
mockCache.flushInvalidatedCacheEntriesFor(host, request);
expectLastCall().andThrow(new IOException()).anyTimes();
mockCache.flushInvalidatedCacheEntriesFor(isA(HttpHost.class), isA(HttpRequest.class), isA(HttpResponse.class));
expectLastCall().anyTimes();
expectLastCall().anyTimes();
expect(mockCache.getCacheEntry(same(host),
isA(HttpRequest.class)))
.andThrow(new IOException()).anyTimes();
@ -1853,7 +1853,7 @@ public class TestCachingHttpClient {
expect(mockValidityPolicy.isRevalidatable(
(HttpCacheEntry)anyObject())).andReturn(b);
}
private void cacheEntryMustRevalidate(boolean b) {
expect(mockValidityPolicy.mustRevalidate(mockCacheEntry))
.andReturn(b);
@ -1863,7 +1863,7 @@ public class TestCachingHttpClient {
expect(mockValidityPolicy.proxyRevalidate(mockCacheEntry))
.andReturn(b);
}
private void mayReturnStaleWhileRevalidating(boolean b) {
expect(mockValidityPolicy.mayReturnStaleWhileRevalidating(
(HttpCacheEntry)anyObject(), (Date)anyObject())).andReturn(b);

View File

@ -54,12 +54,12 @@ public class TestHttpCacheEntrySerializers {
private static final Charset UTF8 = Charset.forName("UTF-8");
private HttpCacheEntrySerializer impl;
@Before
public void setUp() {
impl = new DefaultHttpCacheEntrySerializer();
}
@Test
public void canSerializeEntriesWithVariantMaps() throws Exception {
readWriteVerify(makeCacheEntryWithVariantMap());
@ -96,7 +96,7 @@ public class TestHttpCacheEntrySerializers {
return cacheEntry;
}
private boolean areEqual(HttpCacheEntry one, HttpCacheEntry two) throws IOException {
// dates are only stored with second precision, so scrub milliseconds
if (!((one.getRequestDate().getTime() / 1000) == (two.getRequestDate()

View File

@ -363,4 +363,4 @@ public class TestProtocolDeviations {
Assert.assertSame(originResponse, result);
}
}
}

View File

@ -66,7 +66,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
private Date now;
private Date tenSecondsAgo;
private Date twoMinutesAgo;
@Override
@Before
public void setUp() {
@ -76,7 +76,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
twoMinutesAgo = new Date(now.getTime() - 2 * 60 * 1000L);
tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
}
/* "identity: The default (identity) encoding; the use of no
* transformation whatsoever. This content-coding is used only in the
* Accept-Encoding header, and SHOULD NOT be used in the
@ -107,7 +107,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
* "304 Not Modified. ... If the conditional GET used a strong cache
* validator (see section 13.3.3), the response SHOULD NOT include
* other entity-headers."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
*/
private void cacheGenerated304ForValidatorShouldNotContainEntityHeader(
@ -119,29 +119,29 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader(validatorHeader, validator);
resp1.setHeader(headerName, headerValue);
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader(conditionalHeader, validator);
replayMocks();
impl.execute(host, req1);
HttpResponse result = impl.execute(host, req2);
verifyMocks();
if (HttpStatus.SC_NOT_MODIFIED == result.getStatusLine().getStatusCode()) {
assertNull(result.getFirstHeader(headerName));
}
}
private void cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader(
String headerName, String headerValue) throws Exception,
IOException {
cacheGenerated304ForValidatorShouldNotContainEntityHeader(headerName,
headerValue, "ETag", "\"etag\"", "If-None-Match");
}
private void cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader(
String headerName, String headerValue) throws Exception,
IOException {
@ -149,28 +149,28 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
headerValue, "Last-Modified", formatDate(twoMinutesAgo),
"If-Modified-Since");
}
@Test
public void cacheGenerated304ForStrongEtagValidatorShouldNotContainAllow()
throws Exception {
cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader(
"Allow", "GET,HEAD");
}
@Test
public void cacheGenerated304ForStrongDateValidatorShouldNotContainAllow()
throws Exception {
cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader(
"Allow", "GET,HEAD");
}
@Test
public void cacheGenerated304ForStrongEtagValidatorShouldNotContainContentEncoding()
throws Exception {
cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader(
"Content-Encoding", "gzip");
}
@Test
public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentEncoding()
throws Exception {
@ -184,7 +184,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader(
"Content-Language", "en");
}
@Test
public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentLanguage()
throws Exception {
@ -198,21 +198,21 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader(
"Content-Length", "128");
}
@Test
public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentLength()
throws Exception {
cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader(
"Content-Length", "128");
}
@Test
public void cacheGenerated304ForStrongValidatorShouldNotContainContentMD5()
throws Exception {
cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader(
"Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==");
}
@Test
public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentMD5()
throws Exception {
@ -229,9 +229,9 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader(validatorHeader, validator);
resp1.setHeader("Content-Range", "bytes 0-127/256");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("If-Range", validator);
req2.setHeader("Range","bytes=0-127");
@ -240,67 +240,67 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified");
resp2.setHeader("Date", formatDate(now));
resp2.setHeader(validatorHeader, validator);
// cache module does not currently deal with byte ranges, but we want
// this test to work even if it does some day
Capture<HttpRequest> cap = new Capture<HttpRequest>();
expect(mockBackend.execute(same(host), capture(cap), (HttpContext)isNull()))
.andReturn(resp2).times(0,1);
replayMocks();
impl.execute(host, req1);
HttpResponse result = impl.execute(host, req2);
verifyMocks();
if (!cap.hasCaptured()
&& HttpStatus.SC_NOT_MODIFIED == result.getStatusLine().getStatusCode()) {
// cache generated a 304
assertNull(result.getFirstHeader("Content-Range"));
}
}
@Test
public void cacheGenerated304ForStrongEtagValidatorShouldNotContainContentRange()
throws Exception {
cacheGenerated304ForStrongValidatorShouldNotContainContentRange(
"ETag", "\"etag\"", "If-None-Match");
}
@Test
public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentRange()
throws Exception {
cacheGenerated304ForStrongValidatorShouldNotContainContentRange(
"Last-Modified", formatDate(twoMinutesAgo), "If-Modified-Since");
}
@Test
public void cacheGenerated304ForStrongEtagValidatorShouldNotContainContentType()
throws Exception {
cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader(
"Content-Type", "text/html");
}
@Test
public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentType()
throws Exception {
cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader(
"Content-Type", "text/html");
}
@Test
public void cacheGenerated304ForStrongEtagValidatorShouldNotContainLastModified()
throws Exception {
cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader(
"Last-Modified", formatDate(tenSecondsAgo));
}
@Test
public void cacheGenerated304ForStrongDateValidatorShouldNotContainLastModified()
throws Exception {
cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader(
"Last-Modified", formatDate(twoMinutesAgo));
}
private void shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation(
String entityHeader, String entityHeaderValue) throws Exception,
IOException {
@ -311,23 +311,23 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp.setHeader("Date", formatDate(now));
resp.setHeader("Etag", "\"etag\"");
resp.setHeader(entityHeader, entityHeaderValue);
backendExpectsAnyRequest().andReturn(resp);
replayMocks();
HttpResponse result = impl.execute(host, req);
verifyMocks();
assertNull(result.getFirstHeader(entityHeader));
}
@Test
public void shouldStripAllowFromOrigin304ResponseToStrongValidation()
throws Exception {
shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation(
"Allow", "GET,HEAD");
}
@Test
public void shouldStripContentEncodingFromOrigin304ResponseToStrongValidation()
throws Exception {
@ -341,14 +341,14 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation(
"Content-Language", "en");
}
@Test
public void shouldStripContentLengthFromOrigin304ResponseToStrongValidation()
throws Exception {
shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation(
"Content-Length", "128");
}
@Test
public void shouldStripContentMD5FromOrigin304ResponseToStrongValidation()
throws Exception {
@ -362,35 +362,35 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation(
"Content-Type", "text/html;charset=utf-8");
}
@Test
public void shouldStripContentRangeFromOrigin304ResponseToStringValidation()
throws Exception {
HttpRequest req = HttpTestUtils.makeDefaultRequest();
req.setHeader("If-Range","\"etag\"");
req.setHeader("Range","bytes=0-127");
HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified");
resp.setHeader("Date", formatDate(now));
resp.setHeader("ETag", "\"etag\"");
resp.setHeader("Content-Range", "bytes 0-127/256");
backendExpectsAnyRequest().andReturn(resp);
replayMocks();
HttpResponse result = impl.execute(host, req);
verifyMocks();
assertNull(result.getFirstHeader("Content-Range"));
}
@Test
public void shouldStripLastModifiedFromOrigin304ResponseToStrongValidation()
throws Exception {
shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation(
"Last-Modified", formatDate(twoMinutesAgo));
}
/*
* "For this reason, a cache SHOULD NOT return a stale response if the
* client explicitly requests a first-hand or fresh one, unless it is
@ -616,7 +616,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
assertEquals(warning, result.getFirstHeader("Warning").getValue());
}
/*
* "A transparent proxy SHOULD NOT modify an end-to-end header unless
* the definition of that header requires or specifically allows that."
@ -1175,7 +1175,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
}
assertTrue(foundEtag1 && foundEtag2);
}
/* "If the entity-tag of the new response matches that of an existing
* entry, the new response SHOULD be used to update the header fields
* of the existing entry, and the result MUST be returned to the
@ -1237,7 +1237,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
assertEquals(formatDate(now), result1.getFirstHeader("Date").getValue());
assertEquals(formatDate(now), result2.getFirstHeader("Date").getValue());
}
@Test
public void testResponseToExistingVariantsIsCachedForFutureResponses()
throws Exception {
@ -1279,7 +1279,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
* for the associated entity, its entity-tag SHOULD NOT be included in
* the If-None-Match header field unless the request is for a range
* that would be fully satisfied by that entry."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6
*/
@Test
@ -1291,9 +1291,9 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("Vary", "User-Agent");
resp1.setHeader("ETag", "\"etag1\"");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("User-Agent", "agent2");
req2.setHeader("Range", "bytes=0-49");
@ -1306,27 +1306,27 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp2.setHeader("ETag", "\"etag2\"");
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Date", formatDate(new Date()));
backendExpectsAnyRequest().andReturn(resp2);
HttpRequest req3 = HttpTestUtils.makeDefaultRequest();
req3.setHeader("User-Agent", "agent3");
HttpResponse resp3 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("Vary", "User-Agent");
resp1.setHeader("ETag", "\"etag3\"");
Capture<HttpRequest> cap = new Capture<HttpRequest>();
expect(mockBackend.execute(isA(HttpHost.class), capture(cap),
(HttpContext)isNull())).andReturn(resp3);
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
impl.execute(host, req3);
verifyMocks();
HttpRequest captured = cap.getValue();
for(Header h : captured.getHeaders("If-None-Match")) {
for(HeaderElement elt : h.getElements()) {
@ -1334,15 +1334,15 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
}
}
}
/* "If a cache receives a successful response whose Content-Location
* field matches that of an existing cache entry for the same Request-
* URI, whose entity-tag differs from that of the existing entry, and
* whose Date is more recent than that of the existing entry, the
* existing entry SHOULD NOT be returned in response to future requests
* and SHOULD be deleted from the cache.
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6
*/
@Test
public void cachedEntryShouldNotBeUsedIfMoreRecentMentionInContentLocation()
@ -1352,34 +1352,34 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("ETag", "\"old-etag\"");
resp1.setHeader("Date", formatDate(tenSecondsAgo));
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new HttpGet("http://foo.example.com/bar");
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("ETag", "\"new-etag\"");
resp2.setHeader("Date", formatDate(now));
resp2.setHeader("Content-Location", "http://foo.example.com/");
backendExpectsAnyRequest().andReturn(resp2);
HttpRequest req3 = new HttpGet("http://foo.example.com");
HttpResponse resp3 = HttpTestUtils.make200Response();
backendExpectsAnyRequest().andReturn(resp3);
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
impl.execute(host, req3);
verifyMocks();
}
/*
* "This specifically means that responses from HTTP/1.0 servers for such
* URIs [those containing a '?' in the rel_path part] SHOULD NOT be taken
* from a cache."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9
*/
@Test
@ -1391,23 +1391,23 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Content-Length","200");
resp1.setHeader("Date", formatDate(now));
resp1.setHeader("Expires", formatDate(tenSecondsFromNow));
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new HttpGet("http://foo.example.com/bar?baz=quux");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
resp2.setEntity(HttpTestUtils.makeBody(200));
resp2.setHeader("Content-Length","200");
resp2.setHeader("Date", formatDate(now));
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
verifyMocks();
}
@Test
public void responseToGetWithQueryFrom1_0OriginVia1_1ProxyIsNotCached()
throws Exception {
@ -1418,18 +1418,18 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Date", formatDate(now));
resp1.setHeader("Expires", formatDate(tenSecondsFromNow));
resp1.setHeader("Via","1.0 someproxy");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new HttpGet("http://foo.example.com/bar?baz=quux");
HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
resp2.setEntity(HttpTestUtils.makeBody(200));
resp2.setHeader("Content-Length","200");
resp2.setHeader("Date", formatDate(now));
resp2.setHeader("Via","1.0 someproxy");
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
@ -1440,7 +1440,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
* "A cache that passes through requests for methods it does not
* understand SHOULD invalidate any entities referred to by the
* Request-URI."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10
*/
@Test
@ -1449,30 +1449,30 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","max-age=3600");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new BasicHttpRequest("FROB", "/", HttpVersion.HTTP_1_1);
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("Cache-Control","max-age=3600");
backendExpectsAnyRequest().andReturn(resp2);
HttpRequest req3 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp3 = HttpTestUtils.make200Response();
resp3.setHeader("ETag", "\"etag\"");
backendExpectsAnyRequest().andReturn(resp3);
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
HttpResponse result = impl.execute(host, req3);
verifyMocks();
assertTrue(HttpTestUtils.semanticallyTransparent(resp3, result));
}
@Test
public void shouldInvalidateAllVariantsForUnknownMethod()
throws Exception {
@ -1481,7 +1481,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","max-age=3600");
resp1.setHeader("Vary", "User-Agent");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
@ -1489,30 +1489,30 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("Cache-Control","max-age=3600");
resp2.setHeader("Vary", "User-Agent");
backendExpectsAnyRequest().andReturn(resp2);
HttpRequest req3 = new BasicHttpRequest("FROB", "/", HttpVersion.HTTP_1_1);
req3.setHeader("User-Agent", "agent3");
HttpResponse resp3 = HttpTestUtils.make200Response();
resp3.setHeader("Cache-Control","max-age=3600");
backendExpectsAnyRequest().andReturn(resp3);
HttpRequest req4 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
req4.setHeader("User-Agent", "agent1");
HttpResponse resp4 = HttpTestUtils.make200Response();
resp4.setHeader("ETag", "\"etag1\"");
backendExpectsAnyRequest().andReturn(resp4);
HttpRequest req5 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
req5.setHeader("User-Agent", "agent2");
HttpResponse resp5 = HttpTestUtils.make200Response();
resp5.setHeader("ETag", "\"etag2\"");
backendExpectsAnyRequest().andReturn(resp5);
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
@ -1520,7 +1520,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
HttpResponse result4 = impl.execute(host, req4);
HttpResponse result5 = impl.execute(host, req5);
verifyMocks();
assertTrue(HttpTestUtils.semanticallyTransparent(resp4, result4));
assertTrue(HttpTestUtils.semanticallyTransparent(resp5, result5));
}
@ -1529,7 +1529,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
* "If a new cacheable response is received from a resource while any
* existing responses for the same resource are cached, the cache
* SHOULD use the new response to reply to the current request."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.12
*/
@Test
@ -1540,29 +1540,29 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Date", formatDate(tenSecondsAgo));
resp1.setHeader("Cache-Control", "max-age=3600");
resp1.setHeader("ETag", "\"etag1\"");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control", "max-age=0");
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("Date", formatDate(now));
resp2.setHeader("Cache-Control", "max-age=3600");
resp2.setHeader("ETag", "\"etag2\"");
backendExpectsAnyRequest().andReturn(resp2);
HttpRequest req3 = HttpTestUtils.makeDefaultRequest();
replayMocks();
impl.execute(host, req1);
impl.execute(host, req2);
HttpResponse result = impl.execute(host, req3);
verifyMocks();
assertTrue(HttpTestUtils.semanticallyTransparent(resp2, result));
}
/*
* "Many HTTP/1.0 cache implementations will treat an Expires value
* that is less than or equal to the response Date value as being
@ -1571,7 +1571,7 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
* does not include a Cache-Control header field, it SHOULD consider
* the response to be non-cacheable in order to retain compatibility
* with HTTP/1.0 servers."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3
*/
@Test
@ -1582,24 +1582,24 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Date", formatDate(now));
resp1.setHeader("Expires", formatDate(now));
resp1.removeHeaders("Cache-Control");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control", "max-stale=1000");
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("ETag", "\"etag2\"");
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host, req1);
HttpResponse result = impl.execute(host, req2);
verifyMocks();
assertTrue(HttpTestUtils.semanticallyTransparent(resp2, result));
}
@Test
public void expiresPriorToDateWithNoCacheControlIsNotCacheable()
throws Exception {
@ -1608,28 +1608,28 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
resp1.setHeader("Date", formatDate(now));
resp1.setHeader("Expires", formatDate(tenSecondsAgo));
resp1.removeHeaders("Cache-Control");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control", "max-stale=1000");
HttpResponse resp2 = HttpTestUtils.make200Response();
resp2.setHeader("ETag", "\"etag2\"");
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host, req1);
HttpResponse result = impl.execute(host, req2);
verifyMocks();
assertTrue(HttpTestUtils.semanticallyTransparent(resp2, result));
}
/*
* "If a request includes the no-cache directive, it SHOULD NOT
* include min-fresh, max-stale, or max-age."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4
*/
@Test
@ -1638,15 +1638,15 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
req1.setHeader("Cache-Control", "min-fresh=10, no-cache");
req1.addHeader("Cache-Control", "max-stale=0, max-age=0");
Capture<HttpRequest> cap = new Capture<HttpRequest>();
expect(mockBackend.execute(same(host), capture(cap), (HttpContext)isNull()))
.andReturn(HttpTestUtils.make200Response());
replayMocks();
impl.execute(host, req1);
verifyMocks();
HttpRequest captured = cap.getValue();
boolean foundNoCache = false;
boolean foundDisallowedDirective = false;
@ -1665,14 +1665,14 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
assertTrue(foundNoCache);
assertFalse(foundDisallowedDirective);
}
/*
* "To do this, the client may include the only-if-cached directive in
* a request. If it receives this directive, a cache SHOULD either
* respond using a cached entry that is consistent with the other
* constraints of the request, or respond with a 504 (Gateway Timeout)
* status."
*
*
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4
*/
@Test
@ -1680,35 +1680,35 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
throws Exception {
HttpRequest req = HttpTestUtils.makeDefaultRequest();
req.setHeader("Cache-Control", "only-if-cached");
replayMocks();
HttpResponse result = impl.execute(host, req);
verifyMocks();
assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT,
result.getStatusLine().getStatusCode());
}
@Test
public void cacheHitOkWithOnlyIfCached()
throws Exception {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control","max-age=3600");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control", "only-if-cached");
replayMocks();
impl.execute(host, req1);
HttpResponse result = impl.execute(host, req2);
verifyMocks();
assertTrue(HttpTestUtils.semanticallyTransparent(resp1, result));
}
@Test
public void returns504ForStaleEntryWithOnlyIfCached()
throws Exception {
@ -1716,21 +1716,21 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", formatDate(tenSecondsAgo));
resp1.setHeader("Cache-Control","max-age=5");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control", "only-if-cached");
replayMocks();
impl.execute(host, req1);
HttpResponse result = impl.execute(host, req2);
verifyMocks();
assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT,
result.getStatusLine().getStatusCode());
}
@Test
public void returnsStaleCacheEntryWithOnlyIfCachedAndMaxStale()
throws Exception {
@ -1739,18 +1739,18 @@ public class TestProtocolRecommendations extends AbstractProtocolTest {
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Date", formatDate(tenSecondsAgo));
resp1.setHeader("Cache-Control","max-age=5");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control", "max-stale=20, only-if-cached");
replayMocks();
impl.execute(host, req1);
HttpResponse result = impl.execute(host, req2);
verifyMocks();
assertTrue(HttpTestUtils.semanticallyTransparent(resp1, result));
}
}

View File

@ -5836,4 +5836,4 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
Assert.assertTrue(warningHeaders == null || warningHeaders.length == 0);
}
}
}

View File

@ -38,26 +38,26 @@ import org.apache.http.impl.cookie.DateUtils;
import org.apache.http.message.BasicHttpRequest;
import org.junit.Test;
/**
/**
* A suite of acceptance tests for compliance with RFC5861, which
* describes the stale-if-error and stale-while-revalidate
* Cache-Control extensions.
*/
public class TestRFC5861Compliance extends AbstractProtocolTest {
/*
/*
* "The stale-if-error Cache-Control extension indicates that when an
* error is encountered, a cached stale response MAY be used to satisfy
* the request, regardless of other freshness information.When used as a
* the request, regardless of other freshness information.When used as a
* request Cache-Control extension, its scope of application is the request
* it appears in; when used as a response Cache-Control extension, its
* scope is any request applicable to the cached response in which it
* it appears in; when used as a response Cache-Control extension, its
* scope is any request applicable to the cached response in which it
* occurs.Its value indicates the upper limit to staleness; when the cached
* response is more stale than the indicated amount, the cached response
* SHOULD NOT be used to satisfy the request, absent other information.
* In this context, an error is any situation that would result in a
* 500, 502, 503, or 504 HTTP response status code being returned."
*
*
* http://tools.ietf.org/html/rfc5861
*/
@Test
@ -67,22 +67,22 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
"public, max-age=5, stale-if-error=60");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp2 = HttpTestUtils.make500Response();
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host,req1);
HttpResponse result = impl.execute(host,req2);
verifyMocks();
HttpTestUtils.assert110WarningFound(result);
}
@Test
public void testStaleIfErrorInResponseYieldsToMustRevalidate()
throws Exception{
@ -90,22 +90,22 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
"public, max-age=5, stale-if-error=60, must-revalidate");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp2 = HttpTestUtils.make500Response();
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host,req1);
HttpResponse result = impl.execute(host,req2);
verifyMocks();
assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode());
}
@Test
public void testStaleIfErrorInResponseYieldsToProxyRevalidateForSharedCache()
throws Exception{
@ -114,46 +114,46 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
"public, max-age=5, stale-if-error=60, proxy-revalidate");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp2 = HttpTestUtils.make500Response();
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host,req1);
HttpResponse result = impl.execute(host,req2);
verifyMocks();
assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode());
}
@Test
public void testStaleIfErrorInResponseNeedNotYieldToProxyRevalidateForPrivateCache()
throws Exception{
CacheConfig config = new CacheConfig();
config.setSharedCache(false);
impl = new CachingHttpClient(mockBackend, config);
Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L);
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
"public, max-age=5, stale-if-error=60, proxy-revalidate");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp2 = HttpTestUtils.make500Response();
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host,req1);
HttpResponse result = impl.execute(host,req2);
verifyMocks();
HttpTestUtils.assert110WarningFound(result);
}
@ -164,23 +164,23 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
"public, max-age=5, stale-if-error=60");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control","min-fresh=2");
HttpResponse resp2 = HttpTestUtils.make500Response();
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host,req1);
HttpResponse result = impl.execute(host,req2);
verifyMocks();
assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode());
}
@Test
public void testStaleIfErrorInRequestIsTrueReturnsStaleEntryWithWarning()
throws Exception{
@ -188,23 +188,23 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
"public, max-age=5");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control","public, stale-if-error=60");
HttpResponse resp2 = HttpTestUtils.make500Response();
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host,req1);
HttpResponse result = impl.execute(host,req2);
verifyMocks();
HttpTestUtils.assert110WarningFound(result);
}
@Test
public void testStaleIfErrorInResponseIsFalseReturnsError()
throws Exception{
@ -213,14 +213,14 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
"public, max-age=5, stale-if-error=2");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp2 = HttpTestUtils.make500Response();
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host,req1);
HttpResponse result = impl.execute(host,req2);
@ -229,7 +229,7 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR,
result.getStatusLine().getStatusCode());
}
@Test
public void testStaleIfErrorInRequestIsFalseReturnsError()
throws Exception{
@ -238,15 +238,15 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
HttpRequest req1 = HttpTestUtils.makeDefaultRequest();
HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo,
"public, max-age=5");
backendExpectsAnyRequest().andReturn(resp1);
HttpRequest req2 = HttpTestUtils.makeDefaultRequest();
req2.setHeader("Cache-Control","stale-if-error=2");
HttpResponse resp2 = HttpTestUtils.make500Response();
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
impl.execute(host,req1);
HttpResponse result = impl.execute(host,req2);
@ -255,22 +255,22 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR,
result.getStatusLine().getStatusCode());
}
/*
* When present in an HTTP response, the stale-while-revalidate Cache-
* Control extension indicates that caches MAY serve the response in
* which it appears after it becomes stale, up to the indicated number
* of seconds.
*
*
* http://tools.ietf.org/html/rfc5861
*/
@Test
public void testStaleWhileRevalidateReturnsStaleEntryWithWarning()
throws Exception {
params.setAsynchronousWorkersMax(1);
impl = new CachingHttpClient(mockBackend, cache, params);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = HttpTestUtils.make200Response();
Date now = new Date();
@ -300,15 +300,15 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
}
assertTrue(warning110Found);
}
@Test
public void testCanAlsoServeStale304sWhileRevalidating()
throws Exception {
params.setAsynchronousWorkersMax(1);
params.setSharedCache(false);
impl = new CachingHttpClient(mockBackend, cache, params);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = HttpTestUtils.make200Response();
Date now = new Date();
@ -340,17 +340,17 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
assertTrue(warning110Found);
}
@Test
public void testStaleWhileRevalidateYieldsToMustRevalidate()
throws Exception {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
params.setAsynchronousWorkersMax(1);
impl = new CachingHttpClient(mockBackend, cache, params);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15, must-revalidate");
@ -364,7 +364,7 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
resp2.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15, must-revalidate");
resp2.setHeader("ETag","\"etag\"");
resp2.setHeader("Date", DateUtils.formatDate(now));
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
@ -388,14 +388,14 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
@Test
public void testStaleWhileRevalidateYieldsToProxyRevalidateForSharedCache()
throws Exception {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
params.setAsynchronousWorkersMax(1);
params.setSharedCache(true);
impl = new CachingHttpClient(mockBackend, cache, params);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15, proxy-revalidate");
@ -409,7 +409,7 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
resp2.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15, proxy-revalidate");
resp2.setHeader("ETag","\"etag\"");
resp2.setHeader("Date", DateUtils.formatDate(now));
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
@ -433,14 +433,14 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
@Test
public void testStaleWhileRevalidateYieldsToExplicitFreshnessRequest()
throws Exception {
Date now = new Date();
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
params.setAsynchronousWorkersMax(1);
params.setSharedCache(true);
impl = new CachingHttpClient(mockBackend, cache, params);
HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
HttpResponse resp1 = HttpTestUtils.make200Response();
resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15");
@ -455,7 +455,7 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
resp2.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15");
resp2.setHeader("ETag","\"etag\"");
resp2.setHeader("Date", DateUtils.formatDate(now));
backendExpectsAnyRequest().andReturn(resp2);
replayMocks();
@ -475,5 +475,5 @@ public class TestRFC5861Compliance extends AbstractProtocolTest {
}
assertFalse(warning110Found);
}
}

View File

@ -42,22 +42,22 @@ public class TestRequestProtocolCompliance {
private RequestProtocolCompliance impl;
private HttpRequest req;
private HttpRequest result;
@Before
public void setUp() {
req = HttpTestUtils.makeDefaultRequest();
impl = new RequestProtocolCompliance();
}
@Test
public void doesNotModifyACompliantRequest() throws Exception {
result = impl.makeRequestCompliant(req);
result = impl.makeRequestCompliant(req);
assertTrue(HttpTestUtils.equivalent(req, result));
}
@Test
public void removesEntityFromTRACERequest() throws Exception {
HttpEntityEnclosingRequest req =
HttpEntityEnclosingRequest req =
new BasicHttpEntityEnclosingRequest("TRACE", "/", HttpVersion.HTTP_1_1);
req.setEntity(HttpTestUtils.makeBody(50));
result = impl.makeRequestCompliant(req);
@ -65,7 +65,7 @@ public class TestRequestProtocolCompliance {
assertNull(((HttpEntityEnclosingRequest)result).getEntity());
}
}
@Test
public void upgrades1_0RequestTo1_1() throws Exception {
req = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_0);
@ -80,7 +80,7 @@ public class TestRequestProtocolCompliance {
result = impl.makeRequestCompliant(req);
assertEquals(HttpVersion.HTTP_1_1, result.getProtocolVersion());
}
@Test
public void stripsMinFreshFromRequestIfNoCachePresent()
throws Exception {
@ -107,7 +107,7 @@ public class TestRequestProtocolCompliance {
assertEquals("no-cache",
result.getFirstHeader("Cache-Control").getValue());
}
@Test
public void doesNotStripMinFreshFromRequestWithoutNoCache()
throws Exception {
@ -116,7 +116,7 @@ public class TestRequestProtocolCompliance {
assertEquals("min-fresh=10",
result.getFirstHeader("Cache-Control").getValue());
}
@Test
public void correctlyStripsMinFreshFromMiddleIfNoCache()
throws Exception {

View File

@ -60,7 +60,7 @@ public class TestResponseCachingPolicy {
now = new Date();
sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
policy = new ResponseCachingPolicy(0, true);
request = new BasicHttpRequest("GET","/",HTTP_1_1);
response = new BasicHttpResponse(
@ -397,7 +397,7 @@ public class TestResponseCachingPolicy {
response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
Assert.assertFalse(policy.isResponseCacheable(request, response));
}
@Test
public void getsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheableEvenWithExpires() {
request = new BasicHttpRequest("GET", "/foo?s=bar");
@ -406,7 +406,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Expires", formatDate(tenSecondsFromNow));
Assert.assertFalse(policy.isResponseCacheable(request, response));
}
@Test
public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreNotCacheable() {
request = new BasicHttpRequest("GET", "/foo?s=bar");
@ -424,7 +424,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Via", "1.0 someproxy");
Assert.assertFalse(policy.isResponseCacheable(request, response));
}
@Test
public void getsWithQueryParametersFrom1_0OriginsViaExplicitProxiesAreNotCacheableEvenWithExpires() {
request = new BasicHttpRequest("GET", "/foo?s=bar");
@ -443,7 +443,7 @@ public class TestResponseCachingPolicy {
response.setHeader("Via", "1.1 someproxy");
Assert.assertTrue(policy.isResponseCacheable(request, response));
}
@Test
public void notCacheableIfExpiresEqualsDateAndNoCacheControl() {
response.setHeader("Date", formatDate(now));

View File

@ -60,12 +60,12 @@ public class TestResponseProtocolCompliance {
private static class Flag {
public boolean set;
}
private void setMinimalResponseHeaders(HttpResponse resp) {
resp.setHeader("Date", DateUtils.formatDate(new Date()));
resp.setHeader("Server", "MyServer/1.0");
}
private ByteArrayInputStream makeTrackableBody(int nbytes, final Flag closed) {
byte[] buf = HttpTestUtils.getRandomBytes(nbytes);
ByteArrayInputStream bais = new ByteArrayInputStream(buf) {
@ -76,7 +76,7 @@ public class TestResponseProtocolCompliance {
};
return bais;
}
private HttpResponse makePartialResponse(int nbytes) {
HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
setMinimalResponseHeaders(resp);
@ -84,7 +84,7 @@ public class TestResponseProtocolCompliance {
resp.setHeader("Content-Range","0-127/256");
return resp;
}
@Test
public void consumesBodyIfOriginSendsOneInResponseToHEAD() throws Exception {
HttpRequest req = new HttpHead("http://foo.example.com/");
@ -96,7 +96,7 @@ public class TestResponseProtocolCompliance {
final Flag closed = new Flag();
ByteArrayInputStream bais = makeTrackableBody(nbytes, closed);
resp.setEntity(new InputStreamEntity(bais, -1));
impl.ensureProtocolCompliance(req, resp);
assertNull(resp.getEntity());
assertTrue(closed.set || bais.read() == -1);
@ -108,7 +108,7 @@ public class TestResponseProtocolCompliance {
int nbytes = 128;
HttpResponse resp = makePartialResponse(nbytes);
resp.setEntity(HttpTestUtils.makeBody(nbytes));
impl.ensureProtocolCompliance(req, resp);
}
@ -117,18 +117,18 @@ public class TestResponseProtocolCompliance {
HttpRequest req = new HttpGet("http://foo.example.com/");
int nbytes = 128;
HttpResponse resp = makePartialResponse(nbytes);
final Flag closed = new Flag();
ByteArrayInputStream bais = makeTrackableBody(nbytes, closed);
resp.setEntity(new InputStreamEntity(bais, -1));
try {
impl.ensureProtocolCompliance(req, resp);
} catch (ClientProtocolException expected) {
}
assertTrue(closed.set || bais.read() == -1);
}
@Test
public void consumesBodyOf100ContinueResponseIfItArrives() throws Exception {
HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1);
@ -137,12 +137,12 @@ public class TestResponseProtocolCompliance {
req.setHeader("Content-Type", "application/octet-stream");
HttpEntity postBody = new ByteArrayEntity(HttpTestUtils.getRandomBytes(nbytes));
req.setEntity(postBody);
HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_CONTINUE, "Continue");
final Flag closed = new Flag();
ByteArrayInputStream bais = makeTrackableBody(nbytes, closed);
resp.setEntity(new InputStreamEntity(bais, -1));
try {
impl.ensureProtocolCompliance(req, resp);
} catch (ClientProtocolException expected) {

View File

@ -78,4 +78,4 @@ public interface RedirectStrategy {
HttpResponse response,
HttpContext context) throws ProtocolException;
}
}

View File

@ -57,4 +57,4 @@ public interface ServiceUnavailableRetryStrategy {
*/
long getRetryInterval();
}
}

View File

@ -43,4 +43,4 @@ public interface Idn {
* @return the Unicode domain name
*/
String toUnicode(String punycode);
}
}

View File

@ -72,4 +72,4 @@ public class JdkIdn implements Idn {
}
}
}
}

View File

@ -123,4 +123,4 @@ public class Rfc3492Idn implements Idn {
return output.toString();
}
}
}

View File

@ -49,4 +49,4 @@ public interface DnsResolver {
*/
InetAddress[] resolve(String host) throws UnknownHostException;
}
}

View File

@ -59,4 +59,4 @@ public interface ClientCookie extends Cookie {
boolean containsAttribute(String name);
}
}

View File

@ -44,7 +44,7 @@ import org.apache.http.protocol.HttpContext;
import org.apache.http.client.*;
/**
* {@link HttpClient} implementation that can automatically retry the request in case of
* {@link HttpClient} implementation that can automatically retry the request in case of
* a non-2xx response using the {@link ServiceUnavailableRetryStrategy} interface.
*
* @since 4.2
@ -174,4 +174,4 @@ public class AutoRetryHttpClient implements HttpClient {
return backend.getParams();
}
}
}

View File

@ -110,11 +110,11 @@ public class DefaultHttpRequestRetryHandler implements HttpRequestRetryHandler {
HttpRequest request = (HttpRequest)
context.getAttribute(ExecutionContext.HTTP_REQUEST);
if(requestIsAborted(request)){
return false;
return false;
}
if (handleAsIdempotent(request)) {
// Retry if the request is considered idempotent
return true;
@ -154,7 +154,7 @@ public class DefaultHttpRequestRetryHandler implements HttpRequestRetryHandler {
protected boolean handleAsIdempotent(final HttpRequest request) {
return !(request instanceof HttpEntityEnclosingRequest);
}
protected boolean requestIsAborted(final HttpRequest request) {
return (request instanceof HttpUriRequest && ((HttpUriRequest)request).isAborted());
}

View File

@ -211,4 +211,4 @@ public class DefaultRedirectStrategy implements RedirectStrategy {
}
}
}
}

View File

@ -37,7 +37,7 @@ import org.apache.http.protocol.HttpContext;
* Default implementation of the {@link ServiceUnavailableRetryStrategy} interface.
* that retries <code>503</code> (Service Unavailable) responses for a fixed number of times
* at a fixed interval.
*
*
* @since 4.2
*/
@Immutable

View File

@ -92,4 +92,4 @@ public class InMemoryDnsResolver implements DnsResolver {
return resolvedAddresses;
}
}
}

View File

@ -218,4 +218,4 @@ public class BestMatchSpec implements CookieSpec {
return "best-match";
}
}
}

View File

@ -64,4 +64,4 @@ public class RFC2965CommentUrlAttributeHandler implements CookieAttributeHandler
return true;
}
}
}

View File

@ -64,4 +64,4 @@ public class RFC2965DiscardAttributeHandler implements CookieAttributeHandler {
return true;
}
}
}

View File

@ -191,4 +191,4 @@ public class RFC2965DomainAttributeHandler implements CookieAttributeHandler {
return effectiveHostWithoutDomain.indexOf('.') == -1;
}
}
}

View File

@ -95,4 +95,4 @@ public class RFC2965VersionAttributeHandler implements CookieAttributeHandler {
return true;
}
}
}

View File

@ -512,9 +512,9 @@ public class TestRequestAddCookies {
// Test for ordering adapted from test in Commons HC 3.1
public void testCookieOrder() throws Exception {
HttpRequest request = new BasicHttpRequest("GET", "/foobar/yada/yada");
this.cookieStore.clear();
cookieStore.addCookie(makeCookie("nomatch", "value", "localhost.local", "/noway"));
cookieStore.addCookie(makeCookie("name2", "value", "localhost.local", "/foobar/yada"));
cookieStore.addCookie(makeCookie("name3", "value", "localhost.local", "/foobar"));

View File

@ -327,10 +327,10 @@ public class TestURIUtils {
public void testHTTPCLIENT_911() throws Exception{
Assert.assertEquals(new HttpHost("localhost"),URIUtils.extractHost(new URI("http://localhost/abcd")));
Assert.assertEquals(new HttpHost("localhost"),URIUtils.extractHost(new URI("http://localhost/abcd%3A")));
Assert.assertEquals(new HttpHost("local_host"),URIUtils.extractHost(new URI("http://local_host/abcd")));
Assert.assertEquals(new HttpHost("local_host"),URIUtils.extractHost(new URI("http://local_host/abcd%3A")));
Assert.assertEquals(new HttpHost("localhost",8),URIUtils.extractHost(new URI("http://localhost:8/abcd")));
Assert.assertEquals(new HttpHost("local_host",8),URIUtils.extractHost(new URI("http://local_host:8/abcd")));
@ -345,5 +345,5 @@ public class TestURIUtils {
Assert.assertEquals(new HttpHost("local_host",8080),URIUtils.extractHost(new URI("http://@local_host:8080/abcd")));
}
}

View File

@ -207,4 +207,4 @@ public class TestURLEncodedUtils {
Assert.assertEquals(parameter.getValue(), expectedValue);
}
}
}

View File

@ -267,7 +267,7 @@ public class TestHostnameVerifier {
checkMatching(bhv, "s.a.b.c", cns, alt, false); // OK
checkMatching(shv, "s.a.b.c", cns, alt, true); // subdomain not OK
cns = new String []{};
alt = new String []{"dummy", "*.b.c"}; // check matches against all alts
checkMatching(bhv, "a.b.c", cns, alt, false); // OK
@ -275,28 +275,28 @@ public class TestHostnameVerifier {
checkMatching(bhv, "s.a.b.c", cns, alt, false); // OK
checkMatching(shv, "s.a.b.c", cns, alt, true); // subdomain not OK
alt = new String []{"*.gov.uk"};
checkMatching(bhv, "a.gov.uk", cns, alt, true); // Bad 2TLD
checkMatching(shv, "a.gov.uk", cns, alt, true); // Bad 2TLD
checkMatching(bhv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD
checkMatching(shv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD/no subdomain allowed
alt = new String []{"*.gov.com"};
checkMatching(bhv, "a.gov.com", cns, alt, false); // OK, gov not 2TLD here
checkMatching(shv, "a.gov.com", cns, alt, false); // OK, gov not 2TLD here
checkMatching(bhv, "s.a.gov.com", cns, alt, false); // OK, gov not 2TLD here
checkMatching(shv, "s.a.gov.com", cns, alt, true); // no subdomain allowed
cns = new String []{"a*.gov.uk"}; // 2TLD check applies to wildcards
checkMatching(bhv, "a.gov.uk", cns, alt, true); // Bad 2TLD
checkMatching(shv, "a.gov.uk", cns, alt, true); // Bad 2TLD
checkMatching(bhv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD
checkMatching(shv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD/no subdomain allowed
}
@Test
@ -305,7 +305,7 @@ public class TestHostnameVerifier {
String alt[] = {};
X509HostnameVerifier bhv = new BrowserCompatHostnameVerifier();
X509HostnameVerifier shv = new StrictHostnameVerifier();
cns = new String []{"a*.b.c"}; // component part
checkMatching(bhv, "a.b.c", cns, alt, false); // OK
checkMatching(shv, "a.b.c", cns, alt, false); // OK
@ -317,10 +317,10 @@ public class TestHostnameVerifier {
checkWildcard("s*.gov.uk", false); // 2 character TLD, invalid 2TLD
checkWildcard("s*.gouv.uk", false); // 2 character TLD, invalid 2TLD
}
// Helper
private void checkWildcard(String host, boolean isOK) {
Assert.assertTrue(host+" should be "+isOK, isOK==AbstractVerifier.acceptableCountryWildcard(host));
Assert.assertTrue(host+" should be "+isOK, isOK==AbstractVerifier.acceptableCountryWildcard(host));
}
@Test

View File

@ -28,11 +28,11 @@ package org.apache.http.impl.client;
public class MockClock implements Clock {
private long t = System.currentTimeMillis();
public long getCurrentTime() {
return t;
}
public void setCurrentTime(long now) {
t = now;
}

View File

@ -52,33 +52,33 @@ public class TestAIMDBackoffManager {
impl = new AIMDBackoffManager(connPerRoute, clock);
impl.setPerHostConnectionCap(10);
}
@Test
public void isABackoffManager() {
assertTrue(impl instanceof BackoffManager);
}
@Test
public void halvesConnectionsOnBackoff() {
connPerRoute.setMaxForRoute(route, 4);
impl.backOff(route);
assertEquals(2, connPerRoute.getMaxForRoute(route));
}
@Test
public void doesNotBackoffBelowOneConnection() {
connPerRoute.setMaxForRoute(route, 1);
impl.backOff(route);
assertEquals(1, connPerRoute.getMaxForRoute(route));
assertEquals(1, connPerRoute.getMaxForRoute(route));
}
@Test
public void increasesByOneOnProbe() {
connPerRoute.setMaxForRoute(route, 2);
impl.probe(route);
assertEquals(3, connPerRoute.getMaxForRoute(route));
assertEquals(3, connPerRoute.getMaxForRoute(route));
}
@Test
public void doesNotIncreaseBeyondPerHostMaxOnProbe() {
connPerRoute.setDefaultMaxPerRoute(5);
@ -87,7 +87,7 @@ public class TestAIMDBackoffManager {
impl.probe(route);
assertEquals(5, connPerRoute.getMaxForRoute(route));
}
@Test
public void backoffDoesNotAdjustDuringCoolDownPeriod() {
connPerRoute.setMaxForRoute(route, 4);
@ -99,7 +99,7 @@ public class TestAIMDBackoffManager {
impl.backOff(route);
assertEquals(max, connPerRoute.getMaxForRoute(route));
}
@Test
public void backoffStillAdjustsAfterCoolDownPeriod() {
connPerRoute.setMaxForRoute(route, 8);
@ -111,9 +111,9 @@ public class TestAIMDBackoffManager {
impl.backOff(route);
assertTrue(max == 1 || max > connPerRoute.getMaxForRoute(route));
}
@Test
public void probeDoesNotAdjustDuringCooldownPeriod() {
public void probeDoesNotAdjustDuringCooldownPeriod() {
connPerRoute.setMaxForRoute(route, 4);
long now = System.currentTimeMillis();
clock.setCurrentTime(now);
@ -135,7 +135,7 @@ public class TestAIMDBackoffManager {
impl.probe(route);
assertTrue(max < connPerRoute.getMaxForRoute(route));
}
@Test
public void willBackoffImmediatelyEvenAfterAProbe() {
connPerRoute.setMaxForRoute(route, 8);
@ -147,7 +147,7 @@ public class TestAIMDBackoffManager {
impl.backOff(route);
assertTrue(connPerRoute.getMaxForRoute(route) < max);
}
@Test
public void backOffFactorIsConfigurable() {
connPerRoute.setMaxForRoute(route, 10);
@ -155,7 +155,7 @@ public class TestAIMDBackoffManager {
impl.backOff(route);
assertEquals(9, connPerRoute.getMaxForRoute(route));
}
@Test
public void coolDownPeriodIsConfigurable() {
long cd = new Random().nextLong() / 2;

View File

@ -48,34 +48,34 @@ public class TestDefaultBackoffStrategy {
public void setUp() {
impl = new DefaultBackoffStrategy();
}
@Test
public void isABackoffStrategy() {
assertTrue(impl instanceof ConnectionBackoffStrategy);
}
@Test
public void backsOffForSocketTimeouts() {
assertTrue(impl.shouldBackoff(new SocketTimeoutException()));
}
@Test
public void backsOffForConnectionTimeouts() {
assertTrue(impl.shouldBackoff(new ConnectException()));
}
@Test
public void doesNotBackOffForConnectionManagerTimeout() {
assertFalse(impl.shouldBackoff(new ConnectionPoolTimeoutException()));
}
@Test
public void backsOffForServiceUnavailable() {
HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_SERVICE_UNAVAILABLE, "Service Unavailable");
assertTrue(impl.shouldBackoff(resp));
}
@Test
public void doesNotBackOffForNon503StatusCodes() {
for(int i = 100; i <= 599; i++) {

View File

@ -40,73 +40,73 @@ import org.junit.Test;
public class TestDefaultHttpRequestRetryHandler {
@Test
public void noRetryOnConnectTimeout() throws Exception {
HttpContext context = mock(HttpContext.class);
HttpUriRequest request = mock(HttpUriRequest.class);
DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
Assert.assertEquals(3, retryHandler.getRetryCount());
when(request.isAborted()).thenReturn(Boolean.FALSE);
when(context.getAttribute(ExecutionContext.HTTP_REQUEST)).thenReturn(request);
Assert.assertFalse(retryHandler.retryRequest(new ConnectTimeoutException(), 1, context));
}
@Test
public void noRetryOnUnknownHost() throws Exception {
HttpContext context = mock(HttpContext.class);
HttpUriRequest request = mock(HttpUriRequest.class);
DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
when(request.isAborted()).thenReturn(Boolean.FALSE);
when(context.getAttribute(ExecutionContext.HTTP_REQUEST)).thenReturn(request);
Assert.assertFalse(retryHandler.retryRequest(new UnknownHostException(), 1, context));
}
@Test
public void noRetryOnAbortedRequests() throws Exception{
HttpContext context = mock(HttpContext.class);
HttpUriRequest request = mock(HttpUriRequest.class);
DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
when(request.isAborted()).thenReturn(Boolean.TRUE);
when(context.getAttribute(ExecutionContext.HTTP_REQUEST)).thenReturn(request);
Assert.assertFalse(retryHandler.retryRequest(new IOException(),3,context));
}
@Test
public void retryOnNonAbortedRequests() throws Exception{
HttpContext context = mock(HttpContext.class);
HttpUriRequest request = mock(HttpUriRequest.class);
DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
when(request.isAborted()).thenReturn(Boolean.FALSE);
when(context.getAttribute(ExecutionContext.HTTP_REQUEST)).thenReturn(request);
Assert.assertTrue(retryHandler.retryRequest(new IOException(),3,context));
}
@Test
public void noRetryOnConnectionTimeout() throws Exception{
HttpContext context = mock(HttpContext.class);
HttpUriRequest request = mock(HttpUriRequest.class);
DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
when(request.isAborted()).thenReturn(false);
when(context.getAttribute(ExecutionContext.HTTP_REQUEST)).thenReturn(request);
Assert.assertFalse(retryHandler.retryRequest(new ConnectTimeoutException(),3,context));
}
}
}

View File

@ -43,12 +43,12 @@ public class TestNullBackoffStrategy {
public void setUp() {
impl = new NullBackoffStrategy();
}
@Test
public void doesNotBackoffForThrowables() {
assertFalse(impl.shouldBackoff(new Exception()));
}
@Test
public void doesNotBackoffForResponses() {
HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1,

View File

@ -54,7 +54,7 @@ public class ConnPoolBench {
oldPool(c, reps);
newPool(c, reps);
}
public static void newPool(int c, long reps) throws Exception {
Log log = LogFactory.getLog(ConnPoolBench.class);

View File

@ -82,4 +82,4 @@ public class TestDefaultClientConnectOperator {
return new InetAddress[] { InetAddress.getByAddress(byteIpAddress) };
}
}
}

View File

@ -44,7 +44,6 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>${httpcore.version}</version>
<scope>compile</scope>
</dependency>
<!-- Not currently used

View File

@ -103,7 +103,7 @@ public class HttpMultipart {
/**
* Creates an instance with the specified settings.
*
*
* @param subType mime subtype - must not be {@code null}
* @param charset the character set to use. May be {@code null}, in which case {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used.
* @param boundary to use - must not be {@code null}
@ -128,7 +128,7 @@ public class HttpMultipart {
/**
* Creates an instance with the specified settings.
* Mode is set to {@link HttpMultipartMode#STRICT}
*
*
* @param subType mime subtype - must not be {@code null}
* @param charset the character set to use. May be {@code null}, in which case {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used.
* @param boundary to use - must not be {@code null}

View File

@ -78,7 +78,7 @@ public class StringBody extends AbstractContentBody {
/**
* Create a StringBody from the specified text, mime type and character set.
*
*
* @param text to be used for the body, not {@code null}
* @param mimeType the mime type, not {@code null}
* @param charset the character set, may be {@code null}, in which case the US-ASCII charset is used
@ -103,7 +103,7 @@ public class StringBody extends AbstractContentBody {
/**
* Create a StringBody from the specified text and character set.
* The mime type is set to "text/plain".
*
*
* @param text to be used for the body, not {@code null}
* @param charset the character set, may be {@code null}, in which case the US-ASCII charset is used
* @throws UnsupportedEncodingException
@ -117,7 +117,7 @@ public class StringBody extends AbstractContentBody {
* Create a StringBody from the specified text.
* The mime type is set to "text/plain".
* The hosts default charset is used.
*
*
* @param text to be used for the body, not {@code null}
* @throws UnsupportedEncodingException
* @throws IllegalArgumentException if the {@code text} parameter is null

View File

@ -32,7 +32,6 @@
<relativePath>../project/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcomponents-client</artifactId>
<name>HttpComponents Client</name>
<version>4.2-alpha1-SNAPSHOT</version>