Skip to content

Instantly share code, notes, and snippets.

@hmalphettes
Created October 29, 2011 06:06
Show Gist options
  • Save hmalphettes/1324156 to your computer and use it in GitHub Desktop.
Save hmalphettes/1324156 to your computer and use it in GitHub Desktop.
Download a file with EventMachine
require 'rubygems'
require 'eventmachine'
require 'em-http'
# Learning EM: file download with progress.
# See http://rubylearning.com/blog/2010/10/01/an-introduction-to-eventmachine-and-how-to-avoid-callback-spaghetti/
# for a brilliant introduction to EM.
EM.run do
# just an innocent eclipse file of 2megs from a reasonably fast but not balzing fast server.
@file_download_url= ENV['file_download_url'] || "http://www.intalio.org/public/maven2/org/eclipse/jdt/ecj/3.5.1/ecj-3.5.1.jar"
@download_size = -1
@downloaded_size=0
download_uri = URI.parse(@file_download_url)
@file = open(download_uri.path.split('/').last, "wb")
download_url_no_userinfo = "#{download_uri.scheme}://#{download_uri.host}#{download_uri.path}"
http = EM::HttpRequest.new(download_url_no_userinfo)
.get(:head => download_uri.user.nil? ? {}
: {'authorization' => [download_uri.user, download_uri.password]})
http.errback { p 'Uh oh'; @file.close; EM.stop }
http.callback {
@file.close
unless http.response_header.status == 200
puts "Call failed with response code #{http.response_header.status}"
end
EM.stop
}
http.headers do |hash|
p [:headers, hash]
@download_size = hash["CONTENT_LENGTH"].to_i unless hash["CONTENT_LENGTH"].nil?
end
http.stream do |chunk|
@downloaded_size+=chunk.length
@file.write(chunk)
end
EM.add_periodic_timer(1) do # #{@downloaded_size * 100 / @download_size}%
if @downloaded_size == -1
if @download_size == 0
p "The download has not started"
else
p "Downloading #{@file.path} 0%: total size #{@download_size} bytes. Total size unknown"
end
else
if @download_size == 0
p "Downloading #{@file.path} #{@downloaded_size} out of #{@download_size}. Total size unknown"
else
p "Downloading #{@file.path} #{@downloaded_size} out of #{@download_size}: #{@downloaded_size * 100 / @download_size}%"
end
end
end
end ## EM Loop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment