aspnet/ResponseCaching

feature request - automatic ETag generation

jimasp opened this issue · 4 comments

I'd like a facility where the ResponseCaching middleware can be configured to calculate the ETag automatically based on e.g. request path+query and response body and accounting for vary headers. You'd also want the ability to override that functionality, possibly by passing in an Options object to e.g. specify what vary headers you care about/ignore.

Current community solutions to work out the ETag from the response body use a buffer (because you need to know if e.g. the view file or javascript file guid has changed), which is is a bit of a hack:

http://stackoverflow.com/questions/35458737/implement-http-cache-etag-in-asp-net-core-web-api/43017504

In the real world, the MS responsecaching middleware seems a bit pointless without ETag generation, as it forces you to roll your own middleware to provide this functionality, which means you then don't need the MS version.

It could send an e-tag when serving content from the cache, but it couldn't send one on the initial request. It has the same problem as the rest of the stack, which is that it does not buffer the whole body before it's sent to the client (it does write-through buffering), so it couldn't calculate an e-tag from the body in time to add it to the headers.

Gah, that's an annoyingly clear and excellent explanation of why you can't do it ;)
Thanks.

So what's the best solution to adding E-Tags? The linked StackOverflow answer converts the action result to JSON and creates the E-Tag from that combined with the URL. It would be nice to have something built in.

A verbose e-tag generator needs to buffer and hash the entire response content. A good e-tag generator would come from the original data source and be able to generate the tag without buffering and hashing the entire contents, but that requires very specific knowledge of the type of response being generated. What we did for StaticFiles was an approximation of this, but theoretically not reliable enough.