Skip to content

Instantly share code, notes, and snippets.

@EdgarOrtegaRamirez
Last active July 6, 2018 22:45
Show Gist options
  • Save EdgarOrtegaRamirez/96dd15f9cf42fb7287434c74a6c3b23f to your computer and use it in GitHub Desktop.
Save EdgarOrtegaRamirez/96dd15f9cf42fb7287434c74a6c3b23f to your computer and use it in GitHub Desktop.
Simple File Downloader in Ruby using Net::HTTP, it downloads by chuncks into a file to keep memory as low as possible
# frozen_string_literal: true
require "net/http"
class FileDownloader
attr_reader :uri, :http_response
HTTPS_SCHEME = "https"
def initialize(url:, target:)
@uri = URI(url)
@target = target
@http_response = nil
end
def self.download(url:, target:)
new(url: url, target: target).download
end
def download
Net::HTTP.start(@uri.host, @uri.port, use_ssl: https?) do |http|
request = Net::HTTP::Get.new @uri
http.request request do |response|
@http_response = response
case response.code
when "302"
@uri = URI(response["location"])
return download
when "200"
@target.binmode # no newline conversion | no encoding conversion | encoding is ASCII-8BIT
response.read_body do |chunk|
chunk = yield chunk if block_given?
@target.write(chunk)
end
return @target.tap(&:close)
else
raise Net::HTTPError.new(response.body, nil)
end
end
end
end
private
def https?
@uri.scheme == HTTPS_SCHEME
end
end
# USAGE
file = FileDownloader.download(url: "url-to-file", target: Tempfile.new)
file = Tempfile.new
FileDownloader.download(url: "url-to-file", target: file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment