Cloudflare doesn't cache files without extension into the URL

Yesterday, while debugging some performance issues on one of my websites, I’ve discovered that Cloudflare didn’t cache some images even if they were of the cacheable types.

Checking the headers this was the result:

curl -svo /dev/null <url>/server/images/logo/28
Output
 < date: Sat, 01 Jun 2018 06:27:54 GMT
 < content-type: image/png
 < content-length: 17612
 < set-cookie: __cfduid=<omissis>; expires=Sun, 01-Jun-19 06:27:53 GMT; path=/; domain=<omissis>; HttpOnly; Secure
 < cache-control: max-age=21600
 < expires: Sat, 01 Jun 2018 12:27:54 GMT
 < content-disposition: inline; filename="logo28.png"
 < cache-control: public
 < expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
 < server: cloudflare
 < cf-ray: <omissis>

As you can see the "cf-cache-status" is missing, and this should happen when the file type is one of those that are not "not something they would ordinarily cache" see this article

The resource showed the proper headers and was set as public just like other website resources that were cached correctly by cloudflare. So I’ve tried enforcing a "Cache everything" page rule without any effect.

Then I spent again some time looking to find what was different into the headers without noticing anything new till, after a while, reading again this article, I noticed this phrase:

caches the following types of static content by extension

So I realized that the only difference between cached and uncached content was the presence of the file extension into the url! Even if the files are of the correct mime types and the header contains the file name with the extension.

So I made an experiment and changed the URL of the previous resource including the extension and the result was this:

curl -svo /dev/null <url>/server/images/logo/28.png
Output
 < HTTP/2 200
 < date: Sat, 01 Jun 2018 09:29:38 GMT
 < content-type: image/png
 < content-length: 17612
 < set-cookie: __cfduid=<omissis>; expires=Sun, 01-Jun-19 09:29:38 GMT; path=/; domain=<omissis>; HttpOnly; Secure
 < cache-control: public, max-age=28800
 < expires: Sat, 01 Jun 2018 17:29:38 GMT
 < content-disposition: inline; filename="logo28.png"
 < cf-cache-status: HIT
 < expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
 < server: cloudflare
 < cf-ray: <omissis>

The resource was now cacheable by Cloudflare, what was strange is that the page rules did not enforce the caching of the resource though.

My hypothesis is that the function that decides the cacheability first extracts the file extension from the url then does the actual evaluation, if the resource has not a file extension it just skips all the other phases no matter what page rule you put there.

This is not an issue only something I think it’s useful to be aware of, especially if you serve many "cacheable" content in a rest fashion.

And by the way I really think that Cloudflare offers a great service.

Bye

K.