I'm trying to set up the cache for OkHttp, so it only requests to the server the first time I try to retrieve a response from the server until the expires header date, or cache-control header that comes from the server invalidates the response from the cache.
Currently, its caching the response, but not using it when requesting the resource again. May be this is not the way it was supposed to be used.
I'm setting up OkHttpClient with cache like this:
public static Cache createHttpClientCache(Context context) {
try {
File cacheDir = context.getDir("service_api_cache", Context.MODE_PRIVATE);
return new Cache(cacheDir, HTTP_CACHE_SIZE);
} catch (IOException e) {
Log.e(TAG, "Couldn't create http cache because of IO problem.", e);
return null;
}
}
This is used like this:
if(cache == null) {
cache = createHttpClientCache(context);
}
sClient.setCache(cache);
This is how I make one of the requests to the server with OkHttp that's actually failing to use the cache:
public static JSONObject getApi(Context context)
throws IOException, JSONException, InvalidCookie {
HttpCookie sessionCookie = getServerSession(context);
if(sessionCookie == null){
throw new InvalidCookie();
}
String cookieStr = sessionCookie.getName()+"="+sessionCookie.getValue();
Request request = new Request.Builder()
.url(sServiceRootUrl + "/api/"+API_VERSION)
.header("Accept", "application/json")
.header("Cookie", cookieStr)
.build();
Response response = sClient.newCall(request).execute();
if(response.code() == 200){
String charset = getResponseCharset(response);
if(charset == null){
charset = "utf-8";
}
String responseStr = new String(response.body().bytes(), charset);
response.body().close();
return new JSONObject(responseStr);
} else if(response.code() == 401){
throw new InvalidCookie();
} else {
return null;
}
}
If I get to the directory I specified to be the cache for OkHttp I can see the journal file and 4 other files that contains the responses for some of the requests. This request (the /api one I've just pasted the code) is stored on the cache directory so it was really cached, but the filename has a .tmp at the end, like if it wasn't properly saved to the final file, like other request I made.
This is how it looks like the headers of the server response for the request:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Expires: Sat, 09 Aug 2014 19:36:08 GMT
Cache-Control: max-age=86400, must-revalidate
Last-Modified: Sun, 04 Aug 2013 15:56:04 GMT
Content-Length: 281
Date: Fri, 08 Aug 2014 19:36:08 GMT
And this is how OkHttp stores it on the cache:
{HOST}/api/0.3
GET
0
HTTP/1.1 200 OK
9
Server: Apache-Coyote/1.1
Expires: Sat, 09 Aug 2014 19:36:08 GMT
Cache-Control: max-age=86400, must-revalidate
Last-Modified: Sun, 04 Aug 2013 15:56:04 GMT
Content-Length: 281
Date: Fri, 08 Aug 2014 19:36:08 GMT
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1407526495630
OkHttp-Received-Millis: 1407526495721
After OkHttp creates this file, it keeps requesting to the server the same resource. I can see those messages in Wireshark.
What am I doing wrong?
UPDATE:
This is now the server response after Jesse suggestion:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Expires: Thu, 14 Aug 2014 18:06:05 GMT
Last-Modified: Sun, 10 Aug 2014 12:37:06 GMT
Content-Length: 281
Date: Wed, 13 Aug 2014 18:06:05 GMT
UPDATE 2: Tried the code version and found out that it is quite probable there is a bug somewhere regarding the cache. This is what I've got from the Maven output:
Results :
Failed tests:
CacheTest.conditionalHitUpdatesCache:1653 expected:<[A]> but was:<[B]>
Tests in error:
CallTest.tearDown:86 » IO failed to delete file: C:\Users\Adrian\AppData\Local...
Tests run: 825, Failures: 1, Errors: 1, Skipped: 17
A more complete log can be seen here: https://gist.github.com/16BITBoy/344ea4c22b543f397f53