HTTP Cache API refactoring: entry validation logic factored out from CacheEntry to a separate policy class; HttpCacheEntry should now contain (almost) no protocol specific code
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@966642 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8cf6a94f60
commit
7205e7d340
|
@ -24,7 +24,7 @@
|
|||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
package org.apache.http.client.cache;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
@ -35,5 +35,5 @@ import org.apache.http.message.HeaderGroup;
|
|||
class CachedHeaderGroup extends HeaderGroup implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4572663568087431896L;
|
||||
|
||||
|
||||
}
|
|
@ -24,7 +24,7 @@
|
|||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
package org.apache.http.client.cache;
|
||||
|
||||
import org.apache.http.annotation.Immutable;
|
||||
|
||||
|
@ -32,7 +32,7 @@ import org.apache.http.annotation.Immutable;
|
|||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
class HeaderConstants {
|
||||
public class HeaderConstants {
|
||||
|
||||
public static final String GET_METHOD = "GET";
|
||||
public static final String HEAD_METHOD = "HEAD";
|
|
@ -29,15 +29,15 @@ package org.apache.http.client.cache;
|
|||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public interface HttpCache<K, E> {
|
||||
public interface HttpCache {
|
||||
|
||||
void putEntry(K key, E entry) throws HttpCacheOperationException;
|
||||
void putEntry(String key, HttpCacheEntry entry) throws HttpCacheOperationException;
|
||||
|
||||
E getEntry(K key) throws HttpCacheOperationException;
|
||||
HttpCacheEntry getEntry(String key) throws HttpCacheOperationException;
|
||||
|
||||
void removeEntry(K key) throws HttpCacheOperationException;
|
||||
void removeEntry(String key) throws HttpCacheOperationException;
|
||||
|
||||
void updateEntry(
|
||||
K key, HttpCacheUpdateCallback<E> callback) throws HttpCacheOperationException;
|
||||
String key, HttpCacheUpdateCallback callback) throws HttpCacheOperationException;
|
||||
|
||||
}
|
||||
|
|
218
httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java
vendored
Normal file
218
httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.client.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
|
||||
/**
|
||||
* Structure used to store an {@link HttpResponse} in a cache
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class HttpCacheEntry implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6300496422359477413L;
|
||||
|
||||
private final Date requestDate;
|
||||
private final Date responseDate;
|
||||
private final StatusLine statusLine;
|
||||
private final CachedHeaderGroup responseHeaders;
|
||||
private final HttpEntity body;
|
||||
private final Set<String> variantURIs;
|
||||
|
||||
/**
|
||||
* Create a new {@link HttpCacheEntry}
|
||||
*
|
||||
* @param requestDate
|
||||
* Date/time when the request was made (Used for age
|
||||
* calculations)
|
||||
* @param responseDate
|
||||
* Date/time that the response came back (Used for age
|
||||
* calculations)
|
||||
* @param version
|
||||
* HTTP Response Version
|
||||
* @param responseHeaders
|
||||
* Header[] from original HTTP Response
|
||||
* @param body
|
||||
* HttpEntity representing the body of the response
|
||||
* @param status
|
||||
* Numeric HTTP Status Code
|
||||
* @param reason
|
||||
* String message from HTTP Status Line
|
||||
*/
|
||||
public HttpCacheEntry(
|
||||
final Date requestDate,
|
||||
final Date responseDate,
|
||||
final StatusLine statusLine,
|
||||
final Header[] responseHeaders,
|
||||
final HttpEntity body,
|
||||
final Set<String> variants) {
|
||||
super();
|
||||
if (requestDate == null) {
|
||||
throw new IllegalArgumentException("Request date may not be null");
|
||||
}
|
||||
if (responseDate == null) {
|
||||
throw new IllegalArgumentException("Response date may not be null");
|
||||
}
|
||||
if (statusLine == null) {
|
||||
throw new IllegalArgumentException("Status line may not be null");
|
||||
}
|
||||
if (responseHeaders == null) {
|
||||
throw new IllegalArgumentException("Response headers may not be null");
|
||||
}
|
||||
if (body == null) {
|
||||
throw new IllegalArgumentException("Response body may not be null");
|
||||
}
|
||||
this.requestDate = requestDate;
|
||||
this.responseDate = responseDate;
|
||||
this.statusLine = statusLine;
|
||||
this.responseHeaders = new CachedHeaderGroup();
|
||||
this.responseHeaders.setHeaders(responseHeaders);
|
||||
this.body = body;
|
||||
this.variantURIs = variants != null ? new HashSet<String>(variants) : new HashSet<String>();
|
||||
|
||||
}
|
||||
|
||||
public StatusLine getStatusLine() {
|
||||
return this.statusLine;
|
||||
}
|
||||
|
||||
public ProtocolVersion getProtocolVersion() {
|
||||
return this.statusLine.getProtocolVersion();
|
||||
}
|
||||
|
||||
public String getReasonPhrase() {
|
||||
return this.statusLine.getReasonPhrase();
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return this.statusLine.getStatusCode();
|
||||
}
|
||||
|
||||
public Date getRequestDate() {
|
||||
return requestDate;
|
||||
}
|
||||
|
||||
public Date getResponseDate() {
|
||||
return responseDate;
|
||||
}
|
||||
|
||||
public HttpEntity getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public Header[] getAllHeaders() {
|
||||
return responseHeaders.getAllHeaders();
|
||||
}
|
||||
|
||||
public Header getFirstHeader(String name) {
|
||||
return responseHeaders.getFirstHeader(name);
|
||||
}
|
||||
|
||||
public Header[] getHeaders(String name) {
|
||||
return responseHeaders.getHeaders(name);
|
||||
}
|
||||
|
||||
public boolean hasVariants() {
|
||||
return getFirstHeader(HeaderConstants.VARY) != null;
|
||||
}
|
||||
|
||||
public Set<String> getVariantURIs() {
|
||||
return Collections.unmodifiableSet(this.variantURIs);
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
|
||||
// write CacheEntry
|
||||
out.defaultWriteObject();
|
||||
|
||||
// write (non-serializable) responseHeaders
|
||||
if (null == responseHeaders || responseHeaders.getAllHeaders().length < 1)
|
||||
return;
|
||||
int headerCount = responseHeaders.getAllHeaders().length;
|
||||
Header[] headers = responseHeaders.getAllHeaders();
|
||||
String[][] sheaders = new String[headerCount][2];
|
||||
for (int i = 0; i < headerCount; i++) {
|
||||
sheaders[i][0] = headers[i].getName();
|
||||
sheaders[i][1] = headers[i].getValue();
|
||||
}
|
||||
out.writeObject(sheaders);
|
||||
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
|
||||
// read CacheEntry
|
||||
in.defaultReadObject();
|
||||
|
||||
// read (non-serializable) responseHeaders
|
||||
String[][] sheaders = (String[][]) in.readObject();
|
||||
if (null == sheaders || sheaders.length < 1)
|
||||
return;
|
||||
BasicHeader[] headers = new BasicHeader[sheaders.length];
|
||||
for (int i = 0; i < sheaders.length; i++) {
|
||||
String[] sheader = sheaders[i];
|
||||
headers[i] = new BasicHeader(sheader[0], sheader[1]);
|
||||
}
|
||||
|
||||
this.responseHeaders.setHeaders(headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[request date=" + this.requestDate + "; response date=" + this.responseDate
|
||||
+ "; statusLine=" + this.statusLine + "]";
|
||||
}
|
||||
|
||||
public static HttpCacheEntry copyWithVariant(final HttpCacheEntry entry, final String variantURI){
|
||||
Set<String> variants = new HashSet<String>(entry.getVariantURIs());
|
||||
variants.add(variantURI);
|
||||
return new HttpCacheEntry(
|
||||
entry.getRequestDate(),
|
||||
entry.getResponseDate(),
|
||||
entry.getStatusLine(),
|
||||
entry.getAllHeaders(),
|
||||
entry.getBody(), variants);
|
||||
}
|
||||
|
||||
}
|
|
@ -26,7 +26,7 @@
|
|||
*/
|
||||
package org.apache.http.client.cache;
|
||||
|
||||
public interface HttpCacheUpdateCallback<E> {
|
||||
public interface HttpCacheUpdateCallback {
|
||||
|
||||
/**
|
||||
* Returns the new cache entry that should replace an existing one.
|
||||
|
@ -41,6 +41,6 @@ public interface HttpCacheUpdateCallback<E> {
|
|||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
E update(E existing) throws HttpCacheOperationException;
|
||||
HttpCacheEntry update(HttpCacheEntry existing) throws HttpCacheOperationException;
|
||||
|
||||
}
|
|
@ -31,6 +31,7 @@ import java.util.Map;
|
|||
|
||||
import org.apache.http.annotation.ThreadSafe;
|
||||
import org.apache.http.client.cache.HttpCache;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.client.cache.HttpCacheOperationException;
|
||||
import org.apache.http.client.cache.HttpCacheUpdateCallback;
|
||||
|
||||
|
@ -40,15 +41,15 @@ import org.apache.http.client.cache.HttpCacheUpdateCallback;
|
|||
* @since 4.1
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class BasicHttpCache implements HttpCache<String, CacheEntry> {
|
||||
public class BasicHttpCache implements HttpCache {
|
||||
|
||||
private final LinkedHashMap<String, CacheEntry> baseMap = new LinkedHashMap<String, CacheEntry>(
|
||||
private final LinkedHashMap<String, HttpCacheEntry> baseMap = new LinkedHashMap<String, HttpCacheEntry>(
|
||||
20, 0.75f, true) {
|
||||
|
||||
private static final long serialVersionUID = -7750025207539768511L;
|
||||
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<String, CacheEntry> eldest) {
|
||||
protected boolean removeEldestEntry(Map.Entry<String, HttpCacheEntry> eldest) {
|
||||
return size() > maxEntries;
|
||||
}
|
||||
|
||||
|
@ -61,14 +62,14 @@ public class BasicHttpCache implements HttpCache<String, CacheEntry> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Places a CacheEntry in the cache
|
||||
* Places a HttpCacheEntry in the cache
|
||||
*
|
||||
* @param url
|
||||
* Url to use as the cache key
|
||||
* @param entry
|
||||
* CacheEntry to place in the cache
|
||||
* HttpCacheEntry to place in the cache
|
||||
*/
|
||||
public synchronized void putEntry(String url, CacheEntry entry) {
|
||||
public synchronized void putEntry(String url, HttpCacheEntry entry) {
|
||||
baseMap.put(url, entry);
|
||||
}
|
||||
|
||||
|
@ -77,14 +78,14 @@ public class BasicHttpCache implements HttpCache<String, CacheEntry> {
|
|||
*
|
||||
* @param url
|
||||
* Url that is the cache key
|
||||
* @return CacheEntry if one exists, or null for cache miss
|
||||
* @return HttpCacheEntry if one exists, or null for cache miss
|
||||
*/
|
||||
public synchronized CacheEntry getEntry(String url) {
|
||||
public synchronized HttpCacheEntry getEntry(String url) {
|
||||
return baseMap.get(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a CacheEntry from the cache
|
||||
* Removes a HttpCacheEntry from the cache
|
||||
*
|
||||
* @param url
|
||||
* Url that is the cache key
|
||||
|
@ -95,8 +96,8 @@ public class BasicHttpCache implements HttpCache<String, CacheEntry> {
|
|||
|
||||
public synchronized void updateEntry(
|
||||
String url,
|
||||
HttpCacheUpdateCallback<CacheEntry> callback) throws HttpCacheOperationException {
|
||||
CacheEntry existingEntry = baseMap.get(url);
|
||||
HttpCacheUpdateCallback callback) throws HttpCacheOperationException {
|
||||
HttpCacheEntry existingEntry = baseMap.get(url);
|
||||
baseMap.put(url, callback.update(existingEntry));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,412 +0,0 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.impl.cookie.DateParseException;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* Structure used to store an {@link HttpResponse} in a cache
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class CacheEntry implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6300496422359477413L;
|
||||
|
||||
public static final long MAX_AGE = 2147483648L;
|
||||
|
||||
private final Date requestDate;
|
||||
private final Date responseDate;
|
||||
private final ProtocolVersion version;
|
||||
private final int status;
|
||||
private final String reason;
|
||||
private final CachedHeaderGroup responseHeaders;
|
||||
private final HttpEntity body;
|
||||
private final Set<String> variantURIs;
|
||||
|
||||
/**
|
||||
* Create a new {@link CacheEntry}
|
||||
*
|
||||
* @param requestDate
|
||||
* Date/time when the request was made (Used for age
|
||||
* calculations)
|
||||
* @param responseDate
|
||||
* Date/time that the response came back (Used for age
|
||||
* calculations)
|
||||
* @param version
|
||||
* HTTP Response Version
|
||||
* @param responseHeaders
|
||||
* Header[] from original HTTP Response
|
||||
* @param body
|
||||
* HttpEntity representing the body of the response
|
||||
* @param status
|
||||
* Numeric HTTP Status Code
|
||||
* @param reason
|
||||
* String message from HTTP Status Line
|
||||
*/
|
||||
public CacheEntry(Date requestDate, Date responseDate, ProtocolVersion version,
|
||||
Header[] responseHeaders, HttpEntity body, int status, String reason) {
|
||||
super();
|
||||
this.requestDate = requestDate;
|
||||
this.responseDate = responseDate;
|
||||
this.version = version;
|
||||
this.responseHeaders = new CachedHeaderGroup();
|
||||
this.responseHeaders.setHeaders(responseHeaders);
|
||||
this.status = status;
|
||||
this.reason = reason;
|
||||
this.body = body;
|
||||
this.variantURIs = new HashSet<String>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used to create a copy of an existing entry, while adding another variant URI to it.
|
||||
*
|
||||
* @param entry CacheEntry to be duplicated
|
||||
* @param variantURI URI to add
|
||||
*/
|
||||
private CacheEntry(CacheEntry entry, String variantURI){
|
||||
this(entry.getRequestDate(),
|
||||
entry.getResponseDate(),
|
||||
entry.getProtocolVersion(),
|
||||
entry.getAllHeaders(),
|
||||
entry.body,
|
||||
entry.getStatusCode(),
|
||||
entry.getReasonPhrase());
|
||||
this.variantURIs.addAll(entry.getVariantURIs());
|
||||
this.variantURIs.add(variantURI);
|
||||
}
|
||||
|
||||
public CacheEntry copyWithVariant(String variantURI){
|
||||
return new CacheEntry(this,variantURI);
|
||||
}
|
||||
|
||||
public ProtocolVersion getProtocolVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getReasonPhrase() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Date getRequestDate() {
|
||||
return requestDate;
|
||||
}
|
||||
|
||||
public Date getResponseDate() {
|
||||
return responseDate;
|
||||
}
|
||||
|
||||
public HttpEntity getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public Header[] getAllHeaders() {
|
||||
return responseHeaders.getAllHeaders();
|
||||
}
|
||||
|
||||
public Header getFirstHeader(String name) {
|
||||
return responseHeaders.getFirstHeader(name);
|
||||
}
|
||||
|
||||
public Header[] getHeaders(String name) {
|
||||
return responseHeaders.getHeaders(name);
|
||||
}
|
||||
|
||||
public long getCurrentAgeSecs() {
|
||||
return getCorrectedInitialAgeSecs() + getResidentTimeSecs();
|
||||
}
|
||||
|
||||
public long getFreshnessLifetimeSecs() {
|
||||
long maxage = getMaxAge();
|
||||
if (maxage > -1)
|
||||
return maxage;
|
||||
|
||||
Date dateValue = getDateValue();
|
||||
if (dateValue == null)
|
||||
return 0L;
|
||||
|
||||
Date expiry = getExpirationDate();
|
||||
if (expiry == null)
|
||||
return 0;
|
||||
long diff = expiry.getTime() - dateValue.getTime();
|
||||
return (diff / 1000);
|
||||
}
|
||||
|
||||
public boolean isResponseFresh() {
|
||||
return (getCurrentAgeSecs() < getFreshnessLifetimeSecs());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean indicating whether ETag or Last-Modified responseHeaders
|
||||
* are present
|
||||
*/
|
||||
public boolean isRevalidatable() {
|
||||
return getFirstHeader(HeaderConstants.ETAG) != null
|
||||
|| getFirstHeader(HeaderConstants.LAST_MODIFIED) != null;
|
||||
|
||||
}
|
||||
|
||||
public boolean modifiedSince(HttpRequest request) {
|
||||
Header unmodHeader = request.getFirstHeader(HeaderConstants.IF_UNMODIFIED_SINCE);
|
||||
|
||||
if (unmodHeader == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Date unmodifiedSinceDate = DateUtils.parseDate(unmodHeader.getValue());
|
||||
Date lastModifiedDate = DateUtils.parseDate(getFirstHeader(
|
||||
HeaderConstants.LAST_MODIFIED).getValue());
|
||||
|
||||
if (unmodifiedSinceDate.before(lastModifiedDate)) {
|
||||
return true;
|
||||
}
|
||||
} catch (DateParseException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean indicating whether any Vary responseHeaders are present
|
||||
*/
|
||||
public boolean hasVariants() {
|
||||
return (getFirstHeader(HeaderConstants.VARY) != null);
|
||||
}
|
||||
|
||||
public Set<String> getVariantURIs() {
|
||||
return Collections.unmodifiableSet(this.variantURIs);
|
||||
}
|
||||
|
||||
public boolean mustRevalidate() {
|
||||
return hasCacheControlDirective("must-revalidate");
|
||||
}
|
||||
public boolean proxyRevalidate() {
|
||||
return hasCacheControlDirective("proxy-revalidate");
|
||||
}
|
||||
|
||||
Date getDateValue() {
|
||||
Header dateHdr = getFirstHeader(HTTP.DATE_HEADER);
|
||||
if (dateHdr == null)
|
||||
return null;
|
||||
try {
|
||||
return DateUtils.parseDate(dateHdr.getValue());
|
||||
} catch (DateParseException dpe) {
|
||||
// ignore malformed date
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
long getContentLengthValue() {
|
||||
Header cl = getFirstHeader(HTTP.CONTENT_LEN);
|
||||
if (cl == null)
|
||||
return -1;
|
||||
|
||||
try {
|
||||
return Long.parseLong(cl.getValue());
|
||||
} catch (NumberFormatException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return boolean indicating whether actual length matches Content-Length
|
||||
*/
|
||||
boolean contentLengthHeaderMatchesActualLength() {
|
||||
return getContentLengthValue() == body.getContentLength();
|
||||
}
|
||||
|
||||
long getApparentAgeSecs() {
|
||||
Date dateValue = getDateValue();
|
||||
if (dateValue == null)
|
||||
return MAX_AGE;
|
||||
long diff = responseDate.getTime() - dateValue.getTime();
|
||||
if (diff < 0L)
|
||||
return 0;
|
||||
return (diff / 1000);
|
||||
}
|
||||
|
||||
long getAgeValue() {
|
||||
long ageValue = 0;
|
||||
for (Header hdr : getHeaders(HeaderConstants.AGE)) {
|
||||
long hdrAge;
|
||||
try {
|
||||
hdrAge = Long.parseLong(hdr.getValue());
|
||||
if (hdrAge < 0) {
|
||||
hdrAge = MAX_AGE;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
hdrAge = MAX_AGE;
|
||||
}
|
||||
ageValue = (hdrAge > ageValue) ? hdrAge : ageValue;
|
||||
}
|
||||
return ageValue;
|
||||
}
|
||||
|
||||
long getCorrectedReceivedAgeSecs() {
|
||||
long apparentAge = getApparentAgeSecs();
|
||||
long ageValue = getAgeValue();
|
||||
return (apparentAge > ageValue) ? apparentAge : ageValue;
|
||||
}
|
||||
|
||||
long getResponseDelaySecs() {
|
||||
long diff = responseDate.getTime() - requestDate.getTime();
|
||||
return (diff / 1000L);
|
||||
}
|
||||
|
||||
long getCorrectedInitialAgeSecs() {
|
||||
return getCorrectedReceivedAgeSecs() + getResponseDelaySecs();
|
||||
}
|
||||
|
||||
Date getCurrentDate() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
long getResidentTimeSecs() {
|
||||
long diff = getCurrentDate().getTime() - responseDate.getTime();
|
||||
return (diff / 1000L);
|
||||
}
|
||||
|
||||
long getMaxAge() {
|
||||
long maxage = -1;
|
||||
for (Header hdr : getHeaders(HeaderConstants.CACHE_CONTROL)) {
|
||||
for (HeaderElement elt : hdr.getElements()) {
|
||||
if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())
|
||||
|| "s-maxage".equals(elt.getName())) {
|
||||
try {
|
||||
long currMaxAge = Long.parseLong(elt.getValue());
|
||||
if (maxage == -1 || currMaxAge < maxage) {
|
||||
maxage = currMaxAge;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
// be conservative if can't parse
|
||||
maxage = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxage;
|
||||
}
|
||||
|
||||
Date getExpirationDate() {
|
||||
Header expiresHeader = getFirstHeader(HeaderConstants.EXPIRES);
|
||||
if (expiresHeader == null)
|
||||
return null;
|
||||
try {
|
||||
return DateUtils.parseDate(expiresHeader.getValue());
|
||||
} catch (DateParseException dpe) {
|
||||
// malformed expires header
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean hasCacheControlDirective(String directive) {
|
||||
for(Header h : responseHeaders.getHeaders("Cache-Control")) {
|
||||
for(HeaderElement elt : h.getElements()) {
|
||||
if (directive.equalsIgnoreCase(elt.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
|
||||
// write CacheEntry
|
||||
out.defaultWriteObject();
|
||||
|
||||
// write (non-serializable) responseHeaders
|
||||
if (null == responseHeaders || responseHeaders.getAllHeaders().length < 1)
|
||||
return;
|
||||
int headerCount = responseHeaders.getAllHeaders().length;
|
||||
Header[] headers = responseHeaders.getAllHeaders();
|
||||
String[][] sheaders = new String[headerCount][2];
|
||||
for (int i = 0; i < headerCount; i++) {
|
||||
sheaders[i][0] = headers[i].getName();
|
||||
sheaders[i][1] = headers[i].getValue();
|
||||
}
|
||||
out.writeObject(sheaders);
|
||||
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
|
||||
// read CacheEntry
|
||||
in.defaultReadObject();
|
||||
|
||||
// read (non-serializable) responseHeaders
|
||||
String[][] sheaders = (String[][]) in.readObject();
|
||||
if (null == sheaders || sheaders.length < 1)
|
||||
return;
|
||||
BasicHeader[] headers = new BasicHeader[sheaders.length];
|
||||
for (int i = 0; i < sheaders.length; i++) {
|
||||
String[] sheader = sheaders[i];
|
||||
headers[i] = new BasicHeader(sheader[0], sheader[1]);
|
||||
}
|
||||
|
||||
this.responseHeaders.setHeaders(headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[request date=" + requestDate + "; response date=" + responseDate
|
||||
+ "; status=" + status + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -30,6 +30,7 @@ import java.util.Date;
|
|||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
|
||||
/**
|
||||
* Generates a {@link CacheEntry} from a {@link HttpResponse}
|
||||
|
@ -39,18 +40,18 @@ import org.apache.http.annotation.Immutable;
|
|||
@Immutable
|
||||
class CacheEntryGenerator {
|
||||
|
||||
public CacheEntry generateEntry(
|
||||
Date requestDate,
|
||||
Date responseDate,
|
||||
public HttpCacheEntry generateEntry(
|
||||
Date requestDate,
|
||||
Date responseDate,
|
||||
HttpResponse response,
|
||||
byte[] body) {
|
||||
CacheEntity entity = new CacheEntity(body, response);
|
||||
return new CacheEntry(requestDate,
|
||||
return new HttpCacheEntry(requestDate,
|
||||
responseDate,
|
||||
response.getProtocolVersion(),
|
||||
response.getStatusLine(),
|
||||
response.getAllHeaders(),
|
||||
entity,
|
||||
response.getStatusLine().getStatusCode(),
|
||||
response.getStatusLine().getReasonPhrase());
|
||||
null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,12 +36,14 @@ import java.util.ListIterator;
|
|||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.impl.cookie.DateParseException;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* Update a {@link CacheEntry} with new or updated information based on the latest
|
||||
* Update a {@link HttpCacheEntry} with new or updated information based on the latest
|
||||
* 200 or 304 status responses from the Server. Use the {@link HttpResponse} to perform
|
||||
* the update.
|
||||
*
|
||||
|
@ -57,27 +59,25 @@ class CacheEntryUpdater {
|
|||
* @param requestDate When the request was performed
|
||||
* @param responseDate When the response was gotten
|
||||
* @param response The HttpResponse from the backend server call
|
||||
* @return CacheEntry an updated version of the cache entry
|
||||
* @return HttpCacheEntry an updated version of the cache entry
|
||||
* @throws java.io.IOException if something bad happens while trying to read the body from the original entry
|
||||
*/
|
||||
public CacheEntry updateCacheEntry(
|
||||
CacheEntry entry,
|
||||
public HttpCacheEntry updateCacheEntry(
|
||||
HttpCacheEntry entry,
|
||||
Date requestDate,
|
||||
Date responseDate,
|
||||
HttpResponse response) throws IOException {
|
||||
|
||||
Header[] mergedHeaders = mergeHeaders(entry, response);
|
||||
CacheEntry updated = new CacheEntry(requestDate, responseDate,
|
||||
entry.getProtocolVersion(),
|
||||
HttpCacheEntry updated = new HttpCacheEntry(requestDate, responseDate,
|
||||
entry.getStatusLine(),
|
||||
mergedHeaders,
|
||||
entry.getBody(),
|
||||
entry.getStatusCode(),
|
||||
entry.getReasonPhrase());
|
||||
|
||||
null);
|
||||
return updated;
|
||||
}
|
||||
|
||||
protected Header[] mergeHeaders(CacheEntry entry, HttpResponse response) {
|
||||
protected Header[] mergeHeaders(HttpCacheEntry entry, HttpResponse response) {
|
||||
List<Header> cacheEntryHeaderList = new ArrayList<Header>(Arrays.asList(entry
|
||||
.getAllHeaders()));
|
||||
|
||||
|
@ -112,7 +112,7 @@ class CacheEntryUpdater {
|
|||
}
|
||||
}
|
||||
|
||||
private void removeCacheEntry1xxWarnings(List<Header> cacheEntryHeaderList, CacheEntry entry) {
|
||||
private void removeCacheEntry1xxWarnings(List<Header> cacheEntryHeaderList, HttpCacheEntry entry) {
|
||||
ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
|
||||
|
||||
while (cacheEntryHeaderListIter.hasNext()) {
|
||||
|
@ -128,7 +128,7 @@ class CacheEntryUpdater {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean entryDateHeaderNewerThenResponse(CacheEntry entry, HttpResponse response) {
|
||||
private boolean entryDateHeaderNewerThenResponse(HttpCacheEntry entry, HttpResponse response) {
|
||||
try {
|
||||
Date entryDate = DateUtils.parseDate(entry.getFirstHeader(HTTP.DATE_HEADER)
|
||||
.getValue());
|
||||
|
@ -145,7 +145,7 @@ class CacheEntryUpdater {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean entryAndResponseHaveDateHeader(CacheEntry entry, HttpResponse response) {
|
||||
private boolean entryAndResponseHaveDateHeader(HttpCacheEntry entry, HttpResponse response) {
|
||||
if (entry.getFirstHeader(HTTP.DATE_HEADER) != null
|
||||
&& response.getFirstHeader(HTTP.DATE_HEADER) != null) {
|
||||
return true;
|
||||
|
|
|
@ -36,7 +36,9 @@ import org.apache.http.HeaderElement;
|
|||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.ThreadSafe;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.client.cache.HttpCache;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.client.cache.HttpCacheOperationException;
|
||||
|
||||
/**
|
||||
|
@ -48,7 +50,7 @@ import org.apache.http.client.cache.HttpCacheOperationException;
|
|||
@ThreadSafe // so long as the cache implementation is thread-safe
|
||||
class CacheInvalidator {
|
||||
|
||||
private final HttpCache<String, CacheEntry> cache;
|
||||
private final HttpCache cache;
|
||||
private final URIExtractor uriExtractor;
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
@ -60,7 +62,9 @@ class CacheInvalidator {
|
|||
* @param uriExtractor Provides identifiers for the keys to store cache entries
|
||||
* @param cache the cache to store items away in
|
||||
*/
|
||||
public CacheInvalidator(URIExtractor uriExtractor, HttpCache<String, CacheEntry> cache) {
|
||||
public CacheInvalidator(
|
||||
final URIExtractor uriExtractor,
|
||||
final HttpCache cache) {
|
||||
this.uriExtractor = uriExtractor;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
@ -79,7 +83,7 @@ class CacheInvalidator {
|
|||
try {
|
||||
String theUri = uriExtractor.getURI(host, req);
|
||||
|
||||
CacheEntry parent = cache.getEntry(theUri);
|
||||
HttpCacheEntry parent = cache.getEntry(theUri);
|
||||
|
||||
log.debug("parent entry: " + parent);
|
||||
|
||||
|
|
241
httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java
vendored
Normal file
241
httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java
vendored
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.impl.cookie.DateParseException;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
class CacheValidityPolicy {
|
||||
|
||||
public static final long MAX_AGE = 2147483648L;
|
||||
|
||||
CacheValidityPolicy() {
|
||||
super();
|
||||
}
|
||||
|
||||
public long getCurrentAgeSecs(final HttpCacheEntry entry) {
|
||||
return getCorrectedInitialAgeSecs(entry) + getResidentTimeSecs(entry);
|
||||
}
|
||||
|
||||
public long getFreshnessLifetimeSecs(final HttpCacheEntry entry) {
|
||||
long maxage = getMaxAge(entry);
|
||||
if (maxage > -1)
|
||||
return maxage;
|
||||
|
||||
Date dateValue = getDateValue(entry);
|
||||
if (dateValue == null)
|
||||
return 0L;
|
||||
|
||||
Date expiry = getExpirationDate(entry);
|
||||
if (expiry == null)
|
||||
return 0;
|
||||
long diff = expiry.getTime() - dateValue.getTime();
|
||||
return (diff / 1000);
|
||||
}
|
||||
|
||||
public boolean isResponseFresh(final HttpCacheEntry entry) {
|
||||
return (getCurrentAgeSecs(entry) < getFreshnessLifetimeSecs(entry));
|
||||
}
|
||||
|
||||
public boolean isRevalidatable(final HttpCacheEntry entry) {
|
||||
return entry.getFirstHeader(HeaderConstants.ETAG) != null
|
||||
|| entry.getFirstHeader(HeaderConstants.LAST_MODIFIED) != null;
|
||||
}
|
||||
|
||||
public boolean modifiedSince(final HttpCacheEntry entry, final HttpRequest request) {
|
||||
Header unmodHeader = request.getFirstHeader(HeaderConstants.IF_UNMODIFIED_SINCE);
|
||||
|
||||
if (unmodHeader == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Date unmodifiedSinceDate = DateUtils.parseDate(unmodHeader.getValue());
|
||||
Date lastModifiedDate = DateUtils.parseDate(entry.getFirstHeader(
|
||||
HeaderConstants.LAST_MODIFIED).getValue());
|
||||
|
||||
if (unmodifiedSinceDate.before(lastModifiedDate)) {
|
||||
return true;
|
||||
}
|
||||
} catch (DateParseException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean mustRevalidate(final HttpCacheEntry entry) {
|
||||
return hasCacheControlDirective(entry, "must-revalidate");
|
||||
}
|
||||
|
||||
public boolean proxyRevalidate(final HttpCacheEntry entry) {
|
||||
return hasCacheControlDirective(entry, "proxy-revalidate");
|
||||
}
|
||||
|
||||
protected Date getDateValue(final HttpCacheEntry entry) {
|
||||
Header dateHdr = entry.getFirstHeader(HTTP.DATE_HEADER);
|
||||
if (dateHdr == null)
|
||||
return null;
|
||||
try {
|
||||
return DateUtils.parseDate(dateHdr.getValue());
|
||||
} catch (DateParseException dpe) {
|
||||
// ignore malformed date
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected long getContentLengthValue(final HttpCacheEntry entry) {
|
||||
Header cl = entry.getFirstHeader(HTTP.CONTENT_LEN);
|
||||
if (cl == null)
|
||||
return -1;
|
||||
|
||||
try {
|
||||
return Long.parseLong(cl.getValue());
|
||||
} catch (NumberFormatException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return boolean indicating whether actual length matches Content-Length
|
||||
*/
|
||||
protected boolean contentLengthHeaderMatchesActualLength(final HttpCacheEntry entry) {
|
||||
return getContentLengthValue(entry) == entry.getBody().getContentLength();
|
||||
}
|
||||
|
||||
protected long getApparentAgeSecs(final HttpCacheEntry entry) {
|
||||
Date dateValue = getDateValue(entry);
|
||||
if (dateValue == null)
|
||||
return MAX_AGE;
|
||||
long diff = entry.getResponseDate().getTime() - dateValue.getTime();
|
||||
if (diff < 0L)
|
||||
return 0;
|
||||
return (diff / 1000);
|
||||
}
|
||||
|
||||
protected long getAgeValue(final HttpCacheEntry entry) {
|
||||
long ageValue = 0;
|
||||
for (Header hdr : entry.getHeaders(HeaderConstants.AGE)) {
|
||||
long hdrAge;
|
||||
try {
|
||||
hdrAge = Long.parseLong(hdr.getValue());
|
||||
if (hdrAge < 0) {
|
||||
hdrAge = MAX_AGE;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
hdrAge = MAX_AGE;
|
||||
}
|
||||
ageValue = (hdrAge > ageValue) ? hdrAge : ageValue;
|
||||
}
|
||||
return ageValue;
|
||||
}
|
||||
|
||||
protected long getCorrectedReceivedAgeSecs(final HttpCacheEntry entry) {
|
||||
long apparentAge = getApparentAgeSecs(entry);
|
||||
long ageValue = getAgeValue(entry);
|
||||
return (apparentAge > ageValue) ? apparentAge : ageValue;
|
||||
}
|
||||
|
||||
protected long getResponseDelaySecs(final HttpCacheEntry entry) {
|
||||
long diff = entry.getResponseDate().getTime() - entry.getRequestDate().getTime();
|
||||
return (diff / 1000L);
|
||||
}
|
||||
|
||||
protected long getCorrectedInitialAgeSecs(final HttpCacheEntry entry) {
|
||||
return getCorrectedReceivedAgeSecs(entry) + getResponseDelaySecs(entry);
|
||||
}
|
||||
|
||||
protected Date getCurrentDate() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
protected long getResidentTimeSecs(final HttpCacheEntry entry) {
|
||||
long diff = getCurrentDate().getTime() - entry.getResponseDate().getTime();
|
||||
return (diff / 1000L);
|
||||
}
|
||||
|
||||
protected long getMaxAge(final HttpCacheEntry entry) {
|
||||
long maxage = -1;
|
||||
for (Header hdr : entry.getHeaders(HeaderConstants.CACHE_CONTROL)) {
|
||||
for (HeaderElement elt : hdr.getElements()) {
|
||||
if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())
|
||||
|| "s-maxage".equals(elt.getName())) {
|
||||
try {
|
||||
long currMaxAge = Long.parseLong(elt.getValue());
|
||||
if (maxage == -1 || currMaxAge < maxage) {
|
||||
maxage = currMaxAge;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
// be conservative if can't parse
|
||||
maxage = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxage;
|
||||
}
|
||||
|
||||
protected Date getExpirationDate(final HttpCacheEntry entry) {
|
||||
Header expiresHeader = entry.getFirstHeader(HeaderConstants.EXPIRES);
|
||||
if (expiresHeader == null)
|
||||
return null;
|
||||
try {
|
||||
return DateUtils.parseDate(expiresHeader.getValue());
|
||||
} catch (DateParseException dpe) {
|
||||
// malformed expires header
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean hasCacheControlDirective(final HttpCacheEntry entry, final String directive) {
|
||||
for (Header h : entry.getHeaders("Cache-Control")) {
|
||||
for(HeaderElement elt : h.getElements()) {
|
||||
if (directive.equalsIgnoreCase(elt.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -34,6 +34,7 @@ import org.apache.http.HttpRequest;
|
|||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
|
||||
/**
|
||||
* Determines if an HttpRequest is allowed to be served from the cache.
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.apache.http.HttpResponse;
|
|||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
@ -44,6 +46,17 @@ import org.apache.http.protocol.HTTP;
|
|||
@Immutable
|
||||
class CachedHttpResponseGenerator {
|
||||
|
||||
private final CacheValidityPolicy validityStrategy;
|
||||
|
||||
CachedHttpResponseGenerator(final CacheValidityPolicy validityStrategy) {
|
||||
super();
|
||||
this.validityStrategy = validityStrategy;
|
||||
}
|
||||
|
||||
CachedHttpResponseGenerator() {
|
||||
this(new CacheValidityPolicy());
|
||||
}
|
||||
|
||||
/**
|
||||
* If I was able to use a {@link CacheEntry} to response to the {@link org.apache.http.HttpRequest} then
|
||||
* generate an {@link HttpResponse} based on the cache entry.
|
||||
|
@ -51,7 +64,7 @@ class CachedHttpResponseGenerator {
|
|||
* {@link CacheEntry} to transform into an {@link HttpResponse}
|
||||
* @return {@link HttpResponse} that was constructed
|
||||
*/
|
||||
HttpResponse generateResponse(CacheEntry entry) {
|
||||
HttpResponse generateResponse(HttpCacheEntry entry) {
|
||||
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, entry
|
||||
.getStatusCode(), entry.getReasonPhrase());
|
||||
|
@ -63,7 +76,7 @@ class CachedHttpResponseGenerator {
|
|||
addMissingContentLengthHeader(response, entity);
|
||||
}
|
||||
|
||||
long age = entry.getCurrentAgeSecs();
|
||||
long age = this.validityStrategy.getCurrentAgeSecs(entry);
|
||||
if (age > 0) {
|
||||
if (age >= Integer.MAX_VALUE) {
|
||||
response.setHeader(HeaderConstants.AGE, "2147483648");
|
||||
|
|
|
@ -33,9 +33,11 @@ import org.apache.http.HeaderElement;
|
|||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
|
||||
/**
|
||||
* Determines whether a given {@link CacheEntry} is suitable to be
|
||||
* Determines whether a given {@link HttpCacheEntry} is suitable to be
|
||||
* used as a response for a given {@link HttpRequest}.
|
||||
*
|
||||
* @since 4.1
|
||||
|
@ -45,8 +47,19 @@ class CachedResponseSuitabilityChecker {
|
|||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private final CacheValidityPolicy validityStrategy;
|
||||
|
||||
CachedResponseSuitabilityChecker(final CacheValidityPolicy validityStrategy) {
|
||||
super();
|
||||
this.validityStrategy = validityStrategy;
|
||||
}
|
||||
|
||||
CachedResponseSuitabilityChecker() {
|
||||
this(new CacheValidityPolicy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if I can utilize a {@link CacheEntry} to respond to the given
|
||||
* Determine if I can utilize a {@link HttpCacheEntry} to respond to the given
|
||||
* {@link HttpRequest}
|
||||
*
|
||||
* @param host
|
||||
|
@ -54,21 +67,21 @@ class CachedResponseSuitabilityChecker {
|
|||
* @param request
|
||||
* {@link HttpRequest}
|
||||
* @param entry
|
||||
* {@link CacheEntry}
|
||||
* {@link HttpCacheEntry}
|
||||
* @return boolean yes/no answer
|
||||
*/
|
||||
public boolean canCachedResponseBeUsed(HttpHost host, HttpRequest request, CacheEntry entry) {
|
||||
if (!entry.isResponseFresh()) {
|
||||
public boolean canCachedResponseBeUsed(HttpHost host, HttpRequest request, HttpCacheEntry entry) {
|
||||
if (!validityStrategy.isResponseFresh(entry)) {
|
||||
log.debug("Cache entry was not fresh enough");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entry.contentLengthHeaderMatchesActualLength()) {
|
||||
if (!validityStrategy.contentLengthHeaderMatchesActualLength(entry)) {
|
||||
log.debug("Cache entry Content-Length and header information do not match");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry.modifiedSince(request)) {
|
||||
if (validityStrategy.modifiedSince(entry, request)) {
|
||||
log.debug("Cache entry modified times didn't line up. Cache Entry should not be used");
|
||||
return false;
|
||||
}
|
||||
|
@ -88,7 +101,7 @@ class CachedResponseSuitabilityChecker {
|
|||
if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())) {
|
||||
try {
|
||||
int maxage = Integer.parseInt(elt.getValue());
|
||||
if (entry.getCurrentAgeSecs() > maxage) {
|
||||
if (validityStrategy.getCurrentAgeSecs(entry) > maxage) {
|
||||
log.debug("Response from cache was NOT suitable due to max age");
|
||||
return false;
|
||||
}
|
||||
|
@ -102,7 +115,7 @@ class CachedResponseSuitabilityChecker {
|
|||
if (HeaderConstants.CACHE_CONTROL_MAX_STALE.equals(elt.getName())) {
|
||||
try {
|
||||
int maxstale = Integer.parseInt(elt.getValue());
|
||||
if (entry.getFreshnessLifetimeSecs() > maxstale) {
|
||||
if (validityStrategy.getFreshnessLifetimeSecs(entry) > maxstale) {
|
||||
log.debug("Response from cache was not suitable due to Max stale freshness");
|
||||
return false;
|
||||
}
|
||||
|
@ -116,7 +129,7 @@ class CachedResponseSuitabilityChecker {
|
|||
if (HeaderConstants.CACHE_CONTROL_MIN_FRESH.equals(elt.getName())) {
|
||||
try {
|
||||
int minfresh = Integer.parseInt(elt.getValue());
|
||||
if (entry.getFreshnessLifetimeSecs() < minfresh) {
|
||||
if (validityStrategy.getFreshnessLifetimeSecs(entry) < minfresh) {
|
||||
log.debug("Response from cache was not suitable due to min fresh " +
|
||||
"freshness requirement");
|
||||
return false;
|
||||
|
|
|
@ -47,7 +47,9 @@ import org.apache.http.annotation.ThreadSafe;
|
|||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.client.cache.HttpCache;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.client.cache.HttpCacheOperationException;
|
||||
import org.apache.http.client.cache.HttpCacheUpdateCallback;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
|
@ -75,10 +77,11 @@ public class CachingHttpClient implements HttpClient {
|
|||
private final AtomicLong cacheUpdates = new AtomicLong();
|
||||
|
||||
private final HttpClient backend;
|
||||
private final HttpCache responseCache;
|
||||
private final CacheValidityPolicy validityPolicy;
|
||||
private final ResponseCachingPolicy responseCachingPolicy;
|
||||
private final CacheEntryGenerator cacheEntryGenerator;
|
||||
private final URIExtractor uriExtractor;
|
||||
private final HttpCache<String, CacheEntry> responseCache;
|
||||
private final CachedHttpResponseGenerator responseGenerator;
|
||||
private final CacheInvalidator cacheInvalidator;
|
||||
private final CacheableRequestPolicy cacheableRequestPolicy;
|
||||
|
@ -93,17 +96,18 @@ public class CachingHttpClient implements HttpClient {
|
|||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
public CachingHttpClient(HttpClient client, HttpCache<String, CacheEntry> cache, int maxObjectSizeBytes) {
|
||||
public CachingHttpClient(HttpClient client, HttpCache cache, int maxObjectSizeBytes) {
|
||||
super();
|
||||
this.responseCache = cache;
|
||||
this.backend = client;
|
||||
this.responseCache = cache;
|
||||
this.validityPolicy = new CacheValidityPolicy();
|
||||
this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes);
|
||||
this.responseGenerator = new CachedHttpResponseGenerator(this.validityPolicy);
|
||||
this.cacheEntryGenerator = new CacheEntryGenerator();
|
||||
this.uriExtractor = new URIExtractor();
|
||||
this.responseGenerator = new CachedHttpResponseGenerator();
|
||||
this.cacheInvalidator = new CacheInvalidator(this.uriExtractor, this.responseCache);
|
||||
this.cacheableRequestPolicy = new CacheableRequestPolicy();
|
||||
this.suitabilityChecker = new CachedResponseSuitabilityChecker();
|
||||
this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy);
|
||||
this.conditionalRequestBuilder = new ConditionalRequestBuilder();
|
||||
this.cacheEntryUpdater = new CacheEntryUpdater();
|
||||
this.maxObjectSizeBytes = maxObjectSizeBytes;
|
||||
|
@ -115,13 +119,13 @@ public class CachingHttpClient implements HttpClient {
|
|||
this(new DefaultHttpClient(), new BasicHttpCache(MAX_CACHE_ENTRIES), DEFAULT_MAX_OBJECT_SIZE_BYTES);
|
||||
}
|
||||
|
||||
public CachingHttpClient(HttpCache<String, CacheEntry> cache, int maxObjectSizeBytes) {
|
||||
public CachingHttpClient(HttpCache cache, int maxObjectSizeBytes) {
|
||||
this(new DefaultHttpClient(), cache, maxObjectSizeBytes);
|
||||
}
|
||||
|
||||
CachingHttpClient(HttpClient backend, ResponseCachingPolicy responseCachingPolicy,
|
||||
CachingHttpClient(HttpClient backend, CacheValidityPolicy validityPolicy, ResponseCachingPolicy responseCachingPolicy,
|
||||
CacheEntryGenerator cacheEntryGenerator, URIExtractor uriExtractor,
|
||||
HttpCache<String, CacheEntry> responseCache, CachedHttpResponseGenerator responseGenerator,
|
||||
HttpCache responseCache, CachedHttpResponseGenerator responseGenerator,
|
||||
CacheInvalidator cacheInvalidator, CacheableRequestPolicy cacheableRequestPolicy,
|
||||
CachedResponseSuitabilityChecker suitabilityChecker,
|
||||
ConditionalRequestBuilder conditionalRequestBuilder, CacheEntryUpdater entryUpdater,
|
||||
|
@ -129,6 +133,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
RequestProtocolCompliance requestCompliance) {
|
||||
this.maxObjectSizeBytes = DEFAULT_MAX_OBJECT_SIZE_BYTES;
|
||||
this.backend = backend;
|
||||
this.validityPolicy = validityPolicy;
|
||||
this.responseCachingPolicy = responseCachingPolicy;
|
||||
this.cacheEntryGenerator = cacheEntryGenerator;
|
||||
this.uriExtractor = uriExtractor;
|
||||
|
@ -330,7 +335,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
return callBackend(target, request, context);
|
||||
}
|
||||
|
||||
CacheEntry entry = getCacheEntry(target, request);
|
||||
HttpCacheEntry entry = getCacheEntry(target, request);
|
||||
if (entry == null) {
|
||||
cacheMisses.getAndIncrement();
|
||||
if (log.isDebugEnabled()) {
|
||||
|
@ -352,14 +357,14 @@ public class CachingHttpClient implements HttpClient {
|
|||
return responseGenerator.generateResponse(entry);
|
||||
}
|
||||
|
||||
if (entry.isRevalidatable()) {
|
||||
if (validityPolicy.isRevalidatable(entry)) {
|
||||
log.debug("Revalidating the cache entry");
|
||||
|
||||
try {
|
||||
return revalidateCacheEntry(target, request, context, entry);
|
||||
} catch (IOException ioex) {
|
||||
if (entry.mustRevalidate()
|
||||
|| (isSharedCache() && entry.proxyRevalidate())) {
|
||||
if (validityPolicy.mustRevalidate(entry)
|
||||
|| (isSharedCache() && validityPolicy.proxyRevalidate(entry))) {
|
||||
return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout");
|
||||
} else {
|
||||
HttpResponse response = responseGenerator.generateResponse(entry);
|
||||
|
@ -386,17 +391,18 @@ public class CachingHttpClient implements HttpClient {
|
|||
return new Date();
|
||||
}
|
||||
|
||||
CacheEntry getCacheEntry(HttpHost target, HttpRequest request) {
|
||||
HttpCacheEntry getCacheEntry(HttpHost target, HttpRequest request) {
|
||||
String uri = uriExtractor.getURI(target, request);
|
||||
CacheEntry entry = null;
|
||||
HttpCacheEntry entry = null;
|
||||
try {
|
||||
entry = responseCache.getEntry(uri);
|
||||
} catch (HttpCacheOperationException ex) {
|
||||
log.debug("Was unable to get an entry from the cache based on the uri provided", ex);
|
||||
}
|
||||
|
||||
if (entry == null || !entry.hasVariants())
|
||||
if (entry == null || !entry.hasVariants()) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
String variantUri = uriExtractor.getVariantURI(target, request, entry);
|
||||
try {
|
||||
|
@ -445,7 +451,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
HttpHost target,
|
||||
HttpRequest request,
|
||||
HttpContext context,
|
||||
CacheEntry cacheEntry) throws IOException, ProtocolException {
|
||||
HttpCacheEntry cacheEntry) throws IOException, ProtocolException {
|
||||
HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(request, cacheEntry);
|
||||
Date requestDate = getCurrentDate();
|
||||
|
||||
|
@ -456,7 +462,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
int statusCode = backendResponse.getStatusLine().getStatusCode();
|
||||
if (statusCode == HttpStatus.SC_NOT_MODIFIED || statusCode == HttpStatus.SC_OK) {
|
||||
cacheUpdates.getAndIncrement();
|
||||
CacheEntry updatedEntry = cacheEntryUpdater.updateCacheEntry(cacheEntry, requestDate, responseDate, backendResponse);
|
||||
HttpCacheEntry updatedEntry = cacheEntryUpdater.updateCacheEntry(cacheEntry, requestDate, responseDate, backendResponse);
|
||||
storeInCache(target, request, updatedEntry);
|
||||
return responseGenerator.generateResponse(updatedEntry);
|
||||
}
|
||||
|
@ -465,7 +471,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
backendResponse);
|
||||
}
|
||||
|
||||
void storeInCache(HttpHost target, HttpRequest request, CacheEntry entry) {
|
||||
void storeInCache(HttpHost target, HttpRequest request, HttpCacheEntry entry) {
|
||||
if (entry.hasVariants()) {
|
||||
storeVariantEntry(target, request, entry);
|
||||
} else {
|
||||
|
@ -473,7 +479,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
void storeNonVariantEntry(HttpHost target, HttpRequest req, CacheEntry entry) {
|
||||
void storeNonVariantEntry(HttpHost target, HttpRequest req, HttpCacheEntry entry) {
|
||||
String uri = uriExtractor.getURI(target, req);
|
||||
try {
|
||||
responseCache.putEntry(uri, entry);
|
||||
|
@ -485,7 +491,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
void storeVariantEntry(
|
||||
final HttpHost target,
|
||||
final HttpRequest req,
|
||||
final CacheEntry entry) {
|
||||
final HttpCacheEntry entry) {
|
||||
final String variantURI = uriExtractor.getVariantURI(target, req, entry);
|
||||
try {
|
||||
responseCache.putEntry(variantURI, entry);
|
||||
|
@ -493,9 +499,9 @@ public class CachingHttpClient implements HttpClient {
|
|||
log.debug("Was unable to PUT a variant entry into the cache based on the uri provided", e);
|
||||
}
|
||||
|
||||
HttpCacheUpdateCallback<CacheEntry> callback = new HttpCacheUpdateCallback<CacheEntry>() {
|
||||
HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() {
|
||||
|
||||
public CacheEntry update(CacheEntry existing) throws HttpCacheOperationException {
|
||||
public HttpCacheEntry update(HttpCacheEntry existing) throws HttpCacheOperationException {
|
||||
return doGetUpdatedParentEntry(existing, entry, variantURI);
|
||||
}
|
||||
|
||||
|
@ -508,13 +514,13 @@ public class CachingHttpClient implements HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
CacheEntry doGetUpdatedParentEntry(
|
||||
CacheEntry existing,
|
||||
CacheEntry entry, String variantURI) throws HttpCacheOperationException {
|
||||
HttpCacheEntry doGetUpdatedParentEntry(
|
||||
HttpCacheEntry existing,
|
||||
HttpCacheEntry entry, String variantURI) throws HttpCacheOperationException {
|
||||
if (existing != null) {
|
||||
return existing.copyWithVariant(variantURI);
|
||||
return HttpCacheEntry.copyWithVariant(existing, variantURI);
|
||||
} else {
|
||||
return entry.copyWithVariant(variantURI);
|
||||
return HttpCacheEntry.copyWithVariant(entry, variantURI);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -570,7 +576,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
responseBytes);
|
||||
int correctedStatus = corrected.getStatusLine().getStatusCode();
|
||||
if (HttpStatus.SC_BAD_GATEWAY != correctedStatus) {
|
||||
CacheEntry entry = cacheEntryGenerator
|
||||
HttpCacheEntry entry = cacheEntryGenerator
|
||||
.generateEntry(requestDate, responseDate, corrected,
|
||||
responseBytes);
|
||||
storeInCache(target, request, entry);
|
||||
|
|
|
@ -31,6 +31,8 @@ import org.apache.http.HeaderElement;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.ProtocolException;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.impl.client.RequestWrapper;
|
||||
|
||||
/**
|
||||
|
@ -40,7 +42,7 @@ import org.apache.http.impl.client.RequestWrapper;
|
|||
class ConditionalRequestBuilder {
|
||||
|
||||
/**
|
||||
* When a {@link CacheEntry} is stale but 'might' be used as a response
|
||||
* 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
|
||||
* the origin. Build the origin {@link HttpRequest} here and return it.
|
||||
*
|
||||
|
@ -49,7 +51,7 @@ class ConditionalRequestBuilder {
|
|||
* @return the wrapped request
|
||||
* @throws ProtocolException when I am unable to build a new origin request.
|
||||
*/
|
||||
public HttpRequest buildConditionalRequest(HttpRequest request, CacheEntry cacheEntry)
|
||||
public HttpRequest buildConditionalRequest(HttpRequest request, HttpCacheEntry cacheEntry)
|
||||
throws ProtocolException {
|
||||
RequestWrapper wrapperRequest = new RequestWrapper(request);
|
||||
wrapperRequest.resetHeaders();
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.apache.http.HttpVersion;
|
|||
import org.apache.http.ProtocolException;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.entity.AbstractHttpEntity;
|
||||
import org.apache.http.impl.client.RequestWrapper;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.apache.http.HttpResponse;
|
|||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.impl.cookie.DateParseException;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.apache.http.HttpVersion;
|
|||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.impl.client.RequestWrapper;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
|
|
@ -37,6 +37,8 @@ import org.apache.http.HeaderElement;
|
|||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.cache.HeaderConstants;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
|
@ -84,7 +86,7 @@ class URIExtractor {
|
|||
* @param entry the parent entry used to track the varients
|
||||
* @return String the extracted variant URI
|
||||
*/
|
||||
public String getVariantURI(HttpHost host, HttpRequest req, CacheEntry entry) {
|
||||
public String getVariantURI(HttpHost host, HttpRequest req, HttpCacheEntry entry) {
|
||||
Header[] varyHdrs = entry.getHeaders(HeaderConstants.VARY);
|
||||
if (varyHdrs == null || varyHdrs.length == 0) {
|
||||
return getURI(host, req);
|
||||
|
|
84
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/CacheEntry.java
vendored
Normal file
84
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/CacheEntry.java
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.entity.BasicHttpEntity;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
|
||||
public class CacheEntry extends HttpCacheEntry {
|
||||
|
||||
private static final long serialVersionUID = 7964121802841871079L;
|
||||
|
||||
public static final long MAX_AGE = CacheValidityPolicy.MAX_AGE;
|
||||
|
||||
public CacheEntry(
|
||||
Date requestDate,
|
||||
Date responseDate,
|
||||
StatusLine statusLine,
|
||||
Header[] responseHeaders,
|
||||
HttpEntity body) {
|
||||
super(requestDate, responseDate, statusLine, responseHeaders, body, null);
|
||||
}
|
||||
|
||||
public CacheEntry(
|
||||
Date requestDate,
|
||||
Date responseDate) {
|
||||
super(requestDate, responseDate, new OKStatus(), new Header[] {}, new BasicHttpEntity(), null);
|
||||
}
|
||||
|
||||
public CacheEntry(
|
||||
Date requestDate,
|
||||
Date responseDate,
|
||||
Header[] headers) {
|
||||
super(requestDate, responseDate, new OKStatus(), headers, new BasicHttpEntity(), null);
|
||||
}
|
||||
|
||||
public CacheEntry(Header[] headers) {
|
||||
super(new Date(), new Date(), new OKStatus(), headers, new BasicHttpEntity(), null);
|
||||
}
|
||||
|
||||
public CacheEntry(
|
||||
Header[] headers,
|
||||
byte[] content) {
|
||||
super(new Date(), new Date(), new OKStatus(), headers, new ByteArrayEntity(content), null);
|
||||
}
|
||||
|
||||
public CacheEntry() {
|
||||
this(new Date(), new Date());
|
||||
}
|
||||
|
||||
public CacheEntry(byte[] content) {
|
||||
super(new Date(), new Date(), new OKStatus(), new Header[] {}, new ByteArrayEntity(content), null);
|
||||
}
|
||||
|
||||
}
|
|
@ -62,13 +62,12 @@ public class DoNotTestProtocolRequirements {
|
|||
private HttpHost host;
|
||||
private HttpEntity mockEntity;
|
||||
private HttpClient mockBackend;
|
||||
private HttpCache<String, CacheEntry> mockCache;
|
||||
private HttpCache mockCache;
|
||||
private HttpRequest request;
|
||||
private HttpResponse originResponse;
|
||||
|
||||
private CachingHttpClient impl;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void setUp() {
|
||||
host = new HttpHost("foo.example.com");
|
||||
|
@ -77,7 +76,7 @@ public class DoNotTestProtocolRequirements {
|
|||
|
||||
originResponse = make200Response();
|
||||
|
||||
HttpCache<String, CacheEntry> cache = new BasicHttpCache(MAX_ENTRIES);
|
||||
HttpCache cache = new BasicHttpCache(MAX_ENTRIES);
|
||||
mockBackend = EasyMock.createMock(HttpClient.class);
|
||||
mockEntity = EasyMock.createMock(HttpEntity.class);
|
||||
mockCache = EasyMock.createMock(HttpCache.class);
|
||||
|
|
39
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/OKStatus.java
vendored
Normal file
39
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/OKStatus.java
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
|
||||
public class OKStatus extends BasicStatusLine {
|
||||
|
||||
public OKStatus() {
|
||||
super(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
|
||||
}
|
||||
|
||||
}
|
|
@ -26,38 +26,29 @@
|
|||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestCacheEntry {
|
||||
|
||||
private static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP",1,1);
|
||||
|
||||
@Test
|
||||
public void testGetHeadersReturnsCorrectHeaders() {
|
||||
Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"),
|
||||
new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
Assert.assertEquals(2, entry.getHeaders("bar").length);
|
||||
}
|
||||
|
||||
private CacheEntry getEntry(Header[] headers) {
|
||||
return getEntry(new Date(), new Date(), headers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFirstHeaderReturnsCorrectHeader() {
|
||||
Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"),
|
||||
new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
Assert.assertEquals("barValue1", entry.getFirstHeader("bar").getValue());
|
||||
}
|
||||
|
@ -67,8 +58,7 @@ public class TestCacheEntry {
|
|||
Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"),
|
||||
new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") };
|
||||
|
||||
|
||||
CacheEntry entry = getEntry(headers);
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
Assert.assertEquals(0, entry.getHeaders("baz").length);
|
||||
}
|
||||
|
@ -77,334 +67,23 @@ public class TestCacheEntry {
|
|||
public void testGetFirstHeaderReturnsNullIfNoneMatch() {
|
||||
Header[] headers = new Header[] { new BasicHeader("foo", "fooValue"),
|
||||
new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
Assert.assertEquals(null, entry.getFirstHeader("quux"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApparentAgeIsMaxIntIfDateHeaderNotPresent() {
|
||||
Header[] headers = new Header[0];
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertEquals(2147483648L, entry.getApparentAgeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApparentAgeIsResponseReceivedTimeLessDateHeader() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Date", DateUtils
|
||||
.formatDate(tenSecondsAgo)) };
|
||||
|
||||
|
||||
|
||||
CacheEntry entry = getEntry(now, sixSecondsAgo, headers);
|
||||
|
||||
Assert.assertEquals(4, entry.getApparentAgeSecs());
|
||||
}
|
||||
|
||||
private CacheEntry getEntry(Date requestDate, Date responseDate, Header[] headers) {
|
||||
return new CacheEntry(requestDate, responseDate, HTTP_1_1, headers,
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegativeApparentAgeIsBroughtUpToZero() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Date", DateUtils
|
||||
.formatDate(sixSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = getEntry(now,tenSecondsAgo,headers);
|
||||
Assert.assertEquals(0, entry.getApparentAgeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectedReceivedAgeIsAgeHeaderIfLarger() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Age", "10"), };
|
||||
CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1,
|
||||
headers, new ByteArrayEntity(new byte[] {}), 200, "OK") {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected long getApparentAgeSecs() {
|
||||
return 6;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Assert.assertEquals(10, entry.getCorrectedReceivedAgeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectedReceivedAgeIsApparentAgeIfLarger() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Age", "6"), };
|
||||
CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1,
|
||||
headers, new ByteArrayEntity(new byte[] {}), 200 ,"OK") {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected long getApparentAgeSecs() {
|
||||
return 10;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.assertEquals(10, entry.getCorrectedReceivedAgeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseDelayIsDifferenceBetweenResponseAndRequestTimes() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
|
||||
Header[] headers = new Header[]{};
|
||||
|
||||
CacheEntry entry = new CacheEntry(tenSecondsAgo, sixSecondsAgo,
|
||||
new ProtocolVersion("HTTP",1,1), headers, new ByteArrayEntity(new byte[] {}),
|
||||
200, "OK");
|
||||
|
||||
|
||||
Assert.assertEquals(4, entry.getResponseDelaySecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectedInitialAgeIsCorrectedReceivedAgePlusResponseDelay() {
|
||||
CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1, new Header[] {},
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK") {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected long getCorrectedReceivedAgeSecs() {
|
||||
return 7;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getResponseDelaySecs() {
|
||||
return 13;
|
||||
}
|
||||
};
|
||||
Assert.assertEquals(20, entry.getCorrectedInitialAgeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResidentTimeSecondsIsTimeSinceResponseTime() {
|
||||
final Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
|
||||
CacheEntry entry = new CacheEntry(new Date(), sixSecondsAgo, HTTP_1_1, new Header[]{},
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK") {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected Date getCurrentDate() {
|
||||
return now;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.assertEquals(6, entry.getResidentTimeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCurrentAgeIsCorrectedInitialAgePlusResidentTime() {
|
||||
CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1, new Header[]{},
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK") {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected long getCorrectedInitialAgeSecs() {
|
||||
return 11;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getResidentTimeSecs() {
|
||||
return 17;
|
||||
}
|
||||
};
|
||||
Assert.assertEquals(28, entry.getCurrentAgeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsSMaxAgeIfPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertEquals(10, entry.getFreshnessLifetimeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsMaxAgeIfPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertEquals(10, entry.getFreshnessLifetimeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsMostRestrictiveOfMaxAgeAndSMaxAge() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"),
|
||||
new BasicHeader("Cache-Control", "s-maxage=20") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertEquals(10, entry.getFreshnessLifetimeSecs());
|
||||
|
||||
headers = new Header[] { new BasicHeader("Cache-Control", "max-age=20"),
|
||||
new BasicHeader("Cache-Control", "s-maxage=10") };
|
||||
entry = getEntry(headers);
|
||||
Assert.assertEquals(10, entry.getFreshnessLifetimeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsMaxAgeEvenIfExpiresIsPresent() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"),
|
||||
new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertEquals(10, entry.getFreshnessLifetimeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsSMaxAgeEvenIfExpiresIsPresent() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10"),
|
||||
new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertEquals(10, entry.getFreshnessLifetimeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsFromExpiresHeaderIfNoMaxAge() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Header[] headers = new Header[] {
|
||||
new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertEquals(4, entry.getFreshnessLifetimeSecs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() {
|
||||
CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1, new Header[]{},
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK") {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public long getCurrentAgeSecs() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreshnessLifetimeSecs() {
|
||||
return 10;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.assertTrue(entry.isResponseFresh());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() {
|
||||
CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1, new Header[]{},
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK") {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public long getCurrentAgeSecs() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreshnessLifetimeSecs() {
|
||||
return 6;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.assertFalse(entry.isResponseFresh());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() {
|
||||
CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1, new Header[] {},
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK") {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public long getCurrentAgeSecs() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreshnessLifetimeSecs() {
|
||||
return 6;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.assertFalse(entry.isResponseFresh());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEntryIsRevalidatableIfHeadersIncludeETag() {
|
||||
|
||||
Header[] headers = {
|
||||
new BasicHeader("Expires", DateUtils.formatDate(new Date())),
|
||||
new BasicHeader("ETag", "somevalue")};
|
||||
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
Assert.assertTrue(entry.isRevalidatable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEntryIsRevalidatableIfHeadersIncludeLastModifiedDate() {
|
||||
|
||||
Header[] headers = {
|
||||
new BasicHeader("Expires", DateUtils.formatDate(new Date())),
|
||||
new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())) };
|
||||
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertTrue(entry.isRevalidatable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEntryIsNotRevalidatableIfNoAppropriateHeaders() {
|
||||
|
||||
Header[] headers = {
|
||||
new BasicHeader("Expires", DateUtils.formatDate(new Date())),
|
||||
new BasicHeader("Cache-Control", "public") };
|
||||
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertFalse(entry.isRevalidatable());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() {
|
||||
Header[] headers = new Header[0];
|
||||
|
||||
CacheEntry entry = getEntry(headers);
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
Assert.assertFalse(entry.hasVariants());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEntryWithOneVaryHeaderHasVariants() {
|
||||
Header[] headers = { new BasicHeader("Vary", "User-Agent") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
Assert.assertTrue(entry.hasVariants());
|
||||
}
|
||||
|
||||
|
@ -412,14 +91,14 @@ public class TestCacheEntry {
|
|||
public void testCacheEntryWithMultipleVaryHeadersHasVariants() {
|
||||
Header[] headers = { new BasicHeader("Vary", "User-Agent"),
|
||||
new BasicHeader("Vary", "Accept-Encoding") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
Assert.assertTrue(entry.hasVariants());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEntryWithVaryStarHasVariants(){
|
||||
Header[] headers = { new BasicHeader("Vary", "*") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
Assert.assertTrue(entry.hasVariants());
|
||||
}
|
||||
|
||||
|
@ -427,10 +106,10 @@ public class TestCacheEntry {
|
|||
public void testCacheEntryCanStoreMultipleVariantUris() {
|
||||
|
||||
Header[] headers = new Header[]{};
|
||||
CacheEntry entry = getEntry(headers);
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheEntry addedOne = entry.copyWithVariant("foo");
|
||||
CacheEntry addedTwo = addedOne.copyWithVariant("bar");
|
||||
HttpCacheEntry addedOne = HttpCacheEntry.copyWithVariant(entry, "foo");
|
||||
HttpCacheEntry addedTwo = HttpCacheEntry.copyWithVariant(addedOne, "bar");
|
||||
|
||||
Set<String> variants = addedTwo.getVariantURIs();
|
||||
|
||||
|
@ -438,99 +117,4 @@ public class TestCacheEntry {
|
|||
Assert.assertTrue(variants.contains("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedDateHeaderIsIgnored() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Date", "asdf") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
Date d = entry.getDateValue();
|
||||
|
||||
Assert.assertNull(d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedContentLengthReturnsNegativeOne() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Content-Length", "asdf") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
long length = entry.getContentLengthValue();
|
||||
|
||||
Assert.assertEquals(-1, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegativeAgeHeaderValueReturnsMaxAge() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Age", "-100") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
long length = entry.getAgeValue();
|
||||
|
||||
Assert.assertEquals(CacheEntry.MAX_AGE, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedAgeHeaderValueReturnsMaxAge() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Age", "asdf") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
long length = entry.getAgeValue();
|
||||
|
||||
Assert.assertEquals(CacheEntry.MAX_AGE, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedCacheControlMaxAgeHeaderReturnsZero() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=asdf") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
long maxage = entry.getMaxAge();
|
||||
|
||||
Assert.assertEquals(0, maxage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedExpirationDateReturnsNull() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Expires", "asdf") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
|
||||
Date expirationDate = entry.getExpirationDate();
|
||||
|
||||
Assert.assertNull(expirationDate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMustRevalidateIsFalseIfDirectiveNotPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertFalse(entry.mustRevalidate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMustRevalidateIsTrueWhenDirectiveIsPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, must-revalidate") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertTrue(entry.mustRevalidate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyRevalidateIsFalseIfDirectiveNotPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertFalse(entry.proxyRevalidate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyRevalidateIsTrueWhenDirectiveIsPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, proxy-revalidate") };
|
||||
CacheEntry entry = getEntry(headers);
|
||||
Assert.assertTrue(entry.proxyRevalidate());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.http.HttpEntity;
|
|||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.junit.Assert;
|
||||
|
@ -51,7 +52,7 @@ public class TestCacheEntryGenerator {
|
|||
|
||||
response.setHeader("fooHeader", "fooHeaderValue");
|
||||
|
||||
CacheEntry entry = gen.generateEntry(new Date(), new Date(), response, new byte[] {});
|
||||
HttpCacheEntry entry = gen.generateEntry(new Date(), new Date(), response, new byte[] {});
|
||||
|
||||
Assert.assertEquals("HTTP", entry.getProtocolVersion().getProtocol());
|
||||
Assert.assertEquals(1, entry.getProtocolVersion().getMajor());
|
||||
|
|
|
@ -29,13 +29,13 @@ package org.apache.http.impl.client.cache;
|
|||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.easymock.classextension.EasyMock;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -48,59 +48,28 @@ import static junit.framework.Assert.assertNotSame;
|
|||
|
||||
public class TestCacheEntryUpdater {
|
||||
|
||||
|
||||
private static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1);
|
||||
|
||||
|
||||
private HttpResponse mockResponse;
|
||||
private CacheEntry mockCacheEntry;
|
||||
private Date requestDate;
|
||||
private Date responseDate;
|
||||
|
||||
private boolean implMocked = false;
|
||||
private CacheEntryUpdater impl;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mockResponse = EasyMock.createMock(HttpResponse.class);
|
||||
mockCacheEntry = EasyMock.createMock(CacheEntry.class);
|
||||
|
||||
requestDate = new Date(System.currentTimeMillis() - 1000);
|
||||
responseDate = new Date();
|
||||
|
||||
impl = new CacheEntryUpdater();
|
||||
}
|
||||
|
||||
private void replayMocks() {
|
||||
EasyMock.replay(mockResponse);
|
||||
EasyMock.replay(mockCacheEntry);
|
||||
if (implMocked) {
|
||||
EasyMock.replay(impl);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyMocks() {
|
||||
EasyMock.verify(mockResponse);
|
||||
EasyMock.verify(mockCacheEntry);
|
||||
if (implMocked) {
|
||||
EasyMock.verify(impl);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCacheEntryReturnsDifferentEntryInstance() throws IOException {
|
||||
|
||||
CacheEntry entry = getEntry(new Header[]{});
|
||||
BasicHttpResponse response = new BasicHttpResponse(HTTP_1_1, 200, "OK");
|
||||
CacheEntry entry = new CacheEntry();
|
||||
BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
|
||||
|
||||
replayMocks();
|
||||
|
||||
CacheEntry newEntry = impl.updateCacheEntry(entry, requestDate, responseDate, response);
|
||||
|
||||
verifyMocks();
|
||||
HttpCacheEntry newEntry = impl.updateCacheEntry(entry, requestDate, responseDate, response);
|
||||
|
||||
assertNotSame(newEntry, entry);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -110,13 +79,13 @@ public class TestCacheEntryUpdater {
|
|||
new BasicHeader("Date", DateUtils.formatDate(responseDate)),
|
||||
new BasicHeader("ETag", "\"etag\"")};
|
||||
|
||||
CacheEntry cacheEntry = getEntry(headers);
|
||||
CacheEntry cacheEntry = new CacheEntry(headers);
|
||||
|
||||
HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion(
|
||||
"http", 1, 1), HttpStatus.SC_NOT_MODIFIED, ""));
|
||||
response.setHeaders(new Header[]{});
|
||||
|
||||
CacheEntry updatedEntry = impl.updateCacheEntry(cacheEntry, new Date(), new Date(), response);
|
||||
HttpCacheEntry updatedEntry = impl.updateCacheEntry(cacheEntry, new Date(), new Date(), response);
|
||||
|
||||
Assert.assertEquals(2, updatedEntry.getAllHeaders().length);
|
||||
|
||||
|
@ -133,7 +102,7 @@ public class TestCacheEntryUpdater {
|
|||
new BasicHeader("Cache-Control", "private"), new BasicHeader("ETag", "\"etag\""),
|
||||
new BasicHeader("Last-Modified", DateUtils.formatDate(requestDate)),
|
||||
new BasicHeader("Cache-Control", "max-age=0"),};
|
||||
CacheEntry cacheEntry = getEntry(headers);
|
||||
CacheEntry cacheEntry = new CacheEntry(headers);
|
||||
|
||||
HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion(
|
||||
"http", 1, 1), HttpStatus.SC_NOT_MODIFIED, ""));
|
||||
|
@ -141,7 +110,7 @@ public class TestCacheEntryUpdater {
|
|||
new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)),
|
||||
new BasicHeader("Cache-Control", "public"),});
|
||||
|
||||
CacheEntry updatedEntry = impl.updateCacheEntry(cacheEntry, new Date(), new Date(), response);
|
||||
HttpCacheEntry updatedEntry = impl.updateCacheEntry(cacheEntry, new Date(), new Date(), response);
|
||||
|
||||
|
||||
Assert.assertEquals(4, updatedEntry.getAllHeaders().length);
|
||||
|
@ -160,14 +129,14 @@ public class TestCacheEntryUpdater {
|
|||
new BasicHeader("Date", DateUtils.formatDate(requestDate)),
|
||||
new BasicHeader("ETag", "\"etag\"")};
|
||||
|
||||
CacheEntry cacheEntry = getEntry(headers);
|
||||
CacheEntry cacheEntry = new CacheEntry(headers);
|
||||
HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion(
|
||||
"http", 1, 1), HttpStatus.SC_NOT_MODIFIED, ""));
|
||||
response.setHeaders(new Header[]{
|
||||
new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)),
|
||||
new BasicHeader("Cache-Control", "public"),});
|
||||
|
||||
CacheEntry updatedEntry = impl.updateCacheEntry(cacheEntry, new Date(), new Date(), response);
|
||||
HttpCacheEntry updatedEntry = impl.updateCacheEntry(cacheEntry, new Date(), new Date(), response);
|
||||
|
||||
|
||||
Assert.assertEquals(4, updatedEntry.getAllHeaders().length);
|
||||
|
@ -191,23 +160,17 @@ public class TestCacheEntryUpdater {
|
|||
Date twoSecondsAgo = new Date(now.getTime() - 2000L);
|
||||
Date oneSecondAgo = new Date(now.getTime() - 1000L);
|
||||
|
||||
Header[] headers = new Header[]{};
|
||||
CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo);
|
||||
|
||||
CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, HTTP_1_1, headers,
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK");
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
|
||||
|
||||
HttpResponse response = new BasicHttpResponse(HTTP_1_1, 200, "OK");
|
||||
|
||||
CacheEntry updated = impl.updateCacheEntry(entry, twoSecondsAgo, oneSecondAgo, response);
|
||||
HttpCacheEntry updated = impl.updateCacheEntry(entry, twoSecondsAgo, oneSecondAgo, response);
|
||||
|
||||
assertEquals(twoSecondsAgo, updated.getRequestDate());
|
||||
assertEquals(oneSecondAgo, updated.getResponseDate());
|
||||
|
||||
}
|
||||
|
||||
|
||||
// UTILITY
|
||||
|
||||
private void headersContain(Header[] headers, String name, String value) {
|
||||
for (Header header : headers) {
|
||||
if (header.getName().equals(name)) {
|
||||
|
@ -219,13 +182,4 @@ public class TestCacheEntryUpdater {
|
|||
Assert.fail("Header [" + name + ": " + value + "] not found in headers.");
|
||||
}
|
||||
|
||||
|
||||
private CacheEntry getEntry(Header[] headers) {
|
||||
return getEntry(new Date(), new Date(), headers);
|
||||
}
|
||||
|
||||
private CacheEntry getEntry(Date requestDate, Date responseDate, Header[] headers) {
|
||||
return new CacheEntry(requestDate, responseDate, HTTP_1_1, headers,
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,14 +46,11 @@ public class TestCacheInvalidator {
|
|||
private static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1);
|
||||
|
||||
private CacheInvalidator impl;
|
||||
private HttpCache<String, CacheEntry> mockCache;
|
||||
private HttpCache mockCache;
|
||||
private HttpHost host;
|
||||
private URIExtractor extractor;
|
||||
private CacheEntry mockEntry;
|
||||
|
||||
private boolean mockedImpl;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void setUp() {
|
||||
host = new HttpHost("foo.example.com");
|
||||
|
@ -67,17 +64,11 @@ public class TestCacheInvalidator {
|
|||
private void replayMocks() {
|
||||
EasyMock.replay(mockCache);
|
||||
EasyMock.replay(mockEntry);
|
||||
|
||||
if (mockedImpl)
|
||||
EasyMock.replay(impl);
|
||||
}
|
||||
|
||||
private void verifyMocks() {
|
||||
EasyMock.verify(mockCache);
|
||||
EasyMock.verify(mockEntry);
|
||||
|
||||
if (mockedImpl)
|
||||
EasyMock.verify(impl);
|
||||
}
|
||||
|
||||
// Tests
|
||||
|
|
453
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java
vendored
Normal file
453
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java
vendored
Normal file
|
@ -0,0 +1,453 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestCacheValidityPolicy {
|
||||
|
||||
@Test
|
||||
public void testApparentAgeIsMaxIntIfDateHeaderNotPresent() {
|
||||
CacheEntry entry = new CacheEntry();
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Assert.assertEquals(2147483648L, impl.getApparentAgeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApparentAgeIsResponseReceivedTimeLessDateHeader() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Date", DateUtils
|
||||
.formatDate(tenSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = new CacheEntry(now, sixSecondsAgo, headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertEquals(4, impl.getApparentAgeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegativeApparentAgeIsBroughtUpToZero() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Date", DateUtils
|
||||
.formatDate(sixSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = new CacheEntry(now,tenSecondsAgo,headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Assert.assertEquals(0, impl.getApparentAgeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectedReceivedAgeIsAgeHeaderIfLarger() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Age", "10"), };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy() {
|
||||
|
||||
@Override
|
||||
protected long getApparentAgeSecs(HttpCacheEntry entry) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Assert.assertEquals(10, impl.getCorrectedReceivedAgeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectedReceivedAgeIsApparentAgeIfLarger() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Age", "6"), };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy() {
|
||||
|
||||
@Override
|
||||
protected long getApparentAgeSecs(HttpCacheEntry entry) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Assert.assertEquals(10, impl.getCorrectedReceivedAgeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseDelayIsDifferenceBetweenResponseAndRequestTimes() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
|
||||
CacheEntry entry = new CacheEntry(tenSecondsAgo, sixSecondsAgo);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertEquals(4, impl.getResponseDelaySecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectedInitialAgeIsCorrectedReceivedAgePlusResponseDelay() {
|
||||
CacheEntry entry = new CacheEntry();
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy() {
|
||||
|
||||
@Override
|
||||
protected long getCorrectedReceivedAgeSecs(HttpCacheEntry entry) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getResponseDelaySecs(HttpCacheEntry entry) {
|
||||
return 13;
|
||||
}
|
||||
|
||||
};
|
||||
Assert.assertEquals(20, impl.getCorrectedInitialAgeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResidentTimeSecondsIsTimeSinceResponseTime() {
|
||||
final Date now = new Date();
|
||||
final Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
|
||||
CacheEntry entry = new CacheEntry(now, sixSecondsAgo);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy() {
|
||||
|
||||
@Override
|
||||
protected Date getCurrentDate() {
|
||||
return now;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Assert.assertEquals(6, impl.getResidentTimeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCurrentAgeIsCorrectedInitialAgePlusResidentTime() {
|
||||
CacheEntry entry = new CacheEntry();
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy() {
|
||||
|
||||
@Override
|
||||
protected long getCorrectedInitialAgeSecs(HttpCacheEntry entry) {
|
||||
return 11;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getResidentTimeSecs(HttpCacheEntry entry) {
|
||||
return 17;
|
||||
}
|
||||
};
|
||||
Assert.assertEquals(28, impl.getCurrentAgeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsSMaxAgeIfPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsMaxAgeIfPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsMostRestrictiveOfMaxAgeAndSMaxAge() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"),
|
||||
new BasicHeader("Cache-Control", "s-maxage=20") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
|
||||
|
||||
headers = new Header[] { new BasicHeader("Cache-Control", "max-age=20"),
|
||||
new BasicHeader("Cache-Control", "s-maxage=10") };
|
||||
entry = new CacheEntry(headers);
|
||||
Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsMaxAgeEvenIfExpiresIsPresent() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"),
|
||||
new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsSMaxAgeEvenIfExpiresIsPresent() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10"),
|
||||
new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreshnessLifetimeIsFromExpiresHeaderIfNoMaxAge() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Header[] headers = new Header[] {
|
||||
new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
|
||||
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Assert.assertEquals(4, impl.getFreshnessLifetimeSecs(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() {
|
||||
CacheEntry entry = new CacheEntry();
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy() {
|
||||
|
||||
@Override
|
||||
public long getCurrentAgeSecs(HttpCacheEntry entry) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreshnessLifetimeSecs(HttpCacheEntry entry) {
|
||||
return 10;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.assertTrue(impl.isResponseFresh(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() {
|
||||
CacheEntry entry = new CacheEntry();
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy() {
|
||||
|
||||
@Override
|
||||
public long getCurrentAgeSecs(HttpCacheEntry entry) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreshnessLifetimeSecs(HttpCacheEntry entry) {
|
||||
return 6;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.assertFalse(impl.isResponseFresh(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() {
|
||||
CacheEntry entry = new CacheEntry();
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy() {
|
||||
|
||||
@Override
|
||||
public long getCurrentAgeSecs(HttpCacheEntry entry) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreshnessLifetimeSecs(HttpCacheEntry entry) {
|
||||
return 6;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.assertFalse(impl.isResponseFresh(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEntryIsRevalidatableIfHeadersIncludeETag() {
|
||||
|
||||
Header[] headers = {
|
||||
new BasicHeader("Expires", DateUtils.formatDate(new Date())),
|
||||
new BasicHeader("ETag", "somevalue")};
|
||||
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertTrue(impl.isRevalidatable(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEntryIsRevalidatableIfHeadersIncludeLastModifiedDate() {
|
||||
|
||||
Header[] headers = {
|
||||
new BasicHeader("Expires", DateUtils.formatDate(new Date())),
|
||||
new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())) };
|
||||
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertTrue(impl.isRevalidatable(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEntryIsNotRevalidatableIfNoAppropriateHeaders() {
|
||||
|
||||
Header[] headers = {
|
||||
new BasicHeader("Expires", DateUtils.formatDate(new Date())),
|
||||
new BasicHeader("Cache-Control", "public") };
|
||||
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertFalse(impl.isRevalidatable(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedDateHeaderIsIgnored() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Date", "asdf") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Date d = impl.getDateValue(entry);
|
||||
|
||||
Assert.assertNull(d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedContentLengthReturnsNegativeOne() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Content-Length", "asdf") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
long length = impl.getContentLengthValue(entry);
|
||||
|
||||
Assert.assertEquals(-1, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegativeAgeHeaderValueReturnsMaxAge() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Age", "-100") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
long length = impl.getAgeValue(entry);
|
||||
|
||||
Assert.assertEquals(CacheEntry.MAX_AGE, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedAgeHeaderValueReturnsMaxAge() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Age", "asdf") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
long length = impl.getAgeValue(entry);
|
||||
|
||||
Assert.assertEquals(CacheEntry.MAX_AGE, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedCacheControlMaxAgeHeaderReturnsZero() {
|
||||
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=asdf") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
long maxage = impl.getMaxAge(entry);
|
||||
|
||||
Assert.assertEquals(0, maxage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedExpirationDateReturnsNull() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Expires", "asdf") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
Date expirationDate = impl.getExpirationDate(entry);
|
||||
|
||||
Assert.assertNull(expirationDate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMustRevalidateIsFalseIfDirectiveNotPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertFalse(impl.mustRevalidate(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMustRevalidateIsTrueWhenDirectiveIsPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, must-revalidate") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertTrue(impl.mustRevalidate(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyRevalidateIsFalseIfDirectiveNotPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertFalse(impl.proxyRevalidate(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyRevalidateIsTrueWhenDirectiveIsPresent() {
|
||||
Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, proxy-revalidate") };
|
||||
CacheEntry entry = new CacheEntry(headers);
|
||||
CacheValidityPolicy impl = new CacheValidityPolicy();
|
||||
|
||||
Assert.assertTrue(impl.proxyRevalidate(entry));
|
||||
}
|
||||
|
||||
}
|
|
@ -30,26 +30,45 @@ import java.util.Date;
|
|||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.easymock.classextension.EasyMock;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestCachedHttpResponseGenerator {
|
||||
|
||||
private CacheEntry entry;
|
||||
private CacheValidityPolicy mockValidityPolicy;
|
||||
private CachedHttpResponseGenerator impl;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
|
||||
Header[] hdrs = { new BasicHeader("Date", DateUtils.formatDate(eightSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)),
|
||||
new BasicHeader("Content-Length", "150") };
|
||||
|
||||
entry = new CacheEntry(tenSecondsAgo, sixSecondsAgo, hdrs);
|
||||
mockValidityPolicy = EasyMock.createMock(CacheValidityPolicy.class);
|
||||
impl = new CachedHttpResponseGenerator(mockValidityPolicy);
|
||||
}
|
||||
|
||||
public void replayMocks() {
|
||||
EasyMock.replay(mockValidityPolicy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseHasContentLength() {
|
||||
|
||||
Header[] hdrs = new Header[] {};
|
||||
byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
|
||||
CacheEntry entry = new CacheEntry(
|
||||
new Date(), new Date(), new ProtocolVersion("HTTP", 1, 1), hdrs,
|
||||
new ByteArrayEntity(buf), 200, "OK");
|
||||
CacheEntry entry = new CacheEntry(buf);
|
||||
|
||||
CachedHttpResponseGenerator gen = new CachedHttpResponseGenerator();
|
||||
HttpResponse response = gen.generateResponse(entry);
|
||||
HttpResponse response = impl.generateResponse(entry);
|
||||
|
||||
Header length = response.getFirstHeader("Content-Length");
|
||||
Assert.assertNotNull("Content-Length Header is missing", length);
|
||||
|
@ -63,13 +82,9 @@ public class TestCachedHttpResponseGenerator {
|
|||
|
||||
Header[] hdrs = new Header[] { new BasicHeader("Transfer-Encoding", "chunked") };
|
||||
byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
|
||||
CacheEntry entry = new CacheEntry(
|
||||
new Date(), new Date(), new ProtocolVersion("HTTP", 1, 1), hdrs,
|
||||
new ByteArrayEntity(buf), 200, "OK");
|
||||
CacheEntry entry = new CacheEntry(hdrs, buf);
|
||||
|
||||
|
||||
CachedHttpResponseGenerator gen = new CachedHttpResponseGenerator();
|
||||
HttpResponse response = gen.generateResponse(entry);
|
||||
HttpResponse response = impl.generateResponse(entry);
|
||||
|
||||
Header length = response.getFirstHeader("Content-Length");
|
||||
|
||||
|
@ -78,10 +93,7 @@ public class TestCachedHttpResponseGenerator {
|
|||
|
||||
@Test
|
||||
public void testResponseMatchesCacheEntry() {
|
||||
CacheEntry entry = buildEntry();
|
||||
|
||||
CachedHttpResponseGenerator gen = new CachedHttpResponseGenerator();
|
||||
HttpResponse response = gen.generateResponse(entry);
|
||||
HttpResponse response = impl.generateResponse(entry);
|
||||
|
||||
Assert.assertTrue(response.containsHeader("Content-Length"));
|
||||
|
||||
|
@ -92,36 +104,29 @@ public class TestCachedHttpResponseGenerator {
|
|||
|
||||
@Test
|
||||
public void testResponseStatusCodeMatchesCacheEntry() {
|
||||
CacheEntry entry = buildEntry();
|
||||
|
||||
CachedHttpResponseGenerator gen = new CachedHttpResponseGenerator();
|
||||
HttpResponse response = gen.generateResponse(entry);
|
||||
HttpResponse response = impl.generateResponse(entry);
|
||||
|
||||
Assert.assertEquals(entry.getStatusCode(), response.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAgeHeaderIsPopulatedWithCurrentAgeOfCacheEntryIfNonZero() {
|
||||
final long currAge = 10L;
|
||||
currentAge(10L);
|
||||
replayMocks();
|
||||
|
||||
CacheEntry entry = buildEntryWithCurrentAge(currAge);
|
||||
|
||||
CachedHttpResponseGenerator gen = new CachedHttpResponseGenerator();
|
||||
HttpResponse response = gen.generateResponse(entry);
|
||||
HttpResponse response = impl.generateResponse(entry);
|
||||
|
||||
Header ageHdr = response.getFirstHeader("Age");
|
||||
Assert.assertNotNull(ageHdr);
|
||||
Assert.assertEquals(currAge, Long.parseLong(ageHdr.getValue()));
|
||||
Assert.assertEquals(10L, Long.parseLong(ageHdr.getValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAgeHeaderIsNotPopulatedIfCurrentAgeOfCacheEntryIsZero() {
|
||||
final long currAge = 0L;
|
||||
currentAge(0L);
|
||||
replayMocks();
|
||||
|
||||
CacheEntry entry = buildEntryWithCurrentAge(currAge);
|
||||
|
||||
CachedHttpResponseGenerator gen = new CachedHttpResponseGenerator();
|
||||
HttpResponse response = gen.generateResponse(entry);
|
||||
HttpResponse response = impl.generateResponse(entry);
|
||||
|
||||
Header ageHdr = response.getFirstHeader("Age");
|
||||
Assert.assertNull(ageHdr);
|
||||
|
@ -129,53 +134,19 @@ public class TestCachedHttpResponseGenerator {
|
|||
|
||||
@Test
|
||||
public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() {
|
||||
currentAge(CacheEntry.MAX_AGE + 1L);
|
||||
replayMocks();
|
||||
|
||||
CacheEntry entry = buildEntryWithCurrentAge(CacheEntry.MAX_AGE + 1L);
|
||||
|
||||
CachedHttpResponseGenerator gen = new CachedHttpResponseGenerator();
|
||||
HttpResponse response = gen.generateResponse(entry);
|
||||
HttpResponse response = impl.generateResponse(entry);
|
||||
|
||||
Header ageHdr = response.getFirstHeader("Age");
|
||||
Assert.assertNotNull(ageHdr);
|
||||
Assert.assertEquals(CacheEntry.MAX_AGE, Long.parseLong(ageHdr.getValue()));
|
||||
}
|
||||
|
||||
private CacheEntry buildEntry() {
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
|
||||
Header[] hdrs = { new BasicHeader("Date", DateUtils.formatDate(eightSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)),
|
||||
new BasicHeader("Content-Length", "150") };
|
||||
|
||||
return new CacheEntry(tenSecondsAgo, sixSecondsAgo, new ProtocolVersion("HTTP", 1, 1),
|
||||
hdrs, new ByteArrayEntity(new byte[] {}), 200, "OK");
|
||||
private void currentAge(long sec) {
|
||||
EasyMock.expect(
|
||||
mockValidityPolicy.getCurrentAgeSecs(entry)).andReturn(sec);
|
||||
}
|
||||
|
||||
|
||||
private CacheEntry buildEntryWithCurrentAge(final long currAge){
|
||||
Date now = new Date();
|
||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||
Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L);
|
||||
Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||
Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
|
||||
Header[] hdrs = { new BasicHeader("Date", DateUtils.formatDate(eightSecondsAgo)),
|
||||
new BasicHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)),
|
||||
new BasicHeader("Content-Length", "150") };
|
||||
|
||||
|
||||
return new CacheEntry(tenSecondsAgo, sixSecondsAgo, new ProtocolVersion("HTTP", 1, 1),
|
||||
hdrs, new ByteArrayEntity(new byte[] {}), 200, "OK"){
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public long getCurrentAgeSecs() {
|
||||
return currAge;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
|
@ -38,28 +37,28 @@ import org.junit.Test;
|
|||
|
||||
public class TestCachedResponseSuitabilityChecker {
|
||||
|
||||
private CachedResponseSuitabilityChecker impl;
|
||||
private HttpHost host;
|
||||
private HttpRequest request;
|
||||
private CacheEntry mockEntry;
|
||||
private HttpRequest mockRequest;
|
||||
private CacheEntry entry;
|
||||
private CacheValidityPolicy mockValidityPolicy;
|
||||
private CachedResponseSuitabilityChecker impl;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
host = new HttpHost("foo.example.com");
|
||||
request = new BasicHttpRequest("GET", "/foo");
|
||||
mockEntry = EasyMock.createMock(CacheEntry.class);
|
||||
mockRequest = EasyMock.createMock(HttpRequest.class);
|
||||
mockValidityPolicy = EasyMock.createMock(CacheValidityPolicy.class);
|
||||
entry = new CacheEntry();
|
||||
|
||||
impl = new CachedResponseSuitabilityChecker();
|
||||
impl = new CachedResponseSuitabilityChecker(mockValidityPolicy);
|
||||
}
|
||||
|
||||
public void replayMocks() {
|
||||
EasyMock.replay(mockEntry, mockRequest);
|
||||
EasyMock.replay(mockValidityPolicy);
|
||||
}
|
||||
|
||||
public void verifyMocks() {
|
||||
EasyMock.verify(mockEntry, mockRequest);
|
||||
EasyMock.verify(mockValidityPolicy);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -68,7 +67,7 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
contentLengthMatchesActualLength(false);
|
||||
|
||||
replayMocks();
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
|
||||
verifyMocks();
|
||||
|
||||
|
@ -82,7 +81,7 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
modifiedSince(false, request);
|
||||
|
||||
replayMocks();
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
|
||||
verifyMocks();
|
||||
|
||||
|
@ -97,7 +96,7 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
|
||||
verifyMocks();
|
||||
|
||||
|
@ -109,7 +108,7 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
responseIsFresh(false);
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
|
||||
verifyMocks();
|
||||
|
||||
|
@ -125,7 +124,7 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
verifyMocks();
|
||||
Assert.assertFalse(result);
|
||||
}
|
||||
|
@ -136,11 +135,11 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
responseIsFresh(true);
|
||||
contentLengthMatchesActualLength(true);
|
||||
modifiedSince(false, request);
|
||||
currentAge(20L);
|
||||
|
||||
org.easymock.EasyMock.expect(mockEntry.getCurrentAgeSecs()).andReturn(20L);
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
verifyMocks();
|
||||
Assert.assertFalse(result);
|
||||
}
|
||||
|
@ -151,11 +150,11 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
responseIsFresh(true);
|
||||
contentLengthMatchesActualLength(true);
|
||||
modifiedSince(false, request);
|
||||
currentAge(5L);
|
||||
|
||||
org.easymock.EasyMock.expect(mockEntry.getCurrentAgeSecs()).andReturn(5L);
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
verifyMocks();
|
||||
Assert.assertTrue(result);
|
||||
}
|
||||
|
@ -166,11 +165,11 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
responseIsFresh(true);
|
||||
contentLengthMatchesActualLength(true);
|
||||
modifiedSince(false, request);
|
||||
freshnessLifetime(15L);
|
||||
|
||||
org.easymock.EasyMock.expect(mockEntry.getFreshnessLifetimeSecs()).andReturn(15L);
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
verifyMocks();
|
||||
Assert.assertTrue(result);
|
||||
}
|
||||
|
@ -181,11 +180,11 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
responseIsFresh(true);
|
||||
contentLengthMatchesActualLength(true);
|
||||
modifiedSince(false, request);
|
||||
freshnessLifetime(5L);
|
||||
|
||||
org.easymock.EasyMock.expect(mockEntry.getFreshnessLifetimeSecs()).andReturn(5L);
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
verifyMocks();
|
||||
Assert.assertFalse(result);
|
||||
}
|
||||
|
@ -199,23 +198,21 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
verifyMocks();
|
||||
Assert.assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedCacheControlMaxAgeRequestHeaderCausesUnsuitableEntry() {
|
||||
|
||||
Header[] hdrs = new Header[] { new BasicHeader("Cache-Control", "max-age=foo") };
|
||||
request.addHeader(new BasicHeader("Cache-Control", "max-age=foo"));
|
||||
responseIsFresh(true);
|
||||
contentLengthMatchesActualLength(true);
|
||||
modifiedSince(false, mockRequest);
|
||||
modifiedSince(false, request);
|
||||
|
||||
org.easymock.EasyMock.expect(mockRequest.getHeaders("Cache-Control")).andReturn(hdrs);
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, mockRequest, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
|
||||
verifyMocks();
|
||||
|
||||
|
@ -224,32 +221,43 @@ public class TestCachedResponseSuitabilityChecker {
|
|||
|
||||
@Test
|
||||
public void testMalformedCacheControlMinFreshRequestHeaderCausesUnsuitableEntry() {
|
||||
request.addHeader(new BasicHeader("Cache-Control", "min-fresh=foo"));
|
||||
|
||||
Header[] hdrs = new Header[] { new BasicHeader("Cache-Control", "min-fresh=foo") };
|
||||
responseIsFresh(true);
|
||||
contentLengthMatchesActualLength(true);
|
||||
modifiedSince(false, mockRequest);
|
||||
modifiedSince(false, request);
|
||||
|
||||
org.easymock.EasyMock.expect(mockRequest.getHeaders("Cache-Control")).andReturn(hdrs);
|
||||
replayMocks();
|
||||
|
||||
boolean result = impl.canCachedResponseBeUsed(host, mockRequest, mockEntry);
|
||||
boolean result = impl.canCachedResponseBeUsed(host, request, entry);
|
||||
|
||||
verifyMocks();
|
||||
|
||||
Assert.assertFalse(result);
|
||||
}
|
||||
|
||||
private void currentAge(long sec) {
|
||||
EasyMock.expect(
|
||||
mockValidityPolicy.getCurrentAgeSecs(entry)).andReturn(sec);
|
||||
}
|
||||
|
||||
private void freshnessLifetime(long sec) {
|
||||
EasyMock.expect(
|
||||
mockValidityPolicy.getFreshnessLifetimeSecs(entry)).andReturn(sec);
|
||||
}
|
||||
|
||||
private void responseIsFresh(boolean fresh) {
|
||||
org.easymock.EasyMock.expect(mockEntry.isResponseFresh()).andReturn(fresh);
|
||||
EasyMock.expect(
|
||||
mockValidityPolicy.isResponseFresh(entry)).andReturn(fresh);
|
||||
}
|
||||
|
||||
private void modifiedSince(boolean modified, HttpRequest request) {
|
||||
org.easymock.EasyMock.expect(mockEntry.modifiedSince(request)).andReturn(modified);
|
||||
EasyMock.expect(
|
||||
mockValidityPolicy.modifiedSince(entry, request)).andReturn(modified);
|
||||
}
|
||||
|
||||
private void contentLengthMatchesActualLength(boolean b) {
|
||||
org.easymock.EasyMock.expect(mockEntry.contentLengthHeaderMatchesActualLength()).andReturn(
|
||||
b);
|
||||
EasyMock.expect(
|
||||
mockValidityPolicy.contentLengthHeaderMatchesActualLength(entry)).andReturn(b);
|
||||
}
|
||||
}
|
|
@ -50,6 +50,7 @@ import org.apache.http.client.ClientProtocolException;
|
|||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.client.cache.HttpCache;
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
|
@ -89,11 +90,13 @@ public class TestCachingHttpClient {
|
|||
private static final String GET_RESPONSE_READER = "getResponseReader";
|
||||
|
||||
private CachingHttpClient impl;
|
||||
private boolean mockedImpl;
|
||||
|
||||
private CacheInvalidator mockInvalidator;
|
||||
private CacheValidityPolicy mockValidityPolicy;
|
||||
private CacheableRequestPolicy mockRequestPolicy;
|
||||
private HttpClient mockBackend;
|
||||
private HttpCache<String, CacheEntry> mockCache;
|
||||
private HttpCache mockCache;
|
||||
private CachedResponseSuitabilityChecker mockSuitabilityChecker;
|
||||
private ResponseCachingPolicy mockResponsePolicy;
|
||||
private HttpRequest mockRequest;
|
||||
|
@ -123,8 +126,6 @@ public class TestCachingHttpClient {
|
|||
private Date requestDate;
|
||||
private Date responseDate;
|
||||
|
||||
private boolean mockedImpl;
|
||||
|
||||
private CacheEntryUpdater mockCacheEntryUpdater;
|
||||
private ResponseProtocolCompliance mockResponseProtocolCompliance;
|
||||
private RequestProtocolCompliance mockRequestProtocolCompliance;
|
||||
|
@ -136,6 +137,7 @@ public class TestCachingHttpClient {
|
|||
|
||||
mockInvalidator = EasyMock.createMock(CacheInvalidator.class);
|
||||
mockRequestPolicy = EasyMock.createMock(CacheableRequestPolicy.class);
|
||||
mockValidityPolicy = EasyMock.createMock(CacheValidityPolicy.class);
|
||||
mockBackend = EasyMock.createMock(HttpClient.class);
|
||||
mockCache = EasyMock.createMock(HttpCache.class);
|
||||
mockSuitabilityChecker = EasyMock.createMock(CachedResponseSuitabilityChecker.class);
|
||||
|
@ -168,7 +170,7 @@ public class TestCachingHttpClient {
|
|||
requestDate = new Date(System.currentTimeMillis() - 1000);
|
||||
responseDate = new Date();
|
||||
host = new HttpHost("foo.example.com");
|
||||
impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
|
||||
impl = new CachingHttpClient(mockBackend, mockValidityPolicy, mockResponsePolicy, mockEntryGenerator,
|
||||
mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
|
||||
mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
|
||||
mockCacheEntryUpdater, mockResponseProtocolCompliance,
|
||||
|
@ -179,6 +181,7 @@ public class TestCachingHttpClient {
|
|||
|
||||
EasyMock.replay(mockInvalidator);
|
||||
EasyMock.replay(mockRequestPolicy);
|
||||
EasyMock.replay(mockValidityPolicy);
|
||||
EasyMock.replay(mockSuitabilityChecker);
|
||||
EasyMock.replay(mockResponsePolicy);
|
||||
EasyMock.replay(mockCacheEntry);
|
||||
|
@ -204,7 +207,6 @@ public class TestCachingHttpClient {
|
|||
EasyMock.replay(mockReconstructedResponse);
|
||||
EasyMock.replay(mockResponseProtocolCompliance);
|
||||
EasyMock.replay(mockRequestProtocolCompliance);
|
||||
|
||||
if (mockedImpl) {
|
||||
EasyMock.replay(impl);
|
||||
}
|
||||
|
@ -213,6 +215,7 @@ public class TestCachingHttpClient {
|
|||
private void verifyMocks() {
|
||||
EasyMock.verify(mockInvalidator);
|
||||
EasyMock.verify(mockRequestPolicy);
|
||||
EasyMock.verify(mockValidityPolicy);
|
||||
EasyMock.verify(mockSuitabilityChecker);
|
||||
EasyMock.verify(mockResponsePolicy);
|
||||
EasyMock.verify(mockCacheEntry);
|
||||
|
@ -238,7 +241,6 @@ public class TestCachingHttpClient {
|
|||
EasyMock.verify(mockReconstructedResponse);
|
||||
EasyMock.verify(mockResponseProtocolCompliance);
|
||||
EasyMock.verify(mockRequestProtocolCompliance);
|
||||
|
||||
if (mockedImpl) {
|
||||
EasyMock.verify(impl);
|
||||
}
|
||||
|
@ -288,7 +290,7 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
|
||||
private void requestInspectsRequestLine() {
|
||||
org.easymock.EasyMock.expect(mockRequest.getRequestLine()).andReturn(mockRequestLine);
|
||||
EasyMock.expect(mockRequest.getRequestLine()).andReturn(mockRequestLine);
|
||||
}
|
||||
|
||||
private void requestIsFatallyNonCompliant(RequestProtocolError error) {
|
||||
|
@ -296,7 +298,7 @@ public class TestCachingHttpClient {
|
|||
if (error != null) {
|
||||
errors.add(error);
|
||||
}
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
mockRequestProtocolCompliance.requestIsFatallyNonCompliant(mockRequest)).andReturn(
|
||||
errors);
|
||||
}
|
||||
|
@ -320,12 +322,12 @@ public class TestCachingHttpClient {
|
|||
|
||||
final String variantURI = "variantURI";
|
||||
|
||||
final CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1,
|
||||
new Header[] {}, new ByteArrayEntity(new byte[] {}), 200, "OK");
|
||||
final CacheEntry entry = new CacheEntry(new Date(), new Date(), new OKStatus(),
|
||||
new Header[] {}, new ByteArrayEntity(new byte[] {}));
|
||||
|
||||
replayMocks();
|
||||
|
||||
CacheEntry updatedEntry = impl.doGetUpdatedParentEntry(null, entry, variantURI);
|
||||
HttpCacheEntry updatedEntry = impl.doGetUpdatedParentEntry(null, entry, variantURI);
|
||||
|
||||
verifyMocks();
|
||||
|
||||
|
@ -518,7 +520,7 @@ public class TestCachingHttpClient {
|
|||
gotCacheMiss(theURI);
|
||||
|
||||
replayMocks();
|
||||
CacheEntry result = impl.getCacheEntry(host, mockRequest);
|
||||
HttpCacheEntry result = impl.getCacheEntry(host, mockRequest);
|
||||
verifyMocks();
|
||||
Assert.assertNull(result);
|
||||
}
|
||||
|
@ -532,7 +534,7 @@ public class TestCachingHttpClient {
|
|||
cacheEntryHasVariants(false);
|
||||
|
||||
replayMocks();
|
||||
CacheEntry result = impl.getCacheEntry(host, mockRequest);
|
||||
HttpCacheEntry result = impl.getCacheEntry(host, mockRequest);
|
||||
verifyMocks();
|
||||
Assert.assertSame(mockCacheEntry, result);
|
||||
}
|
||||
|
@ -549,7 +551,7 @@ public class TestCachingHttpClient {
|
|||
gotCacheMiss(variantURI);
|
||||
|
||||
replayMocks();
|
||||
CacheEntry result = impl.getCacheEntry(host, mockRequest);
|
||||
HttpCacheEntry result = impl.getCacheEntry(host, mockRequest);
|
||||
verifyMocks();
|
||||
Assert.assertNull(result);
|
||||
}
|
||||
|
@ -566,7 +568,7 @@ public class TestCachingHttpClient {
|
|||
gotCacheHit(variantURI, mockVariantCacheEntry);
|
||||
|
||||
replayMocks();
|
||||
CacheEntry result = impl.getCacheEntry(host, mockRequest);
|
||||
HttpCacheEntry result = impl.getCacheEntry(host, mockRequest);
|
||||
verifyMocks();
|
||||
Assert.assertSame(mockVariantCacheEntry, result);
|
||||
}
|
||||
|
@ -624,7 +626,7 @@ public class TestCachingHttpClient {
|
|||
final HttpHost theHost = host;
|
||||
final HttpRequest theRequest = mockRequest;
|
||||
final HttpResponse theResponse = mockBackendResponse;
|
||||
impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
|
||||
impl = new CachingHttpClient(mockBackend, mockValidityPolicy, mockResponsePolicy, mockEntryGenerator,
|
||||
mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
|
||||
mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
|
||||
mockCacheEntryUpdater, mockResponseProtocolCompliance,
|
||||
|
@ -656,7 +658,7 @@ public class TestCachingHttpClient {
|
|||
final HttpResponse theResponse = mockBackendResponse;
|
||||
final ResponseHandler<Object> theHandler = mockHandler;
|
||||
final Object value = new Object();
|
||||
impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
|
||||
impl = new CachingHttpClient(mockBackend, mockValidityPolicy, mockResponsePolicy, mockEntryGenerator,
|
||||
mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
|
||||
mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
|
||||
mockCacheEntryUpdater, mockResponseProtocolCompliance,
|
||||
|
@ -677,7 +679,7 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
};
|
||||
|
||||
org.easymock.EasyMock.expect(mockHandler.handleResponse(mockBackendResponse)).andReturn(
|
||||
EasyMock.expect(mockHandler.handleResponse(mockBackendResponse)).andReturn(
|
||||
value);
|
||||
|
||||
replayMocks();
|
||||
|
@ -696,7 +698,7 @@ public class TestCachingHttpClient {
|
|||
final HttpRequest theRequest = mockRequest;
|
||||
final HttpResponse theResponse = mockBackendResponse;
|
||||
final HttpContext theContext = mockContext;
|
||||
impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
|
||||
impl = new CachingHttpClient(mockBackend, mockValidityPolicy, mockResponsePolicy, mockEntryGenerator,
|
||||
mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
|
||||
mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
|
||||
mockCacheEntryUpdater, mockResponseProtocolCompliance,
|
||||
|
@ -713,7 +715,7 @@ public class TestCachingHttpClient {
|
|||
|
||||
final Object theObject = new Object();
|
||||
|
||||
org.easymock.EasyMock.expect(mockHandler.handleResponse(mockBackendResponse)).andReturn(
|
||||
EasyMock.expect(mockHandler.handleResponse(mockBackendResponse)).andReturn(
|
||||
theObject);
|
||||
|
||||
replayMocks();
|
||||
|
@ -728,7 +730,7 @@ public class TestCachingHttpClient {
|
|||
final Counter c = new Counter();
|
||||
final HttpUriRequest theRequest = mockUriRequest;
|
||||
final HttpResponse theResponse = mockBackendResponse;
|
||||
impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
|
||||
impl = new CachingHttpClient(mockBackend, mockValidityPolicy, mockResponsePolicy, mockEntryGenerator,
|
||||
mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
|
||||
mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
|
||||
mockCacheEntryUpdater, mockResponseProtocolCompliance,
|
||||
|
@ -758,7 +760,7 @@ public class TestCachingHttpClient {
|
|||
final HttpRequest theRequest = mockUriRequest;
|
||||
final HttpContext theContext = mockContext;
|
||||
final HttpResponse theResponse = mockBackendResponse;
|
||||
impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
|
||||
impl = new CachingHttpClient(mockBackend, mockValidityPolicy, mockResponsePolicy, mockEntryGenerator,
|
||||
mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
|
||||
mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
|
||||
mockCacheEntryUpdater, mockResponseProtocolCompliance,
|
||||
|
@ -775,7 +777,7 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
};
|
||||
|
||||
org.easymock.EasyMock.expect(mockUriRequest.getURI()).andReturn(uri);
|
||||
EasyMock.expect(mockUriRequest.getURI()).andReturn(uri);
|
||||
|
||||
replayMocks();
|
||||
HttpResponse result = impl.execute(mockUriRequest, mockContext);
|
||||
|
@ -791,7 +793,7 @@ public class TestCachingHttpClient {
|
|||
final HttpUriRequest theRequest = mockUriRequest;
|
||||
final HttpResponse theResponse = mockBackendResponse;
|
||||
final Object theValue = new Object();
|
||||
impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
|
||||
impl = new CachingHttpClient(mockBackend, mockValidityPolicy, mockResponsePolicy, mockEntryGenerator,
|
||||
mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
|
||||
mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
|
||||
mockCacheEntryUpdater, mockResponseProtocolCompliance,
|
||||
|
@ -806,7 +808,7 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
};
|
||||
|
||||
org.easymock.EasyMock.expect(mockHandler.handleResponse(mockBackendResponse)).andReturn(
|
||||
EasyMock.expect(mockHandler.handleResponse(mockBackendResponse)).andReturn(
|
||||
theValue);
|
||||
|
||||
replayMocks();
|
||||
|
@ -826,7 +828,7 @@ public class TestCachingHttpClient {
|
|||
final HttpContext theContext = mockContext;
|
||||
final HttpResponse theResponse = mockBackendResponse;
|
||||
final Object theValue = new Object();
|
||||
impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
|
||||
impl = new CachingHttpClient(mockBackend, mockValidityPolicy, mockResponsePolicy, mockEntryGenerator,
|
||||
mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
|
||||
mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
|
||||
mockCacheEntryUpdater, mockResponseProtocolCompliance,
|
||||
|
@ -841,7 +843,7 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
};
|
||||
|
||||
org.easymock.EasyMock.expect(mockHandler.handleResponse(mockBackendResponse)).andReturn(
|
||||
EasyMock.expect(mockHandler.handleResponse(mockBackendResponse)).andReturn(
|
||||
theValue);
|
||||
|
||||
replayMocks();
|
||||
|
@ -853,7 +855,7 @@ public class TestCachingHttpClient {
|
|||
|
||||
@Test
|
||||
public void testUsesBackendsConnectionManager() {
|
||||
org.easymock.EasyMock.expect(mockBackend.getConnectionManager()).andReturn(
|
||||
EasyMock.expect(mockBackend.getConnectionManager()).andReturn(
|
||||
mockConnectionManager);
|
||||
replayMocks();
|
||||
ClientConnectionManager result = impl.getConnectionManager();
|
||||
|
@ -863,7 +865,7 @@ public class TestCachingHttpClient {
|
|||
|
||||
@Test
|
||||
public void testUsesBackendsHttpParams() {
|
||||
org.easymock.EasyMock.expect(mockBackend.getParams()).andReturn(mockParams);
|
||||
EasyMock.expect(mockBackend.getParams()).andReturn(mockParams);
|
||||
replayMocks();
|
||||
HttpParams result = impl.getParams();
|
||||
verifyMocks();
|
||||
|
@ -881,7 +883,7 @@ public class TestCachingHttpClient {
|
|||
ClientConnectionManager cm = new ThreadSafeClientConnManager(schemeRegistry);
|
||||
HttpClient httpClient = new DefaultHttpClient(cm);
|
||||
|
||||
HttpCache<String, CacheEntry> cacheImpl = new BasicHttpCache(100);
|
||||
HttpCache cacheImpl = new BasicHttpCache(100);
|
||||
|
||||
CachingHttpClient cachingClient = new CachingHttpClient(httpClient, cacheImpl, 8192);
|
||||
|
||||
|
@ -1072,19 +1074,19 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
|
||||
private void callBackendReturnsResponse(HttpResponse response) throws IOException {
|
||||
org.easymock.EasyMock.expect(impl.callBackend(host, mockRequest, mockContext)).andReturn(
|
||||
EasyMock.expect(impl.callBackend(host, mockRequest, mockContext)).andReturn(
|
||||
response);
|
||||
}
|
||||
|
||||
private void revalidateCacheEntryReturns(HttpResponse response) throws IOException,
|
||||
ProtocolException {
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
impl.revalidateCacheEntry(host, mockRequest, mockContext, mockCacheEntry))
|
||||
.andReturn(response);
|
||||
}
|
||||
|
||||
private void cacheEntryValidatable(boolean b) {
|
||||
org.easymock.EasyMock.expect(mockCacheEntry.isRevalidatable()).andReturn(b);
|
||||
EasyMock.expect(mockValidityPolicy.isRevalidatable(mockCacheEntry)).andReturn(b);
|
||||
}
|
||||
|
||||
private void cacheEntryUpdaterCalled() throws IOException {
|
||||
|
@ -1094,26 +1096,26 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
|
||||
private void getCacheEntryReturns(CacheEntry entry) {
|
||||
org.easymock.EasyMock.expect(impl.getCacheEntry(host, mockRequest)).andReturn(entry);
|
||||
EasyMock.expect(impl.getCacheEntry(host, mockRequest)).andReturn(entry);
|
||||
}
|
||||
|
||||
private void backendResponseCodeIs(int code) {
|
||||
org.easymock.EasyMock.expect(mockBackendResponse.getStatusLine()).andReturn(mockStatusLine);
|
||||
org.easymock.EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(code);
|
||||
EasyMock.expect(mockBackendResponse.getStatusLine()).andReturn(mockStatusLine);
|
||||
EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(code);
|
||||
}
|
||||
|
||||
private void conditionalRequestBuilderCalled() throws ProtocolException {
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
mockConditionalRequestBuilder.buildConditionalRequest(mockRequest, mockCacheEntry))
|
||||
.andReturn(mockConditionalRequest);
|
||||
}
|
||||
|
||||
private void getCurrentDateReturns(Date date) {
|
||||
org.easymock.EasyMock.expect(impl.getCurrentDate()).andReturn(date);
|
||||
EasyMock.expect(impl.getCurrentDate()).andReturn(date);
|
||||
}
|
||||
|
||||
private void getMockResponseReader() {
|
||||
org.easymock.EasyMock.expect(impl.getResponseReader(mockBackendResponse)).andReturn(
|
||||
EasyMock.expect(impl.getResponseReader(mockBackendResponse)).andReturn(
|
||||
mockResponseReader);
|
||||
}
|
||||
|
||||
|
@ -1122,7 +1124,7 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
|
||||
private void requestPolicyAllowsCaching(boolean allow) {
|
||||
org.easymock.EasyMock.expect(mockRequestPolicy.isServableFromCache(mockRequest)).andReturn(
|
||||
EasyMock.expect(mockRequestPolicy.isServableFromCache(mockRequest)).andReturn(
|
||||
allow);
|
||||
}
|
||||
|
||||
|
@ -1133,50 +1135,50 @@ public class TestCachingHttpClient {
|
|||
|
||||
private byte[] responseReaderReturnsBufferOfSize(int bufferSize) {
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
org.easymock.EasyMock.expect(mockResponseReader.getResponseBytes()).andReturn(buffer);
|
||||
EasyMock.expect(mockResponseReader.getResponseBytes()).andReturn(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private void readerReturnsReconstructedResponse() {
|
||||
org.easymock.EasyMock.expect(mockResponseReader.getReconstructedResponse()).andReturn(
|
||||
EasyMock.expect(mockResponseReader.getReconstructedResponse()).andReturn(
|
||||
mockReconstructedResponse);
|
||||
}
|
||||
|
||||
private void responseIsTooLarge(boolean tooLarge) throws Exception {
|
||||
org.easymock.EasyMock.expect(mockResponseReader.isResponseTooLarge()).andReturn(tooLarge);
|
||||
EasyMock.expect(mockResponseReader.isResponseTooLarge()).andReturn(tooLarge);
|
||||
}
|
||||
|
||||
private void backendCallWasMadeWithRequest(HttpRequest request) throws IOException {
|
||||
org.easymock.EasyMock.expect(mockBackend.execute(host, request, mockContext)).andReturn(
|
||||
EasyMock.expect(mockBackend.execute(host, request, mockContext)).andReturn(
|
||||
mockBackendResponse);
|
||||
}
|
||||
|
||||
private void responsePolicyAllowsCaching(boolean allow) {
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
mockResponsePolicy.isResponseCacheable(mockRequest, mockBackendResponse))
|
||||
.andReturn(allow);
|
||||
}
|
||||
|
||||
private void gotCacheMiss(String theURI) throws Exception {
|
||||
org.easymock.EasyMock.expect(mockCache.getEntry(theURI)).andReturn(null);
|
||||
EasyMock.expect(mockCache.getEntry(theURI)).andReturn(null);
|
||||
}
|
||||
|
||||
private void cacheEntrySuitable(boolean suitable) {
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
mockSuitabilityChecker.canCachedResponseBeUsed(host, mockRequest, mockCacheEntry))
|
||||
.andReturn(suitable);
|
||||
}
|
||||
|
||||
private void gotCacheHit(String theURI) throws Exception {
|
||||
org.easymock.EasyMock.expect(mockCache.getEntry(theURI)).andReturn(mockCacheEntry);
|
||||
EasyMock.expect(mockCache.getEntry(theURI)).andReturn(mockCacheEntry);
|
||||
}
|
||||
|
||||
private void gotCacheHit(String theURI, CacheEntry entry) throws Exception {
|
||||
org.easymock.EasyMock.expect(mockCache.getEntry(theURI)).andReturn(entry);
|
||||
EasyMock.expect(mockCache.getEntry(theURI)).andReturn(entry);
|
||||
}
|
||||
|
||||
private void cacheEntryHasVariants(boolean b) {
|
||||
org.easymock.EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(b);
|
||||
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(b);
|
||||
}
|
||||
|
||||
private void cacheEntryHasVariants(boolean b, CacheEntry entry) {
|
||||
|
@ -1195,12 +1197,12 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
|
||||
private void responseIsGeneratedFromCache(CacheEntry entry) {
|
||||
org.easymock.EasyMock.expect(mockResponseGenerator.generateResponse(entry))
|
||||
EasyMock.expect(mockResponseGenerator.generateResponse(entry))
|
||||
.andReturn(mockCachedResponse);
|
||||
}
|
||||
|
||||
private void extractTheURI(String theURI) {
|
||||
org.easymock.EasyMock.expect(mockExtractor.getURI(host, mockRequest)).andReturn(theURI);
|
||||
EasyMock.expect(mockExtractor.getURI(host, mockRequest)).andReturn(theURI);
|
||||
}
|
||||
|
||||
private void extractVariantURI(String variantURI) {
|
||||
|
@ -1208,7 +1210,7 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
|
||||
private void extractVariantURI(String variantURI, CacheEntry entry){
|
||||
org.easymock.EasyMock
|
||||
EasyMock
|
||||
.expect(mockExtractor.getVariantURI(host, mockRequest, entry)).andReturn(
|
||||
variantURI);
|
||||
}
|
||||
|
@ -1222,14 +1224,14 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
|
||||
private void generateCacheEntry(Date requestDate, Date responseDate, byte[] bytes) {
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
mockEntryGenerator.generateEntry(requestDate, responseDate, mockBackendResponse,
|
||||
bytes)).andReturn(mockCacheEntry);
|
||||
}
|
||||
|
||||
private void handleBackendResponseReturnsResponse(HttpRequest request, HttpResponse response)
|
||||
throws IOException {
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
impl.handleBackendResponse(host, request, requestDate, responseDate,
|
||||
mockBackendResponse)).andReturn(response);
|
||||
}
|
||||
|
@ -1247,24 +1249,25 @@ public class TestCachingHttpClient {
|
|||
}
|
||||
|
||||
private void requestProtocolValidationIsCalled() throws Exception {
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
mockRequestProtocolCompliance.makeRequestCompliant(mockRequest)).andReturn(
|
||||
mockRequest);
|
||||
}
|
||||
|
||||
private void requestCannotBeMadeCompliantThrows(ProtocolException exception) throws Exception {
|
||||
org.easymock.EasyMock.expect(
|
||||
EasyMock.expect(
|
||||
mockRequestProtocolCompliance.makeRequestCompliant(mockRequest))
|
||||
.andThrow(exception);
|
||||
}
|
||||
|
||||
private void mockImplMethods(String... methods) {
|
||||
mockedImpl = true;
|
||||
impl = EasyMock.createMockBuilder(CachingHttpClient.class).withConstructor(mockBackend,
|
||||
impl = EasyMock.createMockBuilder(CachingHttpClient.class).withConstructor(mockBackend, mockValidityPolicy,
|
||||
mockResponsePolicy, mockEntryGenerator, mockExtractor, mockCache,
|
||||
mockResponseGenerator, mockInvalidator, mockRequestPolicy, mockSuitabilityChecker,
|
||||
mockConditionalRequestBuilder, mockCacheEntryUpdater,
|
||||
mockResponseProtocolCompliance, mockRequestProtocolCompliance).addMockedMethods(
|
||||
methods).createMock();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,10 +31,8 @@ import java.util.Date;
|
|||
import org.apache.http.Header;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.ProtocolException;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
|
@ -66,8 +64,8 @@ public class TestConditionalRequestBuilder {
|
|||
new BasicHeader("Last-Modified", lastModified) };
|
||||
|
||||
CacheEntry cacheEntry = new CacheEntry(new Date(), new Date(),
|
||||
new ProtocolVersion("HTTP",1,1), headers,
|
||||
new ByteArrayEntity(new byte[] {}), 200, "OK");
|
||||
new OKStatus(), headers,
|
||||
new ByteArrayEntity(new byte[] {}));
|
||||
HttpRequest newRequest = impl.buildConditionalRequest(request, cacheEntry);
|
||||
|
||||
Assert.assertNotSame(request, newRequest);
|
||||
|
@ -100,9 +98,7 @@ public class TestConditionalRequestBuilder {
|
|||
new BasicHeader("ETag", theETag) };
|
||||
|
||||
CacheEntry cacheEntry = new CacheEntry(new Date(), new Date(),
|
||||
new ProtocolVersion("HTTP",1,1), headers, new ByteArrayEntity(new byte[] {}),
|
||||
200, "OK");
|
||||
|
||||
new OKStatus(), headers, new ByteArrayEntity(new byte[] {}));
|
||||
|
||||
HttpRequest newRequest = impl.buildConditionalRequest(request, cacheEntry);
|
||||
|
||||
|
@ -135,8 +131,7 @@ public class TestConditionalRequestBuilder {
|
|||
new BasicHeader("ETag", "\"etag\""),
|
||||
new BasicHeader("Cache-Control","max-age=5, must-revalidate") };
|
||||
CacheEntry cacheEntry = new CacheEntry(elevenSecondsAgo, nineSecondsAgo,
|
||||
HttpVersion.HTTP_1_1, cacheEntryHeaders, new ByteArrayEntity(new byte[0]),
|
||||
HttpStatus.SC_OK, "OK");
|
||||
new OKStatus(), cacheEntryHeaders, new ByteArrayEntity(new byte[0]));
|
||||
|
||||
HttpRequest result = impl.buildConditionalRequest(request, cacheEntry);
|
||||
|
||||
|
@ -165,8 +160,7 @@ public class TestConditionalRequestBuilder {
|
|||
new BasicHeader("ETag", "\"etag\""),
|
||||
new BasicHeader("Cache-Control","max-age=5, proxy-revalidate") };
|
||||
CacheEntry cacheEntry = new CacheEntry(elevenSecondsAgo, nineSecondsAgo,
|
||||
HttpVersion.HTTP_1_1, cacheEntryHeaders, new ByteArrayEntity(new byte[0]),
|
||||
HttpStatus.SC_OK, "OK");
|
||||
new OKStatus(), cacheEntryHeaders, new ByteArrayEntity(new byte[0]));
|
||||
|
||||
HttpRequest result = impl.buildConditionalRequest(request, cacheEntry);
|
||||
|
||||
|
|
|
@ -77,13 +77,12 @@ public class TestProtocolDeviations {
|
|||
private HttpEntity body;
|
||||
private HttpEntity mockEntity;
|
||||
private HttpClient mockBackend;
|
||||
private HttpCache<String, CacheEntry> mockCache;
|
||||
private HttpCache mockCache;
|
||||
private HttpRequest request;
|
||||
private HttpResponse originResponse;
|
||||
|
||||
private CachingHttpClient impl;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void setUp() {
|
||||
host = new HttpHost("foo.example.com");
|
||||
|
@ -94,7 +93,7 @@ public class TestProtocolDeviations {
|
|||
|
||||
originResponse = make200Response();
|
||||
|
||||
HttpCache<String, CacheEntry> cache = new BasicHttpCache(MAX_ENTRIES);
|
||||
HttpCache cache = new BasicHttpCache(MAX_ENTRIES);
|
||||
mockBackend = EasyMock.createMock(HttpClient.class);
|
||||
mockEntity = EasyMock.createMock(HttpEntity.class);
|
||||
mockCache = EasyMock.createMock(HttpCache.class);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
package org.apache.http.impl.client.cache;
|
||||
|
||||
import org.apache.http.client.cache.HttpCacheEntry;
|
||||
import org.apache.http.client.cache.HttpCacheOperationException;
|
||||
import org.apache.http.client.cache.HttpCacheUpdateCallback;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
|
@ -41,19 +42,19 @@ import java.io.IOException;
|
|||
public class TestResponseCache {
|
||||
|
||||
private BasicHttpCache cache;
|
||||
private CacheEntry mockEntry;
|
||||
private HttpCacheEntry mockEntry;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
cache = new BasicHttpCache(5);
|
||||
mockEntry = EasyMock.createMock(CacheEntry.class);
|
||||
mockEntry = EasyMock.createMock(HttpCacheEntry.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntryRemainsInCacheWhenPutThere() {
|
||||
cache.putEntry("foo", mockEntry);
|
||||
|
||||
CacheEntry cachedEntry = cache.getEntry("foo");
|
||||
HttpCacheEntry cachedEntry = cache.getEntry("foo");
|
||||
|
||||
Assert.assertSame(mockEntry, cachedEntry);
|
||||
}
|
||||
|
@ -64,7 +65,7 @@ public class TestResponseCache {
|
|||
|
||||
cache.removeEntry("foo");
|
||||
|
||||
CacheEntry nullEntry = cache.getEntry("foo");
|
||||
HttpCacheEntry nullEntry = cache.getEntry("foo");
|
||||
|
||||
Assert.assertNull(nullEntry);
|
||||
}
|
||||
|
@ -73,22 +74,22 @@ public class TestResponseCache {
|
|||
public void testCacheHoldsNoMoreThanSpecifiedMaxEntries() {
|
||||
BasicHttpCache cache = new BasicHttpCache(1);
|
||||
|
||||
CacheEntry entry1 = EasyMock.createMock(CacheEntry.class);
|
||||
HttpCacheEntry entry1 = EasyMock.createMock(HttpCacheEntry.class);
|
||||
cache.putEntry("foo", entry1);
|
||||
|
||||
CacheEntry entry2 = EasyMock.createMock(CacheEntry.class);
|
||||
HttpCacheEntry entry2 = EasyMock.createMock(HttpCacheEntry.class);
|
||||
cache.putEntry("bar", entry2);
|
||||
|
||||
CacheEntry entry3 = EasyMock.createMock(CacheEntry.class);
|
||||
HttpCacheEntry entry3 = EasyMock.createMock(HttpCacheEntry.class);
|
||||
cache.putEntry("baz", entry3);
|
||||
|
||||
CacheEntry e1 = cache.getEntry("foo");
|
||||
HttpCacheEntry e1 = cache.getEntry("foo");
|
||||
Assert.assertNull("Got foo entry when we should not", e1);
|
||||
|
||||
CacheEntry e2 = cache.getEntry("bar");
|
||||
HttpCacheEntry e2 = cache.getEntry("bar");
|
||||
Assert.assertNull("Got bar entry when we should not", e2);
|
||||
|
||||
CacheEntry e3 = cache.getEntry("baz");
|
||||
HttpCacheEntry e3 = cache.getEntry("baz");
|
||||
Assert.assertNotNull("Did not get baz entry, but should have", e3);
|
||||
}
|
||||
|
||||
|
@ -100,7 +101,7 @@ public class TestResponseCache {
|
|||
|
||||
// fill the cache with entries
|
||||
for (int i = 0; i < max_size; i++) {
|
||||
CacheEntry entry = EasyMock.createMock(CacheEntry.class);
|
||||
HttpCacheEntry entry = EasyMock.createMock(HttpCacheEntry.class);
|
||||
cache.putEntry("entry" + i, entry);
|
||||
}
|
||||
|
||||
|
@ -109,17 +110,17 @@ public class TestResponseCache {
|
|||
|
||||
// add another entry, which kicks out the eldest (should be the 2nd one
|
||||
// created), and becomes the new MRU entry
|
||||
CacheEntry newMru = EasyMock.createMock(CacheEntry.class);
|
||||
HttpCacheEntry newMru = EasyMock.createMock(HttpCacheEntry.class);
|
||||
cache.putEntry("newMru", newMru);
|
||||
|
||||
// get the original second eldest
|
||||
CacheEntry gone = cache.getEntry("entry1");
|
||||
HttpCacheEntry gone = cache.getEntry("entry1");
|
||||
Assert.assertNull("entry1 should be gone", gone);
|
||||
|
||||
CacheEntry latest = cache.getEntry("newMru");
|
||||
HttpCacheEntry latest = cache.getEntry("newMru");
|
||||
Assert.assertNotNull("latest entry should still be there", latest);
|
||||
|
||||
CacheEntry originalEldest = cache.getEntry("entry0");
|
||||
HttpCacheEntry originalEldest = cache.getEntry("entry0");
|
||||
Assert.assertNotNull("original eldest entry should still be there", originalEldest);
|
||||
}
|
||||
|
||||
|
@ -127,10 +128,10 @@ public class TestResponseCache {
|
|||
public void testZeroMaxSizeCacheDoesNotStoreAnything() {
|
||||
BasicHttpCache cache = new BasicHttpCache(0);
|
||||
|
||||
CacheEntry entry = EasyMock.createMock(CacheEntry.class);
|
||||
HttpCacheEntry entry = EasyMock.createMock(HttpCacheEntry.class);
|
||||
cache.putEntry("foo", entry);
|
||||
|
||||
CacheEntry gone = cache.getEntry("foo");
|
||||
HttpCacheEntry gone = cache.getEntry("foo");
|
||||
|
||||
Assert.assertNull("This cache should not have anything in it!", gone);
|
||||
}
|
||||
|
@ -141,30 +142,29 @@ public class TestResponseCache {
|
|||
|
||||
final byte[] expectedArray = new byte[] { 1, 2, 3, 4, 5 };
|
||||
|
||||
CacheEntry entry = EasyMock.createMock(CacheEntry.class);
|
||||
CacheEntry entry2 = EasyMock.createMock(CacheEntry.class);
|
||||
HttpCacheEntry entry = EasyMock.createMock(HttpCacheEntry.class);
|
||||
HttpCacheEntry entry2 = EasyMock.createMock(HttpCacheEntry.class);
|
||||
|
||||
cache.putEntry("foo", entry);
|
||||
cache.putEntry("bar", entry2);
|
||||
|
||||
cache.updateEntry("foo", new HttpCacheUpdateCallback<CacheEntry>() {
|
||||
cache.updateEntry("foo", new HttpCacheUpdateCallback() {
|
||||
|
||||
public CacheEntry update(CacheEntry existing) {
|
||||
CacheEntry updated = new CacheEntry(
|
||||
public HttpCacheEntry update(HttpCacheEntry existing) {
|
||||
HttpCacheEntry updated = new HttpCacheEntry(
|
||||
existing.getRequestDate(),
|
||||
existing.getRequestDate(),
|
||||
existing.getProtocolVersion(),
|
||||
existing.getStatusLine(),
|
||||
existing.getAllHeaders(),
|
||||
new ByteArrayEntity(expectedArray),
|
||||
existing.getStatusCode(),
|
||||
existing.getReasonPhrase());
|
||||
null);
|
||||
cache.removeEntry("bar");
|
||||
return updated;
|
||||
}
|
||||
});
|
||||
|
||||
CacheEntry afterUpdate = cache.getEntry("foo");
|
||||
CacheEntry bar = cache.getEntry("bar");
|
||||
HttpCacheEntry afterUpdate = cache.getEntry("foo");
|
||||
HttpCacheEntry bar = cache.getEntry("bar");
|
||||
|
||||
Assert.assertNull(bar);
|
||||
|
||||
|
|
Loading…
Reference in New Issue