On Being for the Web
August 5, 2007
Tim Bray, talking about ETags:
What you want to do is compute the ETag based on the underlying data resources that actually drive the page creation; the input to that process, not its output. This is often going to be a small number (sometimes one) of timestamp or version fields in a database row, or metadata from the underlying filesystem. It’s also going to be application-dependent. So a framework that was really designed for the Web would expose the ETag generation to the application programmer in a way that let them be smart about conserving the resources that actually matter.
Very true; this is what Joe Gregorio wrote about a while ago. Contrary to the Tim’s impression, this seems to be exactly what Rails does:
def handle_conditional_get!
if body.is_a?(String) && (headers['Status'] ? headers['Status'][0..2] == '200' : true) && !body.empty?
self.headers['ETag'] ||= %("#{Digest::MD5.hexdigest(body)}")
self.headers['Cache-Control'] = 'private' if headers['Cache-Control'] == DEFAULT_HEADERS['Cache-Control']
if request.headers['HTTP_IF_NONE_MATCH'] == headers['ETag']
self.headers['Status'] = '304 Not Modified'
self.body = ''
end
end
end
In other words: you can set the header yourself; if you do so, it’s set and Rails will leave it as is. Back in March, I thought that it might make sense to add something in the lower layers to support this. I’m not so sure anymore; it’s probably better to leave this to the application developer.
About
This page contains a single entry from Stefan Tilkov's Random Stuff posted on August 5, 2007 11:41 PM. The previous post in this blog was Google Spreadsheets, CSV, Venus. The next post in this blog is syx - Open Source Smalltalk. Many more can be found on the main index page or by looking through the archives.
Comments
Um, are you sure? I’m reading that code and the first thing I see is
if body.is_a?(String) ...
which suggests that you’ve gone ahead and computed the whole result before you start thinking about conditional-get headers. My point is that the big win would be in avoiding computing the result body. But I’m still a relative Rails newb, so maybe I’m missing something obvious
Posted by: Tim Bray at August 6, 2007 5:49 AM | link
First disclaimer: this is not my code, it’s taken straight from Edge Rails. What I meant is: the default code computes an ETag if it isn’t set. If you set the ETag yourself, no magic happens and it’s passed straight through.
Posted by: Stefan Tilkov at August 6, 2007 10:03 AM | link
