HTTPCLIENT-943: CacheClient Javadoc and Constants usage cleanup
Contributed by Joe Campbell <joseph.r.campbell at gmail.com> git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@948754 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
bd15468e72
commit
0ea086094e
|
@ -34,6 +34,7 @@ import java.io.Serializable;
|
|||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
@ -47,27 +48,31 @@ class CacheEntity implements HttpEntity, Cloneable, Serializable {
|
|||
private final String contentType;
|
||||
private final String contentEncoding;
|
||||
|
||||
public CacheEntity(final byte[] b, final String contentType, final String contentEncoding) {
|
||||
public CacheEntity(final byte[] b, final HttpResponse response) {
|
||||
super();
|
||||
this.content = b;
|
||||
this.contentType = contentType;
|
||||
this.contentEncoding = contentEncoding;
|
||||
|
||||
Header ct = response.getFirstHeader(HTTP.CONTENT_TYPE);
|
||||
Header ce = response.getFirstHeader(HTTP.CONTENT_ENCODING);
|
||||
|
||||
this.contentType = ct != null ? ct.getValue() : null;
|
||||
this.contentEncoding = ce != null ? ce.getValue() : null;
|
||||
}
|
||||
|
||||
public Header getContentType() {
|
||||
if (this.contentType != null) {
|
||||
return new BasicHeader(HTTP.CONTENT_TYPE, this.contentType);
|
||||
} else {
|
||||
if (this.contentType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BasicHeader(HTTP.CONTENT_TYPE, this.contentType);
|
||||
}
|
||||
|
||||
public Header getContentEncoding() {
|
||||
if (this.contentEncoding != null) {
|
||||
return new BasicHeader(HTTP.CONTENT_ENCODING, this.contentEncoding);
|
||||
} else {
|
||||
if (this.contentEncoding == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BasicHeader(HTTP.CONTENT_ENCODING, this.contentEncoding);
|
||||
}
|
||||
|
||||
public boolean isChunked() {
|
||||
|
|
|
@ -45,6 +45,7 @@ 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
|
||||
|
@ -68,6 +69,7 @@ public class CacheEntry implements Serializable {
|
|||
private final Set<String> variantURIs;
|
||||
|
||||
/**
|
||||
* Create a new {@link CacheEntry}
|
||||
*
|
||||
* @param requestDate
|
||||
* Date/time when the request was made (Used for age
|
||||
|
@ -79,8 +81,8 @@ public class CacheEntry implements Serializable {
|
|||
* HTTP Response Version
|
||||
* @param responseHeaders
|
||||
* Header[] from original HTTP Response
|
||||
* @param responseBytes
|
||||
* Byte array containing the body of the response
|
||||
* @param body
|
||||
* HttpEntity representing the body of the response
|
||||
* @param status
|
||||
* Numeric HTTP Status Code
|
||||
* @param reason
|
||||
|
@ -102,6 +104,7 @@ public class CacheEntry implements Serializable {
|
|||
|
||||
/**
|
||||
* Constructor used to create a copy of an existing entry, while adding another variant URI to it.
|
||||
*
|
||||
* @param toCopy CacheEntry to be duplicated
|
||||
* @param variantURI URI to add
|
||||
*/
|
||||
|
@ -158,12 +161,8 @@ public class CacheEntry implements Serializable {
|
|||
return responseHeaders.getHeaders(name);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Response Date header value
|
||||
*/
|
||||
protected Date getDateValue() {
|
||||
Header dateHdr = getFirstHeader(HeaderConstants.DATE);
|
||||
Header dateHdr = getFirstHeader(HTTP.DATE_HEADER);
|
||||
if (dateHdr == null)
|
||||
return null;
|
||||
try {
|
||||
|
@ -175,7 +174,7 @@ public class CacheEntry implements Serializable {
|
|||
}
|
||||
|
||||
protected long getContentLengthValue() {
|
||||
Header cl = getFirstHeader(HeaderConstants.CONTENT_LENGTH);
|
||||
Header cl = getFirstHeader(HTTP.CONTENT_LEN);
|
||||
if (cl == null)
|
||||
return -1;
|
||||
|
||||
|
@ -196,10 +195,6 @@ public class CacheEntry implements Serializable {
|
|||
return getContentLengthValue() == body.getContentLength();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Apparent age of the response
|
||||
*/
|
||||
protected long getApparentAgeSecs() {
|
||||
Date dateValue = getDateValue();
|
||||
if (dateValue == null)
|
||||
|
@ -210,10 +205,6 @@ public class CacheEntry implements Serializable {
|
|||
return (diff / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Response Age header value
|
||||
*/
|
||||
protected long getAgeValue() {
|
||||
long ageValue = 0;
|
||||
for (Header hdr : getHeaders(HeaderConstants.AGE)) {
|
||||
|
@ -237,10 +228,6 @@ public class CacheEntry implements Serializable {
|
|||
return (apparentAge > ageValue) ? apparentAge : ageValue;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Delay between request and response
|
||||
*/
|
||||
protected long getResponseDelaySecs() {
|
||||
long diff = responseDate.getTime() - requestDate.getTime();
|
||||
return (diff / 1000L);
|
||||
|
|
|
@ -28,10 +28,8 @@ package org.apache.http.impl.client.cache;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* Generates a {@link CacheEntry} from a {@link HttpResponse}
|
||||
|
@ -43,12 +41,9 @@ public class CacheEntryGenerator {
|
|||
|
||||
public CacheEntry generateEntry(Date requestDate, Date responseDate, HttpResponse response,
|
||||
byte[] body) {
|
||||
Header ct = response.getFirstHeader(HTTP.CONTENT_TYPE);
|
||||
Header ce = response.getFirstHeader(HTTP.CONTENT_ENCODING);
|
||||
CacheEntity entity = new CacheEntity(
|
||||
body,
|
||||
ct != null ? ct.getValue() : null,
|
||||
ce != null ? ce.getValue() : null);
|
||||
|
||||
CacheEntity entity = new CacheEntity(body, response);
|
||||
|
||||
return new CacheEntry(requestDate,
|
||||
responseDate,
|
||||
response.getProtocolVersion(),
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.apache.http.HttpResponse;
|
|||
import org.apache.http.annotation.Immutable;
|
||||
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
|
||||
|
@ -129,9 +130,9 @@ public class CacheEntryUpdater {
|
|||
|
||||
private boolean entryDateHeaderNewerThenResponse(CacheEntry entry, HttpResponse response) {
|
||||
try {
|
||||
Date entryDate = DateUtils.parseDate(entry.getFirstHeader(HeaderConstants.DATE)
|
||||
Date entryDate = DateUtils.parseDate(entry.getFirstHeader(HTTP.DATE_HEADER)
|
||||
.getValue());
|
||||
Date responseDate = DateUtils.parseDate(response.getFirstHeader(HeaderConstants.DATE)
|
||||
Date responseDate = DateUtils.parseDate(response.getFirstHeader(HTTP.DATE_HEADER)
|
||||
.getValue());
|
||||
|
||||
if (!entryDate.after(responseDate)) {
|
||||
|
@ -145,8 +146,8 @@ public class CacheEntryUpdater {
|
|||
}
|
||||
|
||||
private boolean entryAndResponseHaveDateHeader(CacheEntry entry, HttpResponse response) {
|
||||
if (entry.getFirstHeader(HeaderConstants.DATE) != null
|
||||
&& response.getFirstHeader(HeaderConstants.DATE) != null) {
|
||||
if (entry.getFirstHeader(HTTP.DATE_HEADER) != null
|
||||
&& response.getFirstHeader(HTTP.DATE_HEADER) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,9 +51,11 @@ public class CacheInvalidator {
|
|||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
* Create a new {@link CacheInvalidator} for a given {@link HttpCache} and
|
||||
* {@link URIExtractor}.
|
||||
*
|
||||
* @param uriExtractor
|
||||
* @param cache
|
||||
* @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<CacheEntry> cache) {
|
||||
this.uriExtractor = uriExtractor;
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.http.HttpStatus;
|
|||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* Rebuilds an {@link HttpResponse} from a {@link CacheEntry}
|
||||
|
@ -43,6 +44,8 @@ import org.apache.http.message.BasicHttpResponse;
|
|||
public class CachedHttpResponseGenerator {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param entry
|
||||
* {@link CacheEntry} to transform into an {@link HttpResponse}
|
||||
* @return {@link HttpResponse} that was constructed
|
||||
|
@ -75,16 +78,16 @@ public class CachedHttpResponseGenerator {
|
|||
if (transferEncodingIsPresent(response))
|
||||
return;
|
||||
|
||||
Header contentLength = response.getFirstHeader(HeaderConstants.CONTENT_LENGTH);
|
||||
Header contentLength = response.getFirstHeader(HTTP.CONTENT_LEN);
|
||||
if (contentLength == null) {
|
||||
contentLength = new BasicHeader(HeaderConstants.CONTENT_LENGTH, Long.toString(entity
|
||||
contentLength = new BasicHeader(HTTP.CONTENT_LEN, Long.toString(entity
|
||||
.getContentLength()));
|
||||
response.setHeader(contentLength);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean transferEncodingIsPresent(HttpResponse response) {
|
||||
Header hdr = response.getFirstHeader(HeaderConstants.TRANSFER_ENCODING);
|
||||
Header hdr = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
|
||||
return hdr != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ public class CachedResponseSuitabilityChecker {
|
|||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
* Determine if I can utilize a {@link CacheEntry} to respond to the given
|
||||
* {@link HttpRequest}
|
||||
*
|
||||
* @param host
|
||||
* {@link HttpHost}
|
||||
* @param request
|
||||
|
|
|
@ -296,7 +296,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
/**
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param context
|
||||
* @param context the http context
|
||||
* @param <T> The Return Type Identified by the generic type of the {@link ResponseHandler}
|
||||
* @return T The response type as handled by ResponseHandler
|
||||
* @throws IOException
|
||||
|
|
|
@ -39,11 +39,14 @@ import org.apache.http.impl.client.RequestWrapper;
|
|||
public class ConditionalRequestBuilder {
|
||||
|
||||
/**
|
||||
* When a {@link CacheEntry} 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.
|
||||
*
|
||||
* @param request
|
||||
* @param cacheEntry
|
||||
* @param request the original request from the caller
|
||||
* @param cacheEntry the entry that needs to be revalidated
|
||||
* @return the wrapped request
|
||||
* @throws ProtocolException
|
||||
* @throws ProtocolException when I am unable to build a new origin request.
|
||||
*/
|
||||
public HttpRequest buildConditionalRequest(HttpRequest request, CacheEntry cacheEntry)
|
||||
throws ProtocolException {
|
||||
|
|
|
@ -47,10 +47,11 @@ import org.apache.http.client.cache.HttpCacheEntrySerializer;
|
|||
public class DefaultCacheEntrySerializer implements HttpCacheEntrySerializer<CacheEntry> {
|
||||
|
||||
/**
|
||||
* Write a {@link CacheEntry} to an {@link OutputStream}.
|
||||
*
|
||||
* @param cacheEntry
|
||||
* @param os
|
||||
* @throws IOException
|
||||
* @param cacheEntry the entry to write
|
||||
* @param os the output stream to write to
|
||||
* @throws IOException if problems occur writing the entry
|
||||
*/
|
||||
public void writeTo(CacheEntry cacheEntry, OutputStream os) throws IOException {
|
||||
|
||||
|
@ -84,8 +85,9 @@ public class DefaultCacheEntrySerializer implements HttpCacheEntrySerializer<Cac
|
|||
}
|
||||
|
||||
/**
|
||||
* Read a {@link CacheEntry} from an {@link InputStream}
|
||||
*
|
||||
* @param is
|
||||
* @param is the input stream to read from
|
||||
* @return the cache entry
|
||||
* @throws IOException
|
||||
*/
|
||||
|
|
|
@ -53,9 +53,8 @@ public class HeaderConstants {
|
|||
public static final String ETAG = "ETag";
|
||||
public static final String EXPIRES = "Expires";
|
||||
public static final String AGE = "Age";
|
||||
public static final String CONTENT_LENGTH = "Content-Length";
|
||||
public static final String DATE = "Date";
|
||||
public static final String VARY = "Vary";
|
||||
public static final String ALLOW = "Allow";
|
||||
|
||||
public static final String CACHE_CONTROL = "Cache-Control";
|
||||
public static final String CACHE_CONTROL_NO_STORE = "no-store";
|
||||
|
@ -64,10 +63,10 @@ public class HeaderConstants {
|
|||
public static final String CACHE_CONTROL_MAX_STALE = "max-stale";
|
||||
public static final String CACHE_CONTROL_MIN_FRESH = "min-fresh";
|
||||
|
||||
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
|
||||
public static final String WARNING = "Warning";
|
||||
public static final String EXPECT = "Expect";
|
||||
public static final String RANGE = "Range";
|
||||
public static final String CONTENT_RANGE = "Content-Range";
|
||||
public static final String WWW_AUTHENTICATE = "WWW-Authenticate";
|
||||
public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate";
|
||||
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.apache.http.impl.client.RequestWrapper;
|
|||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
|
@ -51,8 +52,10 @@ import org.apache.http.message.BasicStatusLine;
|
|||
public class RequestProtocolCompliance {
|
||||
|
||||
/**
|
||||
* Test to see if the {@link HttpRequest} is HTTP1.1 compliant or not
|
||||
* and if not, we can not continue.
|
||||
*
|
||||
* @param request
|
||||
* @param request the HttpRequest Object
|
||||
* @return list of {@link RequestProtocolError}
|
||||
*/
|
||||
public List<RequestProtocolError> requestIsFatallyNonCompliant(HttpRequest request) {
|
||||
|
@ -77,10 +80,12 @@ public class RequestProtocolCompliance {
|
|||
}
|
||||
|
||||
/**
|
||||
* If the {@link HttpRequest} is non-compliant but 'fixable' we go ahead and
|
||||
* fix the request here. Returning the updated one.
|
||||
*
|
||||
* @param request
|
||||
* @param request the request to check for compliance
|
||||
* @return the updated request
|
||||
* @throws ProtocolException
|
||||
* @throws ProtocolException when we have trouble making the request compliant
|
||||
*/
|
||||
public HttpRequest makeRequestCompliant(HttpRequest request) throws ProtocolException {
|
||||
if (requestMustNotHaveEntity(request)) {
|
||||
|
@ -137,7 +142,7 @@ public class RequestProtocolCompliance {
|
|||
|
||||
private void addContentTypeHeaderIfMissing(HttpEntityEnclosingRequest request) {
|
||||
if (request.getEntity().getContentType() == null) {
|
||||
((AbstractHttpEntity) request.getEntity()).setContentType("application/octet-stream");
|
||||
((AbstractHttpEntity) request.getEntity()).setContentType(HTTP.OCTET_STREAM_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,12 +163,12 @@ public class RequestProtocolCompliance {
|
|||
private void remove100ContinueHeaderIfExists(HttpRequest request) {
|
||||
boolean hasHeader = false;
|
||||
|
||||
Header[] expectHeaders = request.getHeaders(HeaderConstants.EXPECT);
|
||||
Header[] expectHeaders = request.getHeaders(HTTP.EXPECT_DIRECTIVE);
|
||||
List<HeaderElement> expectElementsThatAreNot100Continue = new ArrayList<HeaderElement>();
|
||||
|
||||
for (Header h : expectHeaders) {
|
||||
for (HeaderElement elt : h.getElements()) {
|
||||
if (!("100-continue".equalsIgnoreCase(elt.getName()))) {
|
||||
if (!(HTTP.EXPECT_CONTINUE.equalsIgnoreCase(elt.getName()))) {
|
||||
expectElementsThatAreNot100Continue.add(elt);
|
||||
} else {
|
||||
hasHeader = true;
|
||||
|
@ -173,7 +178,7 @@ public class RequestProtocolCompliance {
|
|||
if (hasHeader) {
|
||||
request.removeHeader(h);
|
||||
for (HeaderElement elt : expectElementsThatAreNot100Continue) {
|
||||
BasicHeader newHeader = new BasicHeader(HeaderConstants.EXPECT, elt.getName());
|
||||
BasicHeader newHeader = new BasicHeader(HTTP.EXPECT_DIRECTIVE, elt.getName());
|
||||
request.addHeader(newHeader);
|
||||
}
|
||||
return;
|
||||
|
@ -186,16 +191,16 @@ public class RequestProtocolCompliance {
|
|||
private void add100ContinueHeaderIfMissing(HttpRequest request) {
|
||||
boolean hasHeader = false;
|
||||
|
||||
for (Header h : request.getHeaders(HeaderConstants.EXPECT)) {
|
||||
for (Header h : request.getHeaders(HTTP.EXPECT_DIRECTIVE)) {
|
||||
for (HeaderElement elt : h.getElements()) {
|
||||
if ("100-continue".equalsIgnoreCase(elt.getName())) {
|
||||
if (HTTP.EXPECT_CONTINUE.equalsIgnoreCase(elt.getName())) {
|
||||
hasHeader = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasHeader) {
|
||||
request.addHeader(HeaderConstants.EXPECT, "100-continue");
|
||||
request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,24 +237,31 @@ public class RequestProtocolCompliance {
|
|||
return request.getProtocolVersion().compareToVersion(CachingHttpClient.HTTP_1_1) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract error information about the {@link HttpRequest} telling the 'caller'
|
||||
* that a problem occured.
|
||||
*
|
||||
* @param errorCheck What type of error should I get
|
||||
* @return The {@link HttpResponse} that is the error generated
|
||||
*/
|
||||
public HttpResponse getErrorForRequest(RequestProtocolError errorCheck) {
|
||||
switch (errorCheck) {
|
||||
case BODY_BUT_NO_LENGTH_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
HttpStatus.SC_LENGTH_REQUIRED, ""));
|
||||
case BODY_BUT_NO_LENGTH_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
HttpStatus.SC_LENGTH_REQUIRED, ""));
|
||||
|
||||
case WEAK_ETAG_AND_RANGE_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
HttpStatus.SC_BAD_REQUEST, "Weak eTag not compatible with byte range"));
|
||||
case WEAK_ETAG_AND_RANGE_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
HttpStatus.SC_BAD_REQUEST, "Weak eTag not compatible with byte range"));
|
||||
|
||||
case WEAK_ETAG_ON_PUTDELETE_METHOD_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
HttpStatus.SC_BAD_REQUEST,
|
||||
"Weak eTag not compatible with PUT or DELETE requests"));
|
||||
case WEAK_ETAG_ON_PUTDELETE_METHOD_ERROR:
|
||||
return new BasicHttpResponse(new BasicStatusLine(CachingHttpClient.HTTP_1_1,
|
||||
HttpStatus.SC_BAD_REQUEST,
|
||||
"Weak eTag not compatible with PUT or DELETE requests"));
|
||||
|
||||
default:
|
||||
throw new IllegalStateException(
|
||||
"The request was compliant, therefore no error can be generated for it.");
|
||||
default:
|
||||
throw new IllegalStateException(
|
||||
"The request was compliant, therefore no error can be generated for it.");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -311,7 +323,7 @@ public class RequestProtocolCompliance {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (request.getFirstHeader(HeaderConstants.CONTENT_LENGTH) != null
|
||||
if (request.getFirstHeader(HTTP.CONTENT_LEN) != null
|
||||
&& ((HttpEntityEnclosingRequest) request).getEntity() != null)
|
||||
return null;
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.apache.http.HttpStatus;
|
|||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.impl.cookie.DateParseException;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* Determines if an HttpResponse can be cached.
|
||||
|
@ -49,8 +50,10 @@ public class ResponseCachingPolicy {
|
|||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
* Define a cache policy that limits the size of things that should be stored
|
||||
* in the cache to a maximum of {@link HttpResponse} bytes in size.
|
||||
*
|
||||
* @param maxObjectSizeBytes
|
||||
* @param maxObjectSizeBytes the size to limit items into the cache
|
||||
*/
|
||||
public ResponseCachingPolicy(int maxObjectSizeBytes) {
|
||||
this.maxObjectSizeBytes = maxObjectSizeBytes;
|
||||
|
@ -59,8 +62,8 @@ public class ResponseCachingPolicy {
|
|||
/**
|
||||
* Determines if an HttpResponse can be cached.
|
||||
*
|
||||
* @param httpMethod
|
||||
* @param response
|
||||
* @param httpMethod What type of request was this, a GET, PUT, other?
|
||||
* @param response The origin response
|
||||
* @return <code>true</code> if response is cacheable
|
||||
*/
|
||||
public boolean isResponseCacheable(String httpMethod, HttpResponse response) {
|
||||
|
@ -94,7 +97,7 @@ public class ResponseCachingPolicy {
|
|||
return cacheable;
|
||||
}
|
||||
|
||||
Header contentLength = response.getFirstHeader(HeaderConstants.CONTENT_LENGTH);
|
||||
Header contentLength = response.getFirstHeader(HTTP.CONTENT_LEN);
|
||||
if (contentLength != null) {
|
||||
int contentLengthValue = Integer.parseInt(contentLength.getValue());
|
||||
if (contentLengthValue > this.maxObjectSizeBytes)
|
||||
|
@ -111,7 +114,7 @@ public class ResponseCachingPolicy {
|
|||
if (expiresHeaders.length > 1)
|
||||
return false;
|
||||
|
||||
Header[] dateHeaders = response.getHeaders(HeaderConstants.DATE);
|
||||
Header[] dateHeaders = response.getHeaders(HTTP.DATE_HEADER);
|
||||
|
||||
if (dateHeaders.length != 1)
|
||||
return false;
|
||||
|
@ -168,9 +171,11 @@ public class ResponseCachingPolicy {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine if the {@link HttpResponse} gotten from the origin is a
|
||||
* cacheable response.
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param request the {@link HttpRequest} that generated an origin hit
|
||||
* @param response the {@link HttpResponse} from the origin
|
||||
* @return <code>true</code> if response is cacheable
|
||||
*/
|
||||
public boolean isResponseCacheable(HttpRequest request, HttpResponse response) {
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.http.annotation.Immutable;
|
|||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.impl.client.RequestWrapper;
|
||||
import org.apache.http.impl.cookie.DateUtils;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
|
@ -45,10 +46,13 @@ import org.apache.http.impl.cookie.DateUtils;
|
|||
public class ResponseProtocolCompliance {
|
||||
|
||||
/**
|
||||
* When we get a response from a down stream server (Origin Server)
|
||||
* we attempt to see if it is HTTP 1.1 Compliant and if not, attempt to
|
||||
* make it so.
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @throws ClientProtocolException
|
||||
* @param request The {@link HttpRequest} that generated an origin hit and response
|
||||
* @param response The {@link HttpResponse} from the origin server
|
||||
* @throws ClientProtocolException when we are unable to 'convert' the response to a compliant one
|
||||
*/
|
||||
public void ensureProtocolCompliance(HttpRequest request, HttpResponse response)
|
||||
throws ClientProtocolException {
|
||||
|
@ -78,7 +82,7 @@ public class ResponseProtocolCompliance {
|
|||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
|
||||
return;
|
||||
|
||||
if (response.getFirstHeader("Proxy-Authenticate") == null)
|
||||
if (response.getFirstHeader(HeaderConstants.PROXY_AUTHENTICATE) == null)
|
||||
throw new ClientProtocolException(
|
||||
"407 Response did not contain a Proxy-Authentication header");
|
||||
}
|
||||
|
@ -88,7 +92,7 @@ public class ResponseProtocolCompliance {
|
|||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_METHOD_NOT_ALLOWED)
|
||||
return;
|
||||
|
||||
if (response.getFirstHeader("Allow") == null)
|
||||
if (response.getFirstHeader(HeaderConstants.ALLOW) == null)
|
||||
throw new ClientProtocolException("405 Response did not contain an Allow header.");
|
||||
}
|
||||
|
||||
|
@ -97,15 +101,15 @@ public class ResponseProtocolCompliance {
|
|||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_UNAUTHORIZED)
|
||||
return;
|
||||
|
||||
if (response.getFirstHeader("WWW-Authenticate") == null) {
|
||||
if (response.getFirstHeader(HeaderConstants.WWW_AUTHENTICATE) == null) {
|
||||
throw new ClientProtocolException(
|
||||
"401 Response did not contain required WWW-Authenticate challenge header");
|
||||
}
|
||||
}
|
||||
|
||||
private void ensure206ContainsDateHeader(HttpResponse response) {
|
||||
if (response.getFirstHeader(HeaderConstants.DATE) == null) {
|
||||
response.addHeader(HeaderConstants.DATE, DateUtils.formatDate(new Date()));
|
||||
if (response.getFirstHeader(HTTP.DATE_HEADER) == null) {
|
||||
response.addHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -132,8 +136,8 @@ public class ResponseProtocolCompliance {
|
|||
return;
|
||||
}
|
||||
|
||||
if (response.getFirstHeader(HeaderConstants.CONTENT_LENGTH) == null) {
|
||||
response.addHeader(HeaderConstants.CONTENT_LENGTH, "0");
|
||||
if (response.getFirstHeader(HTTP.CONTENT_LEN) == null) {
|
||||
response.addHeader(HTTP.CONTENT_LEN, "0");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +187,7 @@ public class ResponseProtocolCompliance {
|
|||
|
||||
private void removeResponseTransferEncoding(HttpResponse response) {
|
||||
response.removeHeaders("TE");
|
||||
response.removeHeaders(HeaderConstants.TRANSFER_ENCODING);
|
||||
response.removeHeaders(HTTP.TRANSFER_ENCODING);
|
||||
}
|
||||
|
||||
private boolean originalRequestDidNotExpectContinue(RequestWrapper request) {
|
||||
|
|
|
@ -53,9 +53,14 @@ public class SizeLimitedResponseReader {
|
|||
private boolean outputStreamConsumed;
|
||||
|
||||
/**
|
||||
* Create an {@link HttpResponse} that is limited in size, this allows for checking
|
||||
* the size of objects that will be stored in the cache.
|
||||
*
|
||||
* @param maxResponseSizeBytes
|
||||
* Maximum size that a response can be to be eligible for cache inclusion
|
||||
*
|
||||
* @param response
|
||||
* The {@link HttpResponse}
|
||||
*/
|
||||
public SizeLimitedResponseReader(int maxResponseSizeBytes, HttpResponse response) {
|
||||
this.maxResponseSizeBytes = maxResponseSizeBytes;
|
||||
|
|
|
@ -37,6 +37,7 @@ 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.protocol.HTTP;
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
|
@ -44,6 +45,14 @@ import org.apache.http.annotation.Immutable;
|
|||
@Immutable
|
||||
public class URIExtractor {
|
||||
|
||||
/**
|
||||
* For a given {@link HttpHost} and {@link HttpRequest} get a URI from the
|
||||
* pair that I can use as an identifier KEY into my HttpCache
|
||||
*
|
||||
* @param host The host for this request
|
||||
* @param req the {@link HttpRequest}
|
||||
* @return String the extracted URI
|
||||
*/
|
||||
public String getURI(HttpHost host, HttpRequest req) {
|
||||
return String.format("%s%s", host.toString(), req.getRequestLine().getUri());
|
||||
}
|
||||
|
@ -65,6 +74,16 @@ public class URIExtractor {
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given {@link HttpHost} and {@link HttpRequest} if the request has a
|
||||
* VARY header - I need to get an additional URI from the pair of host and
|
||||
* request so that I can also store the variant into my HttpCache.
|
||||
*
|
||||
* @param host The host for this request
|
||||
* @param req the {@link HttpRequest}
|
||||
* @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) {
|
||||
Header[] varyHdrs = entry.getHeaders(HeaderConstants.VARY);
|
||||
if (varyHdrs == null || varyHdrs.length == 0) {
|
||||
|
@ -86,10 +105,10 @@ public class URIExtractor {
|
|||
if (!first) {
|
||||
buf.append("&");
|
||||
}
|
||||
buf.append(URLEncoder.encode(headerName, "UTF-8"));
|
||||
buf.append(URLEncoder.encode(headerName, HTTP.UTF_8));
|
||||
buf.append("=");
|
||||
buf.append(URLEncoder.encode(getFullHeaderValue(req.getHeaders(headerName)),
|
||||
"UTF-8"));
|
||||
HTTP.UTF_8));
|
||||
first = false;
|
||||
}
|
||||
buf.append("}");
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.http.HttpVersion;
|
|||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.cache.HttpCacheEntrySerializer;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -71,9 +72,10 @@ public class TestDefaultCacheEntrySerializer {
|
|||
}
|
||||
ProtocolVersion version = new HttpVersion(1, 1);
|
||||
String body = "Lorem ipsum dolor sit amet";
|
||||
BasicHttpResponse response = new BasicHttpResponse(version, 200, "OK");
|
||||
|
||||
CacheEntry cacheEntry = new CacheEntry(new Date(), new Date(), version, headers,
|
||||
new CacheEntity(body.getBytes("US-ASCII"), null, null), 200, "OK");
|
||||
new CacheEntity(body.getBytes("US-ASCII"), response), 200, "OK");
|
||||
|
||||
return cacheEntry;
|
||||
|
||||
|
|
Loading…
Reference in New Issue