Cloudflare Workers lies about request Accept-Encoding

It seems that Cloudflare Workers doesn’t allow to access original “Accept-Encoding” request header and instead is always returning “gzip”:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  return new Response(request.headers.get('accept-encoding'))
}

curl https://test.sheerun.workers.dev
gzip

curl https://test.sheerun.workers.dev --compressed
gzip

curl https://test.sheerun.workers.dev -H ‘Accept-Encoding: foobar’
gzip

Could you explain why is this the case and how to avoid this?

2 Likes

Hi @sheerun, it looks like this is an artifact of our implementation. While Cloudflare supports brotli and gzip to eyeballs, we only support gzip between CF and origins (see https://support.cloudflare.com/hc/en-us/articles/200168086-Does-Cloudflare-compress-resources-). The Workers runtime lives on the origin side of this divide, so it’s not able to perform content negotiation directly with the eyeball, but rather with a proxy.

Harris

@harris How can I read original Accept-Encoding header?

If you have sufficient control of the client, you could duplicate the information in a different header.

Otherwise, I’m not aware of any way to do so – we’ll always overwrite it to our supported origin content coding: gzip.

@harris I think this fact (that requests forwarded to origin have Accept-Encoding header changed) should not affect Cloudflare Worker, precisely because it’s working at edge, not origin. I cannot control this header because it’s set by browser. I also cannot change header name because it’s not accessible in any way in Cloudflare Worker.

I’d ask Cloudflare team to consider this a bug rather than implementation detail. If you want to change Accept-Encoding header (and it makes sense for your use case), please consider doing so after worker executes its code, not before, as to allow copying or renaming this header in worker code (or at least accessing it).