[Restful-rails-general] Accept header and cache
Nicola Piccinini
pic at superfluo.org
Sat Jul 8 01:21:39 EDT 2006
> No, RESTful Rails shouldn't be adding Accept to the Vary header
> on its own, since at no point does it look at the Accept header
> and send different content base on its value.
>
> If it was handling content negotiation (or conneg for short)
> then it would add the header. Conneg is the process of looking
> at the Accept header, and then rendering a different view to
> match the capabilities of the browser/user-agent.
ok, so I think that the MimeResponds is responsible for this.
This dirty hack:
module ActionController::MimeResponds::InstanceMethods
alias :_or_respond_to :respond_to
def respond_to(*types, &block)
_or_respond_to(*types, &block)
response.vary << 'Accept'
end
end
adds the 'Accept' value in the Vary header whenever the respond_to
method is used. Imho, this makes sense because actually the respond_to
method looks at the Accept header.
>> 2. shouldn't the value of Etag header in the second response be
>> different from the first one? Again the experiments show that this
>> isn't the case.
>
>
> The ETag is currently generated based on the lock_version
> values of all the models that were used to render the view.
>
> It should probably include other information, like the template
> path and timestamp. Unfortunately at the point where you need
> to test the conditions you don't necessarily know which template
> is going to be used, or if one is going to be used at all.
exactly!
> I'm not entirely sure how to best solve this though, but if anyone
> has ideas I'm open to them.
I haven't a solution but I like to discuss here about a ugly workaround
to better understand the problem.
1. another dirty hack:
class HTTP::Conditions
def consider_for_etag
@consider_for_etag ||= []
end
end
2. in Conditions#test!:
etag_values = [].concat(consider_for_etag).concat(lock_versions)
response.etag = Digest::MD5.hexdigest(etag_values.join('|'))
instead of
response.etag = Digest::MD5.hexdigest(lock_versions.join('|'))
3. finally, in RESTful controllers, when appropriate:
resource :by_id do |r|
conditions.consider_for_etag << 'what you want'
# ...
In the case of content type, this could be:
conditions.consider_for_etag << request.headers['Accept']
In this way the resource's Etag is surely different if the content type
is different.
Of course it's sub-optimal because it could be different also when the
content type is the same ... . To make it optimal we should ask the
Responders for the chosen template before it really uses it but this
seems to me difficult.
Moreover this instruction can't be added to the respond_to method
because the Conditions#test! method is called before it.
Any comment?
Thanks, best regards.
--
Nicola Piccinini -- http://superfluo.org
More information about the Restful-rails-general
mailing list