Solutions to support Accept header

I have an origin server that uses Accept header to return the best possible supported image format. Specifically it will return WebP in the case that the Accept header value includes this format or JPEG in other case.

I have seen that Cloudflare doesn’t support Vary headers in the response and does not differ cache key when the Accept header is different in the request.

This can cause a user with a browser supporting WebP (.i.e. Chrome) doing a request and the response being cached (a WebP image), later a user doing the same request with a browser not supporting WebP (.i.e. Safari) and receiving the WebP which will not be rendered in that browser.

What options do we have to support Accept header with Cloudflare for this specific case? In the case that solutions are available what is the cheapest option for this?

More details:

  • I only need to do this when a specific query string is used in the URL so it’s not needed always.
  • Use Polish so it will generate the WebP for me is not a correct solution because I want to have total freedom in how the WebP is generated (quality, lossless, etc.).

Thanks.

The issue on this isn’t what a browser will and will not accept, it’s that servers are sending WebP images with a .jpg extension, and then Cloudflare caches it.

To me, this method is a cheat that only works at the edge. But clearly falls apart if there’s an upstream cache, like Cloudflare, or a CDN.

It sounds like your site uses this workaround; delivering WebP images with a JPG extension.

“Standard” Caching should mean that different query strings return different resources. Like example.com/pictures/file.jpg?image=jpg and example.com/pictures/file.jpg?image=webp should work.

This isn’t happening?

My origin server supports the following:

  • Return a WebP with https://example.com/pictures/file.jpeg?image=webp
  • Return a JPEG with https://example.com/pictures/file.jpeg?image=jpeg
  • Return the “best” supported format with https://example.com/pictures/file.jpeg?image=auto (and checking Accept header).

So yes, in some cases I’m returning a WebP image when the extension is jpeg.

Any idea in a possible solution to support this scenario with Cloudflare?

Thanks.

You can use Transform Rules to modify the URL, such as by appending a query parameter when there is an Accept header containing webp.

2 Likes

Ok, so it’s this. Now I’m just not clear where the problem lies. Cloudflare does send the Accept header to the server:

So we’re back to square 1. Cloudflare is caching the same file for the image=auto query string.

I see Michael has posted a suggestion. Hopefully that works.

I have tried with Transform Rules but I don’t see in the fields select any way to filter by headers.

Any idea on how to create such rule?

Dev Docs has more detail:
https://developers.cloudflare.com/firewall/cf-firewall-language/fields#field-http-request-headers

1 Like

I’m making some progress. Thank you very much for the help.

I’m stuck trying to specify the Query Rewrite (the condition is fine and working). What I want to do is replace query string image=auto to image=webp.

I guess it should be set with Dynamic (in Query section) but not sure how to define that replacement. Any idea?

I don’t know if this will work, but it didn’t throw an error when I saved it:
any(http.request.headers["content-type"][*] contains "webp")

It’s working for me but for "accept" instead of "content-type".

Apart from that If I set the Rewrite to Static I’m removing other possible query strings that are part of the URL and I don’t want to do that. That’s why I said that probably I need Dynamic but I have not found the way to concat a query string (it should be at the beginning) or replace the actual image param.

1 Like

I didn’t know there’d be more. In that case, you’d have to use Regex, which requires a Business or Enterprise plan.

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.