Simplify CurlDownloadStrategy.

This commit is contained in:
Markus Reiter 2017-08-08 18:10:13 +02:00
parent b6b8e8863f
commit ae4bafdb36
15 changed files with 132 additions and 148 deletions

View File

@ -143,7 +143,15 @@ module Hbc
def check_appcast_http_code def check_appcast_http_code
odebug "Verifying appcast returns 200 HTTP response code" odebug "Verifying appcast returns 200 HTTP response code"
result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, "--output", "/dev/null", "--write-out", "%{http_code}", cask.appcast], print_stderr: false)
curl_executable, *args = curl_args(
"--compressed", "--location", "--fail",
"--write-out", "%{http_code}",
"--output", "/dev/null",
cask.appcast,
user_agent: :fake
)
result = @command.run(curl_executable, args: args, print_stderr: false)
if result.success? if result.success?
http_code = result.stdout.chomp http_code = result.stdout.chomp
add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200" add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200"

View File

@ -71,7 +71,7 @@ module Hbc
begin begin
ohai "Downloading #{url}." ohai "Downloading #{url}."
curl url, "-o", path curl_download url, to: path
rescue ErrorDuringExecution rescue ErrorDuringExecution
raise CaskUnavailableError.new(token, "Failed to download #{Formatter.url(url)}.") raise CaskUnavailableError.new(token, "Failed to download #{Formatter.url(url)}.")
end end

View File

@ -90,13 +90,8 @@ module Hbc
end end
end end
def downloaded_size
temporary_path.size? || 0
end
def _fetch def _fetch
odebug "Calling curl with args #{cask_curl_args}" curl_download url, *cask_curl_args, to: temporary_path, user_agent: uri_object.user_agent
curl(*cask_curl_args)
end end
def fetch def fetch
@ -131,23 +126,7 @@ module Hbc
private private
def cask_curl_args def cask_curl_args
default_curl_args.tap do |args| cookies_args + referer_args
args.concat(user_agent_args)
args.concat(cookies_args)
args.concat(referer_args)
end
end
def default_curl_args
[url, "-C", downloaded_size, "-o", temporary_path]
end
def user_agent_args
if uri_object.user_agent
["-A", uri_object.user_agent]
else
[]
end
end end
def cookies_args def cookies_args
@ -181,8 +160,7 @@ module Hbc
class CurlPostDownloadStrategy < CurlDownloadStrategy class CurlPostDownloadStrategy < CurlDownloadStrategy
def cask_curl_args def cask_curl_args
super super.concat(post_args)
default_curl_args.concat(post_args)
end end
def post_args def post_args

View File

@ -12,7 +12,11 @@ module Hbc
end end
def calculate_checkpoint def calculate_checkpoint
result = SystemCommand.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, "--fail", @uri], print_stderr: false) curl_executable, *args = curl_args(
"--compressed", "--location", "--fail", @uri,
user_agent: :fake
)
result = SystemCommand.run(curl_executable, args: args, print_stderr: false)
checkpoint = if result.success? checkpoint = if result.success?
processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}m, "") processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}m, "")

View File

@ -1,8 +1,6 @@
module Hbc module Hbc
class URL class URL
FAKE_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10) https://caskroom.github.io".freeze attr_reader :using, :revision, :trust_cert, :uri, :cookies, :referer, :data, :user_agent
attr_reader :using, :revision, :trust_cert, :uri, :cookies, :referer, :data
extend Forwardable extend Forwardable
def_delegators :uri, :path, :scheme, :to_s def_delegators :uri, :path, :scheme, :to_s
@ -17,7 +15,7 @@ module Hbc
def initialize(uri, options = {}) def initialize(uri, options = {})
@uri = Hbc::UnderscoreSupportingURI.parse(uri) @uri = Hbc::UnderscoreSupportingURI.parse(uri)
@user_agent = options[:user_agent] @user_agent = options.fetch(:user_agent, :default)
@cookies = options[:cookies] @cookies = options[:cookies]
@referer = options[:referer] @referer = options[:referer]
@using = options[:using] @using = options[:using]
@ -25,10 +23,5 @@ module Hbc
@trust_cert = options[:trust_cert] @trust_cert = options[:trust_cert]
@data = options[:data] @data = options[:data]
end end
def user_agent
return FAKE_USER_AGENT if @user_agent == :fake
@user_agent
end
end end
end end

