Skip to content

Instantly share code, notes, and snippets.

@darnmason
Created June 18, 2018 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darnmason/d16a6505195c864e295015edb62b8e4e to your computer and use it in GitHub Desktop.
Save darnmason/d16a6505195c864e295015edb62b8e4e to your computer and use it in GitHub Desktop.
Demonstration of caching issue where OkHttpClient doesn't check either the modified date or the Etag on subsequent requests, it just serves from the cache. Comment out the last-modified header and the test passes as the Etag is checked.
import junit.framework.Assert;
import org.junit.Rule;
import org.junit.Test;
import java.io.File;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
public class OkHttpTest {
private static final String LOCATION = "/android.json";
@Rule public final MockWebServer server = new MockWebServer();
@Test
public void test() throws Exception {
server.enqueue(new MockResponse()
.setResponseCode(200)
.addHeader("content-type: application/json")
.addHeader("date: Mon, 18 Jun 2018 09:53:22 GMT")
// Comment the following line to make the test pass
.addHeader("last-modified: Fri, 11 May 2018 01:07:42 GMT")
.addHeader("etag: \"ff1f3f00586dea6efc5b60c2b689c5b0\"")
.addHeader("accept-ranges: bytes")
.addHeader("server: AmazonS3")
.addHeader("age: 10878")
.addHeader("x-cache: Hit from cloudfront")
.addHeader("via: 1.1 x.cloudfront.net (CloudFront)")
.addHeader("x-amz-cf-id: x")
.setBody("{}"));
Request request = new Request.Builder()
.url(server.url(LOCATION))
.header("User-Agent", "Test Case")
.build();
File cacheDir = new File(System.getProperty("java.io.tmpdir"),
UUID.randomUUID()
.toString()
);
Cache cache = new Cache(cacheDir, 1024);
OkHttpClient client = new OkHttpClient().newBuilder()
.cache(cache)
.connectTimeout(60000,
TimeUnit.MILLISECONDS
)
.readTimeout(60000,
TimeUnit.MILLISECONDS
)
.build();
// Request once
Call call = client.newCall(request);
Response response = call.execute();
assertEquals("{}", response.body()
.string()
);
assertEquals(200, response.code());
assertNull(response.cacheResponse());
assertEquals(1, cache.networkCount());
RecordedRequest recordedRequest = server.takeRequest();
assertEquals(LOCATION, recordedRequest.getPath());
Assert.assertNull(recordedRequest.getHeader("If-None-Match"));
Assert.assertNull(recordedRequest.getHeader("If-Modified-Since"));
assertEquals(0, cache.hitCount());
server.enqueue(new MockResponse()
.setResponseCode(304)
.addHeader("date: Mon, 18 Jun 2018 09:53:22 GMT")
.addHeader("etag: \"ff1f3f00586dea6efc5b60c2b689c5b0\"")
.addHeader("server: AmazonS3")
.addHeader("age: 10878")
.addHeader("x-cache: Hit from cloudfront")
.addHeader("via: 1.1 x.cloudfront.net (CloudFront)")
.addHeader("x-amz-cf-id: x")
);
// Request twice
call = client.newCall(request);
response = call.execute();
assertEquals("{}", response.body()
.string()
);
assertEquals(200, response.code());
assertNotNull(response.cacheResponse());
assertEquals(2, server.getRequestCount());
recordedRequest = server.takeRequest();
assertEquals(LOCATION, recordedRequest.getPath());
Assert.assertEquals("\"ff1f3f00586dea6efc5b60c2b689c5b0\"", recordedRequest.getHeader("If-None-Match"));
assertEquals(1, cache.hitCount());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment