Requests not being made from android app, with max-age set

1k Views Asked by At

I have an api that returns an object as the response, and an etag and max age as headers. The response looks like this:

HEADERS:

  'x-frame-options': 'SAMEORIGIN',
  'x-xss-protection': '1; mode=block',
  'x-content-type-options': 'nosniff',
  'x-download-options': 'noopen',
  'strict-transport-security': 'max-age=15778476000; includeSubDomains',
  'access-control-allow-origin': '*',
  etag: 'c69148a0489a95058e729bde7fd4bf32bf2077b1cba8d4fcf0c2da6e696fa33e',
  'cache-control': 'private,max-age=43200' 

BODY:

{
id: 1985,
url: "https://example.com",
...
}

The desired scenario is that an android application makes the request to ask for this data. The Api returns the data, along with an max age of 43200 secs.

If a request is made before 43200 secs pass, the application has the data from the last response cached. The application makes the request nevertheless, the back-end service compiles the response data, uses the request's etag to decide whether the response data has changed. If the data has changed, it returns a 200 http status and the data. Otherwise it returns a 403 status and no data.

The application receives the response. It uses fast networking to handle caching (says my android teammate). If a 200 status code was returned, the data are updated. Otherwise the application keeps the old data.

If a request is made after 43200 secs have passed, the application no longer has the cached response or it's etag. The request is made, the data are considered as 'new' even if nothing has changed in the data, the status code 200 is returned along with max-age header as above.

What actually happens:

For some reason, after the first request is processed and the application receives the data, no request is made until 43200 secs have passed. The android developer says they see that the request is made and 0 bytes are returned, but when I monitor the requests in the server I don't see any made towards this API.

This doesn't make sense, since max-age does not imply that no requests are made. It simply instructs the application to keep the data in the cache for the duration.

Am I missing the idea of how cache, etags and max-age work?

Back-end is built in node js, and uses express for routing.

1

There are 1 best solutions below

0
On

You've only set the max-age and private directives in the Cache-Control header. The actual behaviour you have described is the correct behaviour since max-age directive has no bearing on forcing the cache to validate responses each time a request is made. For that, you have to add the no-cache directive as well to the Cache-Control header.

The no-cache directives tells the cache to always validate the stored response with the origin server before serving it (i.e., the desired behaviour you have described). Upon revalidation, the stored response will be valid for another 43200 secs (max-age). Without the no-cache directive, the HTTP client is free to make use of cached responses. Which I guess is why your friend said the request was made, but 0 bytes were returned (browsers also show 0 bytes for responses served from the cache). And which is also why you didn't observe any incoming requests to the server.

Have a look at this article from Google for a good overview on HTTP caching: https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching

If you need in-depth detail on how responses are constructed from caches, have a look at the RFC7234 spec: https://www.rfc-editor.org/rfc/rfc7234#section-4