Skip to content

Instantly share code, notes, and snippets.

@amireh
Created December 10, 2010 10:46
Show Gist options
  • Save amireh/736083 to your computer and use it in GitHub Desktop.
Save amireh/736083 to your computer and use it in GitHub Desktop.
Track progress of an HTTP GET request while following HTTP Redirections
def fetch(link, level, options = {})
raise RuntimeError, 'HTTP redirect too deep' if level == 0
buf = OpenURI::Buffer.new
uri = URI.parse(link)
http = Net::HTTP.new(uri.host, uri.port)
response = nil
http.start {
req = Net::HTTP::Get.new(uri.request_uri)
http.request(req) { |resp|
response = resp
if options[:content_length_proc] && Net::HTTPSuccess === response
if response.key?('Content-Length') && 0 < response['Content-Length'].to_i
options[:content_length_proc].call(response['Content-Length'])
else
options[:content_length_proc].call(nil)
end
end
response.read_body {|str|
buf << str
if options[:progress_proc] && Net::HTTPSuccess === response
options[:progress_proc].call(buf.size)
end
}
}
}
io = buf.io
io.rewind
io.status = [response.code, response.message]
response.each {|name,value| buf.io.meta_add_field name, value }
case response
when Net::HTTPSuccess
Net::HTTPOK
return response, io.read
when Net::HTTPMovedPermanently, # 301
Net::HTTPFound, # 302
Net::HTTPSeeOther, # 303
Net::HTTPTemporaryRedirect # 307
return fetch(response['location'], level - 1, options)
else
raise OpenURI::HTTPError.new(io.status.join(' '), io)
end
puts "WARN!!! shouldn't be here"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment