Merge pull request #15351 from reitermarkus/livecheck-head

Use `curl_headers` and `curl_output` for `Livecheck` strategies.
This commit is contained in:
Markus Reiter 2023-05-09 00:55:34 +02:00 committed by GitHub
commit b05de929c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 19 deletions

View File

@ -481,7 +481,7 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
url = url.sub(%r{^https?://#{GitHubPackages::URL_DOMAIN}/}o, "#{domain.chomp("/")}/") url = url.sub(%r{^https?://#{GitHubPackages::URL_DOMAIN}/}o, "#{domain.chomp("/")}/")
end end
parsed_output = curl_head(url.to_s, timeout: timeout) parsed_output = curl_headers(url.to_s, wanted_headers: ["content-disposition"], timeout: timeout)
parsed_headers = parsed_output.fetch(:responses).map { |r| r.fetch(:headers) } parsed_headers = parsed_output.fetch(:responses).map { |r| r.fetch(:headers) }
final_url = curl_response_follow_redirections(parsed_output.fetch(:responses), url) final_url = curl_response_follow_redirections(parsed_output.fetch(:responses), url)

View File

@ -10,6 +10,8 @@ module Homebrew
# #
# @api private # @api private
module Strategy module Strategy
extend Utils::Curl
module_function module_function
# {Strategy} priorities informally range from 1 to 10, where 10 is the # {Strategy} priorities informally range from 1 to 10, where 10 is the
@ -53,14 +55,6 @@ module Homebrew
"--silent" "--silent"
].freeze ].freeze
# `curl` arguments used in `Strategy#page_headers` method.
PAGE_HEADERS_CURL_ARGS = ([
# We only need the response head (not the body)
"--head",
# Some servers may not allow a HEAD request, so we use GET
"--request", "GET"
] + DEFAULT_CURL_ARGS).freeze
# `curl` arguments used in `Strategy#page_content` method. # `curl` arguments used in `Strategy#page_content` method.
PAGE_CONTENT_CURL_ARGS = ([ PAGE_CONTENT_CURL_ARGS = ([
"--compressed", "--compressed",
@ -188,11 +182,12 @@ module Homebrew
headers = [] headers = []
[:default, :browser].each do |user_agent| [:default, :browser].each do |user_agent|
output, _, status = curl_with_workarounds( output, _, status = curl_headers(
*PAGE_HEADERS_CURL_ARGS, url, url,
**DEFAULT_CURL_OPTIONS, wanted_headers: ["location", "content-disposition"],
use_homebrew_curl: homebrew_curl, use_homebrew_curl: homebrew_curl,
user_agent: user_agent user_agent: user_agent,
**DEFAULT_CURL_OPTIONS,
) )
next unless status.success? next unless status.success?
@ -216,7 +211,7 @@ module Homebrew
def self.page_content(url, homebrew_curl: false) def self.page_content(url, homebrew_curl: false)
stderr = T.let(nil, T.nilable(String)) stderr = T.let(nil, T.nilable(String))
[:default, :browser].each do |user_agent| [:default, :browser].each do |user_agent|
stdout, stderr, status = curl_with_workarounds( stdout, stderr, status = curl_output(
*PAGE_CONTENT_CURL_ARGS, url, *PAGE_CONTENT_CURL_ARGS, url,
**DEFAULT_CURL_OPTIONS, **DEFAULT_CURL_OPTIONS,
use_homebrew_curl: homebrew_curl, use_homebrew_curl: homebrew_curl,

View File

@ -12,7 +12,7 @@ describe CurlDownloadStrategy do
let(:artifact_domain) { nil } let(:artifact_domain) { nil }
before do before do
allow(strategy).to receive(:curl_head).and_return({ responses: [{ headers: {} }] }) allow(strategy).to receive(:curl_headers).and_return({ responses: [{ headers: {} }] })
end end
it "parses the opts and sets the corresponding args" do it "parses the opts and sets the corresponding args" do

View File

@ -205,7 +205,7 @@ module Utils
curl_with_workarounds(*args, print_stderr: false, show_output: true, **options) curl_with_workarounds(*args, print_stderr: false, show_output: true, **options)
end end
def curl_head(*args, **options) def curl_headers(*args, wanted_headers: [], **options)
[[], ["--request", "GET"]].each do |request_args| [[], ["--request", "GET"]].each do |request_args|
result = curl_output( result = curl_output(
"--fail", "--location", "--silent", "--head", *request_args, *args, "--fail", "--location", "--silent", "--head", *request_args, *args,
@ -216,9 +216,9 @@ module Utils
if result.success? || result.exit_status == 22 if result.success? || result.exit_status == 22
parsed_output = parse_curl_output(result.stdout) parsed_output = parse_curl_output(result.stdout)
# If we didn't get a `Content-Disposition` header yet, retry using `GET`. # If we didn't get any wanted header yet, retry using `GET`.
next if request_args.empty? && next if request_args.empty? && wanted_headers.any? &&
parsed_output.fetch(:responses).none? { |r| r.fetch(:headers).key?("content-disposition") } parsed_output.fetch(:responses).none? { |r| (r.fetch(:headers).keys & wanted_headers).any? }
return parsed_output if result.success? return parsed_output if result.success?
end end