Skip to content

Commit

Permalink
Provide cached ETag and input stream in single call
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinsawicki committed Aug 8, 2012
1 parent 7ae5ac9 commit 0aa9197
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 54 deletions.
35 changes: 15 additions & 20 deletions lib/src/main/java/com/github/kevinsawicki/etag/CacheRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static java.net.HttpURLConnection.HTTP_NOT_MODIFIED;

import com.github.kevinsawicki.etag.EtagCache.CacheResponse;
import com.github.kevinsawicki.http.HttpRequest;

import java.io.IOException;
Expand Down Expand Up @@ -56,7 +57,7 @@ public static CacheRequest get(final URL url, final EtagCache cache)

private final EtagCache cache;

private InputStream stream;
private CacheResponse response;

private boolean etagAdded;

Expand Down Expand Up @@ -90,28 +91,22 @@ public CacheRequest(final URL url, final String method, final EtagCache cache)
this.cache = cache;
}

private void closeCacheStream() {
if (stream == null)
private void closeCacheResponse() {
if (response == null)
return;

try {
stream.close();
} catch (IOException ignored) {
// Ignored
} finally {
stream = null;
}
response.close();
response = null;
}

@Override
protected HttpRequest closeOutput() throws IOException {
// Only attempt to add an etag once
if (!etagAdded) {
etagAdded = true;
String etag = cache.getEtag(getConnection());
stream = cache.getStream(getConnection());
if (etag != null && stream != null)
ifNoneMatch(etag);
response = cache.get(getConnection());
if (response != null)
ifNoneMatch(response.eTag);
}

return super.closeOutput();
Expand All @@ -122,29 +117,29 @@ public int code() throws HttpRequestException {
final int code = super.code();

if (code != HTTP_NOT_MODIFIED)
closeCacheStream();
closeCacheResponse();
return code;
}

@Override
public HttpRequest disconnect() {
closeCacheStream();
closeCacheResponse();

return super.disconnect();
}

@Override
public InputStream stream() throws HttpRequestException {
if (notModified() && stream != null)
return stream;
if (notModified() && response != null)
return response.body;

if (ok()) {
InputStream streamWrapper = cache.putStream(getConnection());
final InputStream streamWrapper = cache.put(getConnection());
if (streamWrapper != null)
return streamWrapper;
}

closeCacheStream();
closeCacheResponse();

return super.stream();
}
Expand Down
66 changes: 40 additions & 26 deletions lib/src/main/java/com/github/kevinsawicki/etag/EtagCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.jakewharton.DiskLruCache.Editor;
import com.jakewharton.DiskLruCache.Snapshot;

import java.io.Closeable;
import java.io.File;
import java.io.FilterInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -71,6 +72,35 @@ public static EtagCache create(final File file, final long size) {
}
}

/**
* Get cached response
*/
public static class CacheResponse implements Closeable {

/**
* ETag of response
*/
public final String eTag;

/**
* Body of response
*/
public final InputStream body;

private final Snapshot snapshot;

CacheResponse(final String eTag, final InputStream body,
final Snapshot snapshot) {
this.eTag = eTag;
this.body = body;
this.snapshot = snapshot;
}

public void close() {
snapshot.close();
}
}

private static final int ETAG = 0;

private static final int BODY = 1;
Expand Down Expand Up @@ -219,12 +249,12 @@ public EtagCache(final File file, final long size) throws IOException {
}

/**
* Get cached etag for connection
* Get cached response for connection
*
* @param connection
* @return etag or null if not in cache or connection isn't cacheable
*/
public String getEtag(final URLConnection connection) {
public CacheResponse get(final URLConnection connection) {
final String key = getKey(connection);
if (key == null)
return null;
Expand All @@ -239,32 +269,16 @@ public String getEtag(final URLConnection connection) {
return null;

try {
return snapshot.getString(ETAG);
} catch (IOException e) {
return null;
} finally {
snapshot.close();
}
}

/**
* Get cached stream
*
* @param connection
* @return cached stream or null if not in cache or connection isn't cacheable
*/
public InputStream getStream(final URLConnection connection) {
final String key = getKey(connection);
if (key == null)
return null;

Snapshot snapshot;
try {
snapshot = cache.get(key);
final String etag = snapshot.getString(ETAG);
if (etag != null && etag.length() > 0) {
final InputStream body = snapshot.getInputStream(BODY);
if (body != null)
return new CacheResponse(etag, body, snapshot);
}
} catch (IOException e) {
return null;
}
return snapshot != null ? snapshot.getInputStream(BODY) : null;
return null;
}

/**
Expand All @@ -273,7 +287,7 @@ public InputStream getStream(final URLConnection connection) {
* @param connection
* @return input stream that will be cached, null if cannot be cached
*/
public InputStream putStream(final URLConnection connection) {
public InputStream put(final URLConnection connection) {
final String key = getKey(connection);
if (key == null)
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,13 @@ public void handle(Request request, HttpServletResponse response) {
EtagCache cache = EtagCache.create(file, ONE_MB);
assertNotNull(cache);
CacheRequest request = CacheRequest.get(url, cache);
assertNull(cache.getEtag(request.getConnection()));
assertNull(cache.getStream(request.getConnection()));
assertNull(cache.get(request.getConnection()));
assertTrue(request.ok());
assertEquals("hello", request.body());
request = CacheRequest.get(url, cache);
assertTrue(request.notModified());
assertEquals("hello", request.body());
assertNotNull(cache.getEtag(request.getConnection()));
assertNotNull(cache.getStream(request.getConnection()));
assertNotNull(cache.get(request.getConnection()));
}

/**
Expand All @@ -98,14 +96,12 @@ public void handle(Request request, HttpServletResponse response) {
EtagCache cache = EtagCache.create(file, ONE_MB);
assertNotNull(cache);
CacheRequest request = CacheRequest.get(url, cache);
assertNull(cache.getEtag(request.getConnection()));
assertNull(cache.getStream(request.getConnection()));
assertNull(cache.get(request.getConnection()));
assertTrue(request.ok());
assertEquals("hello", request.body());
request = CacheRequest.get(url, cache);
assertTrue(request.ok());
assertEquals("hello", request.body());
assertNotNull(cache.getEtag(request.getConnection()));
assertNotNull(cache.getStream(request.getConnection()));
assertNotNull(cache.get(request.getConnection()));
}
}

0 comments on commit 0aa9197

Please sign in to comment.