Do not set current time as 'Last Modified' when "not found" avatar is used

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.

1 Like

Cool, this is now fixed per:

https://github.com/discourse/discourse/commit/b3aab1770fc8ee994586296c8367b2cb32c6ec89

3 Likes