View File

@ -33,7 +33,7 @@ module Hbc
meta_dir = cached || cask.metadata_subdir("gpg", :now, true) meta_dir = cached || cask.metadata_subdir("gpg", :now, true)
sig_path = meta_dir.join("signature.asc") sig_path = meta_dir.join("signature.asc")
curl(cask.gpg.signature, "-o", sig_path.to_s) unless cached || force curl_download cask.gpg.signature, to: sig_path unless cached || force
sig_path sig_path
end end

View File

@ -242,12 +242,10 @@ class FormulaAuditor
def self.http_content_headers_and_checksum(url, hash_needed: false, user_agent: :default) def self.http_content_headers_and_checksum(url, hash_needed: false, user_agent: :default)
max_time = hash_needed ? "600" : "25" max_time = hash_needed ? "600" : "25"
args = curl_args( output, = curl_output(
extra_args: ["--connect-timeout", "15", "--include", "--max-time", max_time, url], "--connect-timeout", "15", "--include", "--max-time", max_time, "--location", url,
show_output: true, user_agent: user_agent
user_agent: user_agent,
) )
output = Open3.popen3(*args) { |_, stdout, _, _| stdout.read }
status_code = :unknown status_code = :unknown
while status_code == :unknown || status_code.to_s.start_with?("3") while status_code == :unknown || status_code.to_s.start_with?("3")

View File

@ -25,9 +25,9 @@ module Homebrew
"public_download_numbers": true, "public_download_numbers": true,
"public_stats": true} "public_stats": true}
EOS EOS
curl "--silent", "--fail", "-u#{bintray_user}:#{bintray_key}", curl "--silent", "--fail", "--user", "#{bintray_user}:#{bintray_key}",
"-H", "Content-Type: application/json", "--header", "Content-Type: application/json",
"-d", package_blob, bintray_repo_url "--data", package_blob, bintray_repo_url
puts puts
end end
@ -40,8 +40,8 @@ module Homebrew
content_url = "https://api.bintray.com/content/homebrew/mirror" content_url = "https://api.bintray.com/content/homebrew/mirror"
content_url += "/#{bintray_package}/#{f.pkg_version}/#{filename}" content_url += "/#{bintray_package}/#{f.pkg_version}/#{filename}"
content_url += "?publish=1" content_url += "?publish=1"
curl "--silent", "--fail", "-u#{bintray_user}:#{bintray_key}", curl "--silent", "--fail", "--user", "#{bintray_user}:#{bintray_key}",
"-T", download, content_url "--upload-file", download, content_url
puts puts
ohai "Mirrored #{filename}!" ohai "Mirrored #{filename}!"
end end

View File

@ -228,7 +228,7 @@ module Homebrew
"https://github.com/BrewTestBot/homebrew-#{tap.repo}/compare/homebrew:master...pr-#{issue}" "https://github.com/BrewTestBot/homebrew-#{tap.repo}/compare/homebrew:master...pr-#{issue}"
end end
curl "--silent", "--fail", "-o", "/dev/null", "-I", bottle_commit_url curl "--silent", "--fail", "--output", "/dev/null", "--head", bottle_commit_url
safe_system "git", "checkout", "--quiet", "-B", bottle_branch, orig_revision safe_system "git", "checkout", "--quiet", "-B", bottle_branch, orig_revision
pull_patch bottle_commit_url, "bottle commit" pull_patch bottle_commit_url, "bottle commit"
@ -303,7 +303,7 @@ module Homebrew
extra_msg = @description ? "(#{@description})" : nil extra_msg = @description ? "(#{@description})" : nil
ohai "Fetching patch #{extra_msg}" ohai "Fetching patch #{extra_msg}"
puts "Patch: #{patch_url}" puts "Patch: #{patch_url}"
curl patch_url, "-s", "-o", patchpath curl_download patch_url, to: patchpath
end end
def apply_patch def apply_patch
@ -433,10 +433,10 @@ module Homebrew
end end
version = info.pkg_version version = info.pkg_version
ohai "Publishing on Bintray: #{package} #{version}" ohai "Publishing on Bintray: #{package} #{version}"
curl "-w", '\n', "--silent", "--fail", curl "--write-out", '\n', "--silent", "--fail",
"-u#{creds[:user]}:#{creds[:key]}", "-X", "POST", "--user", "#{creds[:user]}:#{creds[:key]}", "--request", "POST",
"-H", "Content-Type: application/json", "--header", "Content-Type: application/json",
"-d", '{"publish_wait_for_secs": 0}', "--data", '{"publish_wait_for_secs": 0}',
"https://api.bintray.com/content/homebrew/#{repo}/#{package}/#{version}/publish" "https://api.bintray.com/content/homebrew/#{repo}/#{package}/#{version}/publish"
true true
rescue => e rescue => e
@ -587,7 +587,7 @@ module Homebrew
# We're in the cache; make sure to force re-download # We're in the cache; make sure to force re-download
loop do loop do
begin begin
curl url, "-o", filename curl_download url, to: filename
break break
rescue rescue
if retry_count >= max_curl_retries if retry_count >= max_curl_retries
@ -606,7 +606,7 @@ module Homebrew
end end
def check_bintray_mirror(name, url) def check_bintray_mirror(name, url)
headers = curl_output("--connect-timeout", "15", "--head", url)[0] headers, = curl_output("--connect-timeout", "15", "--location", "--head", url)
status_code = headers.scan(%r{^HTTP\/.* (\d+)}).last.first status_code = headers.scan(%r{^HTTP\/.* (\d+)}).last.first
return if status_code.start_with?("2") return if status_code.start_with?("2")
opoo "The Bintray mirror #{url} is not reachable (HTTP status code #{status_code})." opoo "The Bintray mirror #{url} is not reachable (HTTP status code #{status_code})."

View File

@ -375,75 +375,59 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
ohai "Downloading from #{url}" ohai "Downloading from #{url}"
end end
urls = actual_urls(url) curl_download resolved_url(url), to: temporary_path
unless urls.empty?
ohai "Downloading from #{urls.last}"
if !ENV["HOMEBREW_NO_INSECURE_REDIRECT"].nil? && url.start_with?("https://") &&
urls.any? { |u| !u.start_with? "https://" }
puts "HTTPS to HTTP redirect detected & HOMEBREW_NO_INSECURE_REDIRECT is set."
raise CurlDownloadStrategyError, url
end
url = urls.last
end
curl url, "-C", downloaded_size, "-o", temporary_path
end end
# Curl options to be always passed to curl, # Curl options to be always passed to curl,
# with raw head calls (`curl -I`) or with actual `fetch`. # with raw head calls (`curl --head`) or with actual `fetch`.
def _curl_opts def _curl_opts
copts = [] return ["--user" << meta.fetch(:user)] if meta.key?(:user)
copts << "--user" << meta.fetch(:user) if meta.key?(:user) []
copts
end end
def actual_urls(url) def resolved_url(url)
urls = [] redirect_url, _, status = curl_output(
curl_args = _curl_opts << "-I" << "-L" << url *_curl_opts, "--silent", "--head",
Utils.popen_read("curl", *curl_args).scan(/^Location: (.+)$/).map do |m| "--write-out", "%{redirect_url}",
urls << URI.join(urls.last || url, m.first.chomp).to_s "--output", "/dev/null",
end url.to_s
urls )
return url unless status.success?
return url if redirect_url.empty?
ohai "Downloading from #{redirect_url}"
if ENV["HOMEBREW_NO_INSECURE_REDIRECT"] &&
url.start_with?("https://") && !redirect_url.start_with?("https://")
puts "HTTPS to HTTP redirect detected & HOMEBREW_NO_INSECURE_REDIRECT is set."
raise CurlDownloadStrategyError, url
end end
def downloaded_size redirect_url
temporary_path.size? || 0
end end
def curl(*args) def curl(*args, **options)
args.concat _curl_opts args.concat _curl_opts
args << "--connect-timeout" << "5" unless mirrors.empty? args << "--connect-timeout" << "5" unless mirrors.empty?
super super(*args, **options)
end end
end end
# Detect and download from Apache Mirror # Detect and download from Apache Mirror
class CurlApacheMirrorDownloadStrategy < CurlDownloadStrategy class CurlApacheMirrorDownloadStrategy < CurlDownloadStrategy
def apache_mirrors def apache_mirrors
rd, wr = IO.pipe mirrors, = Open3.capture3(
buf = "" *curl_args(*_curl_opts, "--silent", "--location", "#{@url}&asjson=1"),
)
pid = fork do JSON.parse(mirrors)
ENV.delete "HOMEBREW_CURL_VERBOSE"
rd.close
$stdout.reopen(wr)
$stderr.reopen(wr)
curl "#{@url}&asjson=1"
end
wr.close
rd.readline if ARGV.verbose? # Remove Homebrew output
buf << rd.read until rd.eof?
rd.close
Process.wait(pid)
buf
end end
def _fetch def _fetch
return super if @tried_apache_mirror return super if @tried_apache_mirror
@tried_apache_mirror = true @tried_apache_mirror = true
mirrors = JSON.parse(apache_mirrors) mirrors = apache_mirrors
path_info = mirrors.fetch("path_info") path_info = mirrors.fetch("path_info")
@url = mirrors.fetch("preferred") + path_info @url = mirrors.fetch("preferred") + path_info
@mirrors |= %W[https://archive.apache.org/dist/#{path_info}] @mirrors |= %W[https://archive.apache.org/dist/#{path_info}]
@ -460,7 +444,7 @@ end
class CurlPostDownloadStrategy < CurlDownloadStrategy class CurlPostDownloadStrategy < CurlDownloadStrategy
def _fetch def _fetch
base_url, data = @url.split("?") base_url, data = @url.split("?")
curl base_url, "-d", data, "-C", downloaded_size, "-o", temporary_path curl_download base_url, "--data", data, to: temporary_path
end end
end end
@ -530,7 +514,7 @@ class S3DownloadStrategy < CurlDownloadStrategy
s3url = obj.public_url s3url = obj.public_url
end end
curl s3url, "-C", downloaded_size, "-o", temporary_path curl_download s3url, to: temporary_path
end end
end end
@ -566,7 +550,7 @@ class GitHubPrivateRepositoryDownloadStrategy < CurlDownloadStrategy
end end
def _fetch def _fetch
curl download_url, "-C", downloaded_size, "-o", temporary_path curl_download download_url, to: temporary_path
end end
private private
@ -615,7 +599,7 @@ class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDo
def _fetch def _fetch
# HTTP request header `Accept: application/octet-stream` is required. # HTTP request header `Accept: application/octet-stream` is required.
# Without this, the GitHub API will respond with metadata, not binary. # Without this, the GitHub API will respond with metadata, not binary.
curl download_url, "-C", downloaded_size, "-o", temporary_path, "-H", "Accept: application/octet-stream" curl_download download_url, "--header", "Accept: application/octet-stream", to: temporary_path
end end
private private
@ -915,18 +899,27 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy
def github_last_commit def github_last_commit
return if ENV["HOMEBREW_NO_GITHUB_API"] return if ENV["HOMEBREW_NO_GITHUB_API"]
output, _, status = curl_output "-H", "Accept: application/vnd.github.v3.sha", \ output, _, status = curl_output(
"-I", "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{@ref}" "--silent", "--head", "--location",
"-H", "Accept: application/vnd.github.v3.sha",
"https://api.github.com/repos/#{@user}/#{@repo}/commits/#{@ref}"
)
commit = output[/^ETag: \"(\h+)\"/, 1] if status.success? return unless status.success?
commit = output[/^ETag: \"(\h+)\"/, 1]
version.update_commit(commit) if commit version.update_commit(commit) if commit
commit commit
end end
def multiple_short_commits_exist?(commit) def multiple_short_commits_exist?(commit)
return if ENV["HOMEBREW_NO_GITHUB_API"] return if ENV["HOMEBREW_NO_GITHUB_API"]
output, _, status = curl_output "-H", "Accept: application/vnd.github.v3.sha", \
"-I", "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{commit}" output, _, status = curl_output(
"--silent", "--head", "--location",
"-H", "Accept: application/vnd.github.v3.sha",
"https://api.github.com/repos/#{@user}/#{@repo}/commits/#{commit}"
)
!(status.success? && output && output[/^Status: (200)/, 1] == "200") !(status.success? && output && output[/^Status: (200)/, 1] == "200")
end end
@ -1159,15 +1152,13 @@ class DownloadStrategyDetector
SubversionDownloadStrategy SubversionDownloadStrategy
when %r{^cvs://} when %r{^cvs://}
CVSDownloadStrategy CVSDownloadStrategy
when %r{^https?://(.+?\.)?googlecode\.com/hg} when %r{^hg://}, %r{^https?://(.+?\.)?googlecode\.com/hg}
MercurialDownloadStrategy
when %r{^hg://}
MercurialDownloadStrategy MercurialDownloadStrategy
when %r{^bzr://} when %r{^bzr://}
BazaarDownloadStrategy BazaarDownloadStrategy
when %r{^fossil://} when %r{^fossil://}
FossilDownloadStrategy FossilDownloadStrategy
when %r{^http://svn\.apache\.org/repos/}, %r{^svn\+http://} when %r{^svn\+http://}, %r{^http://svn\.apache\.org/repos/}
SubversionDownloadStrategy SubversionDownloadStrategy
when %r{^https?://(.+?\.)?sourceforge\.net/hgweb/} when %r{^https?://(.+?\.)?sourceforge\.net/hgweb/}
MercurialDownloadStrategy MercurialDownloadStrategy

View File

@ -165,7 +165,7 @@ module Formulary
def load_file def load_file
HOMEBREW_CACHE_FORMULA.mkpath HOMEBREW_CACHE_FORMULA.mkpath
FileUtils.rm_f(path) FileUtils.rm_f(path)
curl url, "-o", path curl_download url, to: path
super super
rescue MethodDeprecatedError => e rescue MethodDeprecatedError => e
if url =~ %r{github.com/([\w-]+)/homebrew-([\w-]+)/} if url =~ %r{github.com/([\w-]+)/homebrew-([\w-]+)/}

View File

@ -27,8 +27,11 @@ describe "download strategies", :cask do
expect(downloader).to have_received(:curl).with( expect(downloader).to have_received(:curl).with(
cask.url.to_s, cask.url.to_s,
"-C", 0, "--location",
"-o", kind_of(Pathname) "--remote-time",
"--continue-at", "-",
"--output", kind_of(Pathname),
user_agent: :default
) )
end end
@ -36,25 +39,25 @@ describe "download strategies", :cask do
let(:url_options) { { user_agent: "Mozilla/25.0.1" } } let(:url_options) { { user_agent: "Mozilla/25.0.1" } }
it "adds the appropriate curl args" do it "adds the appropriate curl args" do
curl_args = [] expect(downloader).to receive(:safe_system) { |*args|
allow(downloader).to receive(:curl) { |*args| curl_args = args } expect(args.each_cons(2)).to include(["--user-agent", "Mozilla/25.0.1"])
}
downloader.fetch downloader.fetch
expect(curl_args.each_cons(2)).to include(["-A", "Mozilla/25.0.1"])
end end
end end
context "with a generalized fake user agent" do context "with a generalized fake user agent" do
alias_matcher :a_string_matching, :match
let(:url_options) { { user_agent: :fake } } let(:url_options) { { user_agent: :fake } }
it "adds the appropriate curl args" do it "adds the appropriate curl args" do
curl_args = [] expect(downloader).to receive(:safe_system) { |*args|
allow(downloader).to receive(:curl) { |*args| curl_args = args } expect(args.each_cons(2).to_a).to include(["--user-agent", a_string_matching(/Mozilla.*Mac OS X 10.*AppleWebKit/)])
}
downloader.fetch downloader.fetch
expect(curl_args.each_cons(2)).to include(["-A", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10) https://caskroom.github.io"])
end end
end end

View File

@ -33,13 +33,18 @@ describe Hbc::DSL::Appcast do
describe "#calculate_checkpoint" do describe "#calculate_checkpoint" do
before do before do
expect(Hbc::SystemCommand).to receive(:run).with(*cmd_args).and_return(cmd_result) expect(Hbc::SystemCommand).to receive(:run) do |executable, **options|
expect(executable).to eq "/usr/bin/curl"
expect(options[:args]).to include(*cmd_args)
expect(options[:print_stderr]).to be false
cmd_result
end
allow(cmd_result).to receive(:success?).and_return(cmd_success) allow(cmd_result).to receive(:success?).and_return(cmd_success)
allow(cmd_result).to receive(:stdout).and_return(cmd_stdout) allow(cmd_result).to receive(:stdout).and_return(cmd_stdout)
end end
context "when server returns a successful HTTP status" do context "when server returns a successful HTTP status" do
let(:cmd_args) { ["/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, "--fail", uri], print_stderr: false] } let(:cmd_args) { [HOMEBREW_USER_AGENT_FAKE_SAFARI, "--compressed", "--location", "--fail", uri] }
let(:cmd_result) { double("Hbc::SystemCommand::Result") } let(:cmd_result) { double("Hbc::SystemCommand::Result") }
let(:cmd_success) { true } let(:cmd_success) { true }
let(:cmd_stdout) { "hello world" } let(:cmd_stdout) { "hello world" }
@ -56,7 +61,7 @@ describe Hbc::DSL::Appcast do
end end
context "when server returns a non-successful HTTP status" do context "when server returns a non-successful HTTP status" do
let(:cmd_args) { ["/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, "--fail", uri], print_stderr: false] } let(:cmd_args) { [HOMEBREW_USER_AGENT_FAKE_SAFARI, "--compressed", "--location", "--fail", uri] }
let(:cmd_result) { double("Hbc::SystemCommand::Result") } let(:cmd_result) { double("Hbc::SystemCommand::Result") }
let(:cmd_success) { false } let(:cmd_success) { false }
let(:cmd_stdout) { "some error message from the server" } let(:cmd_stdout) { "some error message from the server" }

View File

@ -1,42 +1,46 @@
require "pathname" require "pathname"
require "open3" require "open3"
def curl_args(options = {}) def curl_executable
curl = Pathname.new ENV["HOMEBREW_CURL"] curl = Pathname.new ENV["HOMEBREW_CURL"]
curl = Pathname.new "/usr/bin/curl" unless curl.exist? curl = Pathname.new "/usr/bin/curl" unless curl.exist?
raise "#{curl} is not executable" unless curl.exist? && curl.executable? return curl if curl.executable?
raise "#{curl} is not executable"
args = [
curl.to_s,
"--remote-time",
"--location",
]
case options[:user_agent]
when :browser
args << "--user-agent" << HOMEBREW_USER_AGENT_FAKE_SAFARI
else
args << "--user-agent" << HOMEBREW_USER_AGENT_CURL
end end
unless options[:show_output] def curl_args(*extra_args, show_output: false, user_agent: :default)
args = [
curl_executable.to_s,
"--fail",
"--show-error",
]
args << "--user-agent" << case user_agent
when :browser, :fake
HOMEBREW_USER_AGENT_FAKE_SAFARI
when :default
HOMEBREW_USER_AGENT_CURL
else
user_agent
end
unless show_output
args << "--progress-bar" unless ARGV.verbose? args << "--progress-bar" unless ARGV.verbose?
args << "--verbose" if ENV["HOMEBREW_CURL_VERBOSE"] args << "--verbose" if ENV["HOMEBREW_CURL_VERBOSE"]
args << "--fail"
args << "--silent" if !$stdout.tty? || ENV["TRAVIS"] args << "--silent" if !$stdout.tty? || ENV["TRAVIS"]
end end
args += options[:extra_args] if options[:extra_args] args + extra_args
args
end end
def curl(*args) def curl(*args)
safe_system(*curl_args(extra_args: args)) safe_system(*curl_args(*args))
end end
def curl_output(*args) def curl_download(*args, to: nil, **options)
curl_args = curl_args(extra_args: args, show_output: true) curl(*args, "--location", "--remote-time", "--continue-at", "-", "--output", to, **options)
Open3.popen3(*curl_args) do |_, stdout, stderr, wait_thread|
[stdout.read, stderr.read, wait_thread.value]
end end
def curl_output(*args, **options)
Open3.capture3(*curl_args(*args, show_output: true, **options))
end end

View File

@ -166,7 +166,7 @@ module GitHub
args += ["--dump-header", headers_tmpfile.path] args += ["--dump-header", headers_tmpfile.path]
output, errors, status = curl_output(url.to_s, *args) output, errors, status = curl_output(url.to_s, "--location", *args)
output, _, http_code = output.rpartition("\n") output, _, http_code = output.rpartition("\n")
output, _, http_code = output.rpartition("\n") if http_code == "000" output, _, http_code = output.rpartition("\n") if http_code == "000"
headers = headers_tmpfile.read headers = headers_tmpfile.read