-2

For one controller (only), I'd like to use an ETag value generated outside of rails caching logic, and manage 304-vs-200 responses myself. It seems that nothing I do to set the ETag header works:

response.etag = myEtag
headers['ETag'] = myEtag
render :text => myText, :etag => myEtag

Rails always uses its own version.

I know I could disable caching app-wide, but I don't want that - just want to override it in the responses for one ActionController subclass.

4

2 回答 2

0

fresh_when, etc. didn't quite suit my needs - in my case the solution was to refuse caching via

def caching_allowed?
  false
end

then set just the headers['ETag'] member on my response - setting any of the .etag options seems to cause Rails to MD5 All The Things.

于 2012-05-14T16:39:33.597 回答
0

Also if you would like to overwrite it directly, you can set the etag value like below:

headers['ETag'] = 'xxxxxx'

Code reference from Rack (rack-1.6.11/lib/rack/etag.rb)

if etag_status?(status) && etag_body?(body) && !skip_caching?(headers)
    original_body = body
    digest, new_body = digest_body(body)
    body = Rack::BodyProxy.new(new_body) do
        original_body.close if original_body.respond_to?(:close)
    end
    headers[ETAG_STRING] = %(W/"#{digest}") if digest
end

private

def skip_caching?(headers)
    (headers[CACHE_CONTROL] && headers[CACHE_CONTROL].include?('no-cache')) ||
      headers.key?(ETAG_STRING) || headers.key?('Last-Modified')
end
于 2019-07-03T07:29:14.460 回答