Index: pom.xml
===================================================================
--- pom.xml (revision 987312)
+++ pom.xml (working copy)
@@ -47,7 +47,17 @@
repo
-
+
+
+ spy
+ Spy Repository
+ default
+ http://bleu.west.spy.net/~dustin/m2repo/
+
+ false
+
+
+
org.apache.httpcomponents
@@ -62,6 +72,11 @@
compile
+ spy
+ memcached
+ 2.5
+
+
junit
junit
${junit.version}
@@ -93,6 +108,11 @@
compile
true
+
+ org.codehaus.jettison
+ jettison
+ 1.2
+
Index: src/main/java/org/apache/http/client/cache/HttpCache.java
===================================================================
--- src/main/java/org/apache/http/client/cache/HttpCache.java (revision 987312)
+++ src/main/java/org/apache/http/client/cache/HttpCache.java (working copy)
@@ -39,22 +39,22 @@
public interface HttpCache {
void flushCacheEntriesFor(HttpHost host, HttpRequest request)
- throws IOException;
+ throws IOException, HttpCacheOperationException;
void flushInvalidatedCacheEntriesFor(HttpHost host, HttpRequest request)
- throws IOException;
+ throws IOException, HttpCacheOperationException;
HttpCacheEntry getCacheEntry(HttpHost host, HttpRequest request)
- throws IOException;
+ throws IOException, HttpCacheOperationException;
HttpResponse cacheAndReturnResponse(
HttpHost host, HttpRequest request, HttpResponse originResponse,
Date requestSent, Date responseReceived)
- throws IOException;
+ throws IOException, HttpCacheOperationException;
HttpResponse updateCacheEntry(
HttpHost target, HttpRequest request, HttpCacheEntry stale, HttpResponse originResponse,
Date requestSent, Date responseReceived)
- throws IOException;
+ throws IOException, HttpCacheOperationException;
}
Index: src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java
===================================================================
--- src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java (revision 0)
+++ src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java (revision 0)
@@ -0,0 +1,11 @@
+package org.apache.http.client.cache;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public interface HttpCacheEntrySerializer {
+ public void writeTo(HttpCacheEntry entry, OutputStream os) throws IOException;
+
+ public HttpCacheEntry readFrom(InputStream is) throws IOException;
+}
Index: src/main/java/org/apache/http/client/cache/HttpCacheOperationException.java
===================================================================
--- src/main/java/org/apache/http/client/cache/HttpCacheOperationException.java (revision 0)
+++ src/main/java/org/apache/http/client/cache/HttpCacheOperationException.java (revision 0)
@@ -0,0 +1,30 @@
+package org.apache.http.client.cache;
+
+
+/**
+ * Exception to be thrown when an {@link HttpCacheStorage} encounters an error performing
+ * an caching operation.
+ *
+ * @since 4.1
+ */
+public class HttpCacheOperationException extends Exception {
+
+ private static final long serialVersionUID = 823573584868632876L;
+
+ public HttpCacheOperationException() {
+ super();
+ }
+
+ public HttpCacheOperationException(String message) {
+ super(message);
+ }
+
+ public HttpCacheOperationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public HttpCacheOperationException(Throwable cause) {
+ super(cause);
+ }
+
+}
\ No newline at end of file
Index: src/main/java/org/apache/http/client/cache/HttpCacheStorage.java
===================================================================
--- src/main/java/org/apache/http/client/cache/HttpCacheStorage.java (revision 987312)
+++ src/main/java/org/apache/http/client/cache/HttpCacheStorage.java (working copy)
@@ -33,13 +33,13 @@
*/
public interface HttpCacheStorage {
- void putEntry(String key, HttpCacheEntry entry) throws IOException;
+ void putEntry(String key, HttpCacheEntry entry) throws IOException, HttpCacheOperationException;
- HttpCacheEntry getEntry(String key) throws IOException;
+ HttpCacheEntry getEntry(String key) throws IOException, HttpCacheOperationException;
- void removeEntry(String key) throws IOException;
+ void removeEntry(String key) throws IOException, HttpCacheOperationException;
void updateEntry(
- String key, HttpCacheUpdateCallback callback) throws IOException;
+ String key, HttpCacheUpdateCallback callback) throws IOException, HttpCacheOperationException;
}
Index: src/main/java/org/apache/http/impl/client/cache/BasicHttpCache.java
===================================================================
--- src/main/java/org/apache/http/impl/client/cache/BasicHttpCache.java (revision 987312)
+++ src/main/java/org/apache/http/impl/client/cache/BasicHttpCache.java (working copy)
@@ -13,6 +13,7 @@
import org.apache.http.HttpVersion;
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.HttpCacheStorage;
import org.apache.http.client.cache.HttpCacheUpdateCallback;
import org.apache.http.client.cache.Resource;
@@ -49,13 +50,13 @@
}
public void flushCacheEntriesFor(HttpHost host, HttpRequest request)
- throws IOException {
+ throws IOException, HttpCacheOperationException {
String uri = uriExtractor.getURI(host, request);
storage.removeEntry(uri);
}
void storeInCache(
- HttpHost target, HttpRequest request, HttpCacheEntry entry) throws IOException {
+ HttpHost target, HttpRequest request, HttpCacheEntry entry) throws IOException, HttpCacheOperationException {
if (entry.hasVariants()) {
storeVariantEntry(target, request, entry);
} else {
@@ -64,7 +65,7 @@
}
void storeNonVariantEntry(
- HttpHost target, HttpRequest req, HttpCacheEntry entry) throws IOException {
+ HttpHost target, HttpRequest req, HttpCacheEntry entry) throws IOException, HttpCacheOperationException {
String uri = uriExtractor.getURI(target, req);
storage.putEntry(uri, entry);
}
@@ -72,7 +73,7 @@
void storeVariantEntry(
final HttpHost target,
final HttpRequest req,
- final HttpCacheEntry entry) throws IOException {
+ final HttpCacheEntry entry) throws IOException, HttpCacheOperationException {
final String parentURI = uriExtractor.getURI(target, req);
final String variantURI = uriExtractor.getVariantURI(target, req, entry);
storage.putEntry(variantURI, entry);
@@ -144,7 +145,7 @@
public HttpResponse updateCacheEntry(HttpHost target, HttpRequest request,
HttpCacheEntry stale, HttpResponse originResponse,
- Date requestSent, Date responseReceived) throws IOException {
+ Date requestSent, Date responseReceived) throws IOException, HttpCacheOperationException {
HttpCacheEntry updatedEntry = cacheEntryUpdater.updateCacheEntry(
request.getRequestLine().getUri(),
stale,
@@ -157,7 +158,7 @@
public HttpResponse cacheAndReturnResponse(HttpHost host, HttpRequest request,
HttpResponse originResponse, Date requestSent, Date responseReceived)
- throws IOException {
+ throws IOException, HttpCacheOperationException {
SizeLimitedResponseReader responseReader = getResponseReader(request, originResponse);
responseReader.readResponse();
@@ -187,7 +188,7 @@
resourceFactory, maxObjectSizeBytes, request, backEndResponse);
}
- public HttpCacheEntry getCacheEntry(HttpHost host, HttpRequest request) throws IOException {
+ public HttpCacheEntry getCacheEntry(HttpHost host, HttpRequest request) throws IOException, HttpCacheOperationException {
HttpCacheEntry root = storage.getEntry(uriExtractor.getURI(host, request));
if (root == null) return null;
if (!root.hasVariants()) return root;
@@ -196,7 +197,7 @@
}
public void flushInvalidatedCacheEntriesFor(HttpHost host,
- HttpRequest request) throws IOException {
+ HttpRequest request) throws IOException, HttpCacheOperationException {
cacheInvalidator.flushInvalidatedCacheEntries(host, request);
}
Index: src/main/java/org/apache/http/impl/client/cache/CacheInvalidator.java
===================================================================
--- src/main/java/org/apache/http/impl/client/cache/CacheInvalidator.java (revision 987312)
+++ src/main/java/org/apache/http/impl/client/cache/CacheInvalidator.java (working copy)
@@ -40,6 +40,7 @@
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.HttpCacheStorage;
/**
@@ -76,8 +77,9 @@
*
* @param host The backend host we are talking to
* @param req The HttpRequest to that host
+ * @throws HttpCacheOperationException
*/
- public void flushInvalidatedCacheEntries(HttpHost host, HttpRequest req) throws IOException {
+ public void flushInvalidatedCacheEntries(HttpHost host, HttpRequest req) throws IOException, HttpCacheOperationException {
if (requestShouldNotBeCached(req)) {
log.debug("Request should not be cached");
@@ -114,13 +116,13 @@
}
}
- protected void flushUriIfSameHost(URL requestURL, URL targetURL) throws IOException {
+ protected void flushUriIfSameHost(URL requestURL, URL targetURL) throws IOException, HttpCacheOperationException {
if (targetURL.getAuthority().equalsIgnoreCase(requestURL.getAuthority())) {
storage.removeEntry(targetURL.toString());
}
}
- protected void flushRelativeUriFromSameHost(URL reqURL, String relUri) throws IOException {
+ protected void flushRelativeUriFromSameHost(URL reqURL, String relUri) throws IOException, HttpCacheOperationException {
URL relURL;
try {
relURL = new URL(reqURL,relUri);
@@ -131,7 +133,7 @@
flushUriIfSameHost(reqURL, relURL);
}
- protected boolean flushAbsoluteUriFromSameHost(URL reqURL, String uri) throws IOException {
+ protected boolean flushAbsoluteUriFromSameHost(URL reqURL, String uri) throws IOException, HttpCacheOperationException {
URL absURL;
try {
absURL = new URL(uri);
Index: src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
===================================================================
--- src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java (revision 987312)
+++ src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java (working copy)
@@ -48,6 +48,7 @@
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.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
@@ -368,13 +369,29 @@
throw new ClientProtocolException(e);
}
- responseCache.flushInvalidatedCacheEntriesFor(target, request);
+ try {
+ responseCache.flushInvalidatedCacheEntriesFor(target, request);
+ } catch (HttpCacheOperationException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
if (!cacheableRequestPolicy.isServableFromCache(request)) {
- return callBackend(target, request, context);
+ try {
+ return callBackend(target, request, context);
+ } catch (HttpCacheOperationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
- HttpCacheEntry entry = responseCache.getCacheEntry(target, request);
+ HttpCacheEntry entry = null;
+ try {
+ entry = responseCache.getCacheEntry(target, request);
+ } catch (HttpCacheOperationException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
if (entry == null) {
cacheMisses.getAndIncrement();
if (log.isDebugEnabled()) {
@@ -382,7 +399,12 @@
log.debug("Cache miss [host: " + target + "; uri: " + rl.getUri() + "]");
}
- return callBackend(target, request, context);
+ try {
+ return callBackend(target, request, context);
+ } catch (HttpCacheOperationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
if (log.isDebugEnabled()) {
@@ -413,9 +435,18 @@
}
} catch (ProtocolException e) {
throw new ClientProtocolException(e);
- }
+ } catch (HttpCacheOperationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
- return callBackend(target, request, context);
+ try {
+ return callBackend(target, request, context);
+ } catch (HttpCacheOperationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
}
public boolean supportsRangeAndContentRangeHeaders() {
@@ -446,7 +477,7 @@
}
HttpResponse callBackend(HttpHost target, HttpRequest request, HttpContext context)
- throws IOException {
+ throws IOException, HttpCacheOperationException {
Date requestDate = getCurrentDate();
@@ -461,7 +492,7 @@
HttpHost target,
HttpRequest request,
HttpContext context,
- HttpCacheEntry cacheEntry) throws IOException, ProtocolException {
+ HttpCacheEntry cacheEntry) throws IOException, ProtocolException, HttpCacheOperationException {
HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(request, cacheEntry);
Date requestDate = getCurrentDate();
@@ -485,7 +516,7 @@
HttpRequest request,
Date requestDate,
Date responseDate,
- HttpResponse backendResponse) throws IOException {
+ HttpResponse backendResponse) throws IOException, HttpCacheOperationException {
log.debug("Handling Backend response");
responseCompliance.ensureProtocolCompliance(request, backendResponse);
Index: src/main/java/org/apache/http/impl/client/cache/DefaultHttpCacheEntrySerializer.java
===================================================================
--- src/main/java/org/apache/http/impl/client/cache/DefaultHttpCacheEntrySerializer.java (revision 0)
+++ src/main/java/org/apache/http/impl/client/cache/DefaultHttpCacheEntrySerializer.java (revision 0)
@@ -0,0 +1,119 @@
+package org.apache.http.impl.client.cache;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.Set;
+
+import org.apache.http.Header;
+import org.apache.http.NameValuePair;
+import org.apache.http.ProtocolVersion;
+import org.apache.http.StatusLine;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.client.cache.HttpCacheEntry;
+import org.apache.http.client.cache.HttpCacheEntrySerializer;
+import org.apache.http.client.cache.Resource;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.message.BasicStatusLine;
+
+/**
+ * {@link HttpCacheEntrySerializer} implementation that uses the default (native)
+ * serialization.
+ *
+ * @see java.io.Serializable
+ *
+ * @since 4.1
+ */
+@Immutable
+public class DefaultHttpCacheEntrySerializer implements HttpCacheEntrySerializer {
+
+ /**
+ *
+ * @param cacheEntry
+ * @param os
+ * @throws IOException
+ */
+ public void writeTo(HttpCacheEntry cacheEntry, OutputStream os) throws IOException {
+
+ ObjectOutputStream oos = null;
+ try {
+ oos = new ObjectOutputStream(os);
+
+ oos.writeObject(cacheEntry.getRequestDate());
+ oos.writeObject(cacheEntry.getResponseDate());
+
+ // workaround to nonserializable BasicStatusLine object
+ // TODO: can change to directly serialize once new httpcore is released
+ oos.writeObject(cacheEntry.getStatusLine().getProtocolVersion());
+ oos.writeObject(cacheEntry.getStatusLine().getStatusCode());
+ oos.writeObject(cacheEntry.getStatusLine().getReasonPhrase());
+
+ // workaround to nonserializable BasicHeader object
+ // TODO: can change to directly serialize once new httpcore is released
+ Header[] headers = cacheEntry.getAllHeaders();
+ NameValuePair[] headerNvps = new NameValuePair[headers.length];
+ for(int i=0; i variants = (Set)ois.readObject();
+
+ return new HttpCacheEntry(requestDate, responseDate, statusLine, headers, resource, variants);
+ } catch (ClassNotFoundException cnfe) {
+ // CacheEntry should be known, it not we have a runtime issue
+ throw new RuntimeException(cnfe);
+ } finally {
+ if (ois != null) {
+ ois.close();
+ }
+ is.close();
+ }
+
+ }
+
+}
Index: src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedHttpCacheStorage.java
===================================================================
--- src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedHttpCacheStorage.java (revision 0)
+++ src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedHttpCacheStorage.java (revision 0)
@@ -0,0 +1,84 @@
+package org.apache.http.impl.client.cache.memcached;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+
+import net.spy.memcached.CASResponse;
+import net.spy.memcached.CASValue;
+import net.spy.memcached.MemcachedClient;
+import net.spy.memcached.MemcachedClientIF;
+
+import org.apache.http.client.cache.HttpCacheEntry;
+import org.apache.http.client.cache.HttpCacheEntrySerializer;
+import org.apache.http.client.cache.HttpCacheOperationException;
+import org.apache.http.client.cache.HttpCacheStorage;
+import org.apache.http.client.cache.HttpCacheUpdateCallback;
+import org.apache.http.impl.client.cache.DefaultHttpCacheEntrySerializer;
+
+public class MemcachedHttpCacheStorage implements HttpCacheStorage {
+
+ private MemcachedClientIF client;
+ private HttpCacheEntrySerializer serializer;
+
+ public MemcachedHttpCacheStorage(InetSocketAddress address) throws IOException {
+ this(new MemcachedClient(address));
+ }
+
+ public MemcachedHttpCacheStorage(MemcachedClientIF client) {
+ this.client = client;
+ this.serializer = new DefaultHttpCacheEntrySerializer();
+ }
+
+ public MemcachedHttpCacheStorage(MemcachedClientIF client,
+ HttpCacheEntrySerializer serializer) {
+ this.client = client;
+ this.serializer = serializer;
+ }
+
+ public void putEntry(String url, HttpCacheEntry entry) throws HttpCacheOperationException, IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ serializer.writeTo(entry, bos);
+ client.set(url, 0, bos.toByteArray());
+ }
+
+ public HttpCacheEntry getEntry(String url) throws HttpCacheOperationException,IOException {
+ byte[] data = (byte[]) client.get(url);
+ if (null == data)
+ return null;
+ InputStream bis = new ByteArrayInputStream(data);
+ return (HttpCacheEntry) serializer.readFrom(bis);
+ }
+
+ public void removeEntry(String url) throws HttpCacheOperationException,IOException {
+ client.delete(url);
+ }
+
+ public void updateEntry(String key, HttpCacheUpdateCallback callback)
+ throws HttpCacheOperationException, IOException {
+ CASValue