Set etag in worker

trying replicate logic to get 304 if file was not changed, seems like I need two important headers
etag and last-modified, for last-modified seems like I need to save it somewhere in KV store, but etag I can calculate, but seems like cloudflare filtering it out. to be 100% sure I created rule with disabled apps, performance and security. but still no luck, in wrangler preview --watch it shows this header.

import CryptoJS from 'crypto-js'

let response = await getAssetFromKV(event, options)
var md5Hash = CryptoJS.MD5(response.body);
response.headers.set('etag', md5Hash.toString())

Are you trying to replicate 304 from customer to CF, or CF to origin?

I’d try to set ETag and last-modified before the object gets put into KV (via fetch or api), then you will need to implement the condition check on the request.

When doing crypto in workers, use the web crypto api instead of crypto-js.

Trying CF to origin(client browser).

Will try to set it earlier, thank you for advice. But seems like CF just blocking it (I have another subdomain which just proxying to GCP bucket and it shows etag and last-modified fine).

And thank you for web-crypto will use it instead of crypto-js.

In that case, ideally origin would provide those fields and issue the 304.

You just need to make sure you are using those headers when you make your request to origin.

Maybe someone at CF has a better idea on how to do this, but you could do it very explicitly using the Cache API (

  1. Do a cache.match(), grab the last-modified and etag (maybe consider using HEAD method?)
  2. Do a fetch to origin, appending those headers.
  3. If it’s not modified, you receive a 304, and then respond with the cache.match version of the file.
  4. If it is modified, put the new version in the cache and then respond.

In this particular case origin is a cloudflare KV store, and it doesn’t have etag or last-modified at list etag I can generate, for last-modified I need get it from somewhere probably other KV namespace or save it as part of the value or part of the key. But I can’t see locally generated etag in the output.

My bad, origin is a browser but I don’t have any other endpoint other cloudflare KV store, which doesn’t have creation/modification/last access date.

this PR doing close stuff but as input

Is this a workers site? Or where is the KV being populated from?

yes, this is worker site. Here is an issue about it