This post originated from an RSS feed registered with Ruby Buzz
by Red Handed.
Original Post: Using Etags With Open-uri
Feed Title: RedHanded
Feed URL: http://redhanded.hobix.com/index.xml
Feed Description: sneaking Ruby through the system
If you just joined us, we’re fawning over Tanaka-san’s code lately. He’s the author of an entire repository of red magic. One of his masterpieces is open-uri, a library that in now enshrined in Ruby 1.8.0.
With open-uri, you can access a file over FTP or HTTP and read from like it was any other IO handle (using read.) For HTTP resources, you can access headers through the meta accessor:
require 'open-uri'
open( "http://redhanded.hobix.com/index.xml" ) do |feed|
p feed.last_modified
p feed.meta['etag']
end
The ETag header is great, as it offers a unique hash for the content being served. If your web server returns an ETag, you can issue a conditional GET.
Especially common in RSS feed readers. This technique was also used in the old RAA-Install to check if the RAA feed had changed since the last install. You just send the web server the old etag under the If-None-Match header. The web server will send you a 304 status unless the file is new. This prevents the whole file from being sent if it is old.
require 'open-uri'
# 1st request -- save the ETag
etag = nil
open( "http://redhanded.hobix.com/index.xml" ) do |feed|
etag = feed.meta['etag']
end
# 2nd request -- only retrieve the file if it has changed
begin
open( "http://redhanded.hobix.com/index.xml",
"If-None-Match" => etag ) do |feed|
puts "File has changed: #{ feed.read.length } bytes read"
end
rescue OpenURI::HTTPError
puts "No file available or file has not changed."
end
You can also use the modification time, with the help of the Time#rfc2822 method which formats dates for HTTP.
require 'open-uri'
# 1st request -- save the modification time
mtime = nil
open( "http://redhanded.hobix.com/index.xml" ) do |feed|
mtime = feed.last_modified
end
# 2nd request -- only retrieve the file if it has changed
begin
open( "http://redhanded.hobix.com/index.xml",
"If-Modified-Since" => mtime.rfc2822 ) do |feed|
puts "File has changed: #{ feed.read.length } bytes read"
end
rescue OpenURI::HTTPError
puts "No file available or file has not changed."
end