logstash/lib/pluginmanager/utils/downloader.rb
João Duarte e9c9865f40
Add apache and elastic license headers to source code files (#11673)
* add license header to ruby and java files
* add license header to erb and rake files
* add license headers to gradle files
2020-03-11 11:53:38 +00:00

107 lines
3.5 KiB
Ruby

# Licensed to Elasticsearch B.V. under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch B.V. licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
require "ruby-progressbar"
require "pluginmanager/utils/http_client"
require "pluginmanager/errors"
require "fileutils"
module LogStash module PluginManager module Utils
class Downloader
class ProgressbarFeedback
FORMAT = "%t [%B] %p%%"
TITLE = "Downloading"
attr_reader :progress_bar
def initialize(max)
@progress_bar = ProgressBar.create(:title => TITLE,
:starting_at => 0,
:total => max,
:format => FORMAT)
end
def update(status)
progress_bar.progress += status
end
end
class SilentFeedback
def initialize(max)
end
def update(status)
end
end
attr_reader :download_to, :remote_file_uri, :feedback_strategy
def initialize(remote_file_uri, feedback = SilentFeedback)
@remote_file_uri = URI(remote_file_uri)
@download_to = Stud::Temporary.pathname
@feedback_strategy = feedback
end
def fetch(redirect_count = 0)
# This is defensive programming, but in the real world we do create redirects all the time
raise HttpClient::RedirectionLimit, "Too many redirection, tried #{REDIRECTION_LIMIT} times" if redirect_count >= HttpClient::REDIRECTION_LIMIT
begin
FileUtils.mkdir_p(download_to)
downloaded_file = ::File.open(::File.join(download_to, ::File.basename(remote_file_uri.path)), "wb")
HttpClient.start(remote_file_uri) do |http|
request = Net::HTTP::Get.new(remote_file_uri.path)
http.request(request) do |response|
if response.code == "200"
download_chunks(response, downloaded_file)
elsif response.code == "302"
new_uri = response.headers["location"]
redirect_count += 1
downloader = self.new(new_uri, feedback_strategy)
downloader.fetch(redirect_count)
else
raise LogStash::PluginManager::FileNotFoundError, "Can't download #{remote_file_uri}" if response.code != "200"
end
end
downloaded_file.close
downloaded_file.path
end
rescue => e
downloaded_file.close unless downloaded_file.closed?
FileUtils.rm_rf(download_to)
raise e
end
end
def self.fetch(remote_file, feedback = SilentFeedback)
new(remote_file, feedback).fetch
end
private
def download_chunks(response, downloaded_file)
feedback = feedback_strategy.new(response.content_length)
response.read_body do |chunk|
feedback.update(chunk.bytesize)
downloaded_file.write(chunk)
end
end
end
end end end