I’ve just discovered a weird interaction with Akamai’s CDN that may be down to the Last-Modified header… but that’s a guess.
This is a response from Akamai with the “default avatar” cached, it’s doing the right thing and passing along the remaining TTL on the cached item:
HTTP/1.1 200 OK
Last-Modified: Fri, 31 Aug 2018 03:59:15 GMT
Content-Type: image/png
Server: nginx
Content-Length: 2608
Cache-Control: public, max-age=61
Date: Fri, 31 Aug 2018 04:17:29 GMT
After the object expires and we request it from the CDN again it’s re-fetched from origin and now the origin has returned the correct avatar:
HTTP/1.1 200 OK
Last-Modified: Fri, 31 Aug 2018 03:30:06 GMT
Content-Type: image/png
Server: nginx
Content-Length: 2608
Cache-Control: public, max-age=31556670
Date: Fri, 31 Aug 2018 04:22:07 GMT
Note that now it’s got a max-age of “forever” and the Last-Modified of the file itself… but the Content-Length has not changed. The actual response from the origin directly looks like this:
HTTP/1.1 200 OK
Last-Modified: Fri, 31 Aug 2018 03:30:06 GMT
Content-Type: image/jpeg
Server: nginx
Content-Length: 1068
Cache-Control: max-age=31556952, public, immutable
Date: Fri, 31 Aug 2018 04:27:35 GMT
I suspect that because the Last-Modified went backwards in time Akamai got confused and cached the “old” content with the “new” max-age. This is a bug on Akamai’s end which I will address with them.
BUT I do not think we should send the current time as Last-Modified here as it doesn’t affect max-age:
max-age=<seconds>
Specifies the maximum amount of time a resource will be considered fresh. Contrary to Expires, > this directive is relative to the time of the request.
We should omit it entirely or set it to the epoch when we return the default avatar.