Can workers override CF Cache ignoring Vary header?

@harris seems Cloudflare cache outlined at https://support.cloudflare.com/hc/en-us/articles/115003206852-Understanding-Origin-Cache-Control does not respect the Accept: Vary header. This can be problematic for CF free plan usage where nginx origin backend is conditionally serving webP images to browsers that support it

map $http_accept $webp_extension {
    default "";
    "~*webp" ".webp";
}

  location ~* ^/wp-content/uploads/(.+/)?(.+)\.(png|jpe?g)$ {
    expires 30d;
    add_header Vary "Accept";
    add_header Cache-Control "public, no-transform";
    try_files $uri$webp_extension $uri =404;
  }

But CF cache ignores Vary header so CF cache ends up serving webP images to browsers that do not support it.

So can CF workers workaround this ? Or only upgrading to CF Pro for Polish and webP is the way ?

1 Like

Perhaps something like: use a Bypass Cache page rule on the route in question, then use the Cache API to explicitly cache the different responses under different URLs.

1 Like

But the Bypass cache page rule wouldn’t exist on Cloudflare Free plans which is where the problem lies. For paid plans they’re have Polish/webP conversion so wouldn’t need a workaround.

I think for now until I find a solution, I’ll just disable nginx side webp detection if CF proxy is detected on the nginx origin site so my LEMP stack end users don’t end up with problems when they use CF free plan and have a high portion of Safari browser users where webP isn’t supported but Cloudflare cache ends up serving webP format images from cache to them still.

map $http_accept $webp_extension {
    default "";
    "~*webp" ".webp";
}

map $http_cf_connecting_ip $webp_extension {
    default "";  
}

I was able to create a “Cache Level: Bypass” page rule (I didn’t know the exact name before) on my free zone, and it worked.

2 Likes

cheers i was incorrectly thinking of cache bypass on cookie :slight_smile:

2 Likes

Can you tell exactly how to do that

Any solution you got?

My solution is to use a CDN with vary header

If it’s just for images needing served by vary header distinction from origin hosted images converted, then Cloudflare does support Vary header for images as outlined at Vary for Images: Serve the Correct Images to the Correct Browsers. Of course this is just for paid Cloudflare plans. So if you don’t need to host varying image formats from origin, then just paid plan Polish would do to serve image format conversions done on the fly at Cloudflare edge.

Or you can use Cloudflare Images Cloudflare Images Now Available to Everyone

If on free plan and need to serve varying image formats hosted on origin server via Cloudflare CDN, then easiest way is to serve them with varying extension names image.jpg, image.webp, image.avif and then use img srcset or picture HTML methods to vary the image format served. Or programmatically to do the same via custom Cloudflare worker which inspects the request Accept header for browser/client supported image formats.

Imagify plugin does that but it can’t be used in background images and sometimes theme don’t support. So I am using a traditional cdn

I would also like to know if this is possible.

Specifically, for Cloudflare Free or Cloudflare Partner customers:

Can we replace this method: (Vary for Images)

With this method: (Workers Set-Up for WebP and AVIF)

https://noise.getoto.net/2021/11/18/cloudflare-images-introduces-avif-blur-and-bundle-with-stream/

Thank you!