Skip to content

Commit

Permalink
use Net:HTTP instead of open-uri
Browse files Browse the repository at this point in the history
  • Loading branch information
benbalter committed May 9, 2018
1 parent b43c9af commit 9c4bd22
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 26 deletions.
2 changes: 1 addition & 1 deletion lib/jekyll-remote-theme.rb
Expand Up @@ -4,7 +4,7 @@
require "fileutils"
require "tempfile"
require "addressable"
require "open-uri"
require "net/http"
require "zip"

$LOAD_PATH.unshift(File.dirname(__FILE__))
Expand Down
58 changes: 34 additions & 24 deletions lib/jekyll-remote-theme/downloader.rb
Expand Up @@ -5,21 +5,12 @@ module RemoteTheme
class Downloader
HOST = "https://codeload.github.com".freeze
PROJECT_URL = "https://github.com/benbalter/jekyll-remote-theme".freeze
USER_AGENT = "Jekyll Remote Theme/#{VERSION} (+#{PROJECT_URL})".freeze
MAX_FILE_SIZE = 1 * (1024 * 1024 * 1024) # Size in bytes (1 GB)
OPTIONS = {
"User-Agent" => "Jekyll Remote Theme/#{VERSION} (+#{PROJECT_URL})",
:redirect => false,
:content_length_proc => ->(size) { enforce_max_file_size!(size) },
:progress_proc => ->(size) { enforce_max_file_size!(size) },
}.freeze

class << self
private def enforce_max_file_size!(size)
if size && size > MAX_FILE_SIZE
raise DownloadError, "Maximum file size of #{MAX_FILE_SIZE} bytes exceeded"
end
end
end
NET_HTTP_ERRORS = [
Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
].freeze

attr_reader :theme
private :theme
Expand Down Expand Up @@ -52,15 +43,34 @@ def zip_file

def download
Jekyll.logger.debug LOG_KEY, "Downloading #{zip_url} to #{zip_file.path}"
io = URI(zip_url).open(OPTIONS)
IO.copy_stream io, zip_file
OpenURI::Meta.init zip_file, io
zip_file
rescue OpenURI::HTTPError, URI::InvalidURIError, SocketError => e
raise DownloadError, "Request failed with #{e.message}"
ensure
io.close if io
io.unlink if io && io.respond_to?(:unlink)
Net::HTTP.start(zip_url.host, zip_url.port, :use_ssl => true) do |http|
http.request(request) do |response|
raise_unless_sucess(response)
enforce_max_file_size(response.content_length)
response.read_body do |chunk|
zip_file.write chunk
end
end
end
rescue *NET_HTTP_ERRORS => e
raise DownloadError, e.message
end

def request
return @request if defined? @request
@request = Net::HTTP::Get.new zip_url.request_uri
@request["User-Agent"] = USER_AGENT
@request
end

def raise_unless_sucess(response)
return if response.is_a?(Net::HTTPSuccess)
raise DownloadError, "#{response.code} - #{response.message}"
end

def enforce_max_file_size(size)
return unless size && size > MAX_FILE_SIZE
raise DownloadError, "Maximum file size of #{MAX_FILE_SIZE} bytes exceeded"
end

def unzip
Expand All @@ -79,7 +89,7 @@ def unzip

# Full URL to codeload zip download endpoint for the given theme
def zip_url
Addressable::URI.join(
@zip_url ||= Addressable::URI.join(
HOST, "#{theme.owner}/", "#{theme.name}/", "zip/", theme.git_ref
).normalize
end
Expand Down
2 changes: 1 addition & 1 deletion spec/jekyll-remote-theme/downloader_spec.rb
Expand Up @@ -53,7 +53,7 @@
after { WebMock.allow_net_connect! }

it "raises a DownloadError" do
msg = "Request failed with 404 Not Found"
msg = "404 - Not Found"
expect { subject.run }.to raise_error(Jekyll::RemoteTheme::DownloadError, msg)
end
end
Expand Down

0 comments on commit 9c4bd22

Please sign in to comment.