Merge pull request #19445 from Homebrew/curl-headers-handle-post-requests

curl_headers: Handle POST requests
This commit is contained in:
Mike McQuaid 2025-03-09 19:15:12 +00:00 committed by GitHub
commit 9c11f1b637
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 9 deletions

View File

@ -178,7 +178,7 @@ module Homebrew
).returns(T::Array[String]) ).returns(T::Array[String])
} }
def self.post_args(post_form: nil, post_json: nil) def self.post_args(post_form: nil, post_json: nil)
if post_form.present? args = if post_form.present?
require "uri" require "uri"
["--data", URI.encode_www_form(post_form)] ["--data", URI.encode_www_form(post_form)]
elsif post_json.present? elsif post_json.present?
@ -187,6 +187,12 @@ module Homebrew
else else
[] []
end end
if (content_length = args[1]&.length)
args << "--header" << "Content-Length: #{content_length}"
end
args
end end
# Collects HTTP response headers, starting with the provided URL. # Collects HTTP response headers, starting with the provided URL.

View File

@ -144,16 +144,22 @@ RSpec.describe Homebrew::Livecheck::Strategy do
end end
describe "::post_args" do describe "::post_args" do
let(:form_string_content_length) { "Content-Length: #{form_string.length}" }
let(:json_string_content_length) { "Content-Length: #{json_string.length}" }
it "returns an array including `--data` and an encoded form data string" do it "returns an array including `--data` and an encoded form data string" do
expect(strategy.post_args(post_form: post_hash)).to eq(["--data", form_string]) expect(strategy.post_args(post_form: post_hash))
.to eq(["--data", form_string, "--header", form_string_content_length])
# If both `post_form` and `post_json` are present, only `post_form` will # If both `post_form` and `post_json` are present, only `post_form` will
# be used. # be used.
expect(strategy.post_args(post_form: post_hash, post_json: post_hash)).to eq(["--data", form_string]) expect(strategy.post_args(post_form: post_hash, post_json: post_hash))
.to eq(["--data", form_string, "--header", form_string_content_length])
end end
it "returns an array including `--json` and a JSON string" do it "returns an array including `--json` and a JSON string" do
expect(strategy.post_args(post_json: post_hash)).to eq(["--json", json_string]) expect(strategy.post_args(post_json: post_hash))
.to eq(["--json", json_string, "--header", json_string_content_length])
end end
it "returns an empty array if `post_form` value is blank" do it "returns an empty array if `post_form` value is blank" do

View File

@ -277,15 +277,20 @@ module Utils
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def curl_headers(*args, wanted_headers: [], **options) def curl_headers(*args, wanted_headers: [], **options)
get_retry_args = ["--request", "GET"] base_args = ["--fail", "--location", "--silent"]
get_retry_args = []
if (is_post_request = args.include?("POST"))
base_args << "--dump-header" << "-"
else
base_args << "--head"
get_retry_args << "--request" << "GET"
end
# This is a workaround for https://github.com/Homebrew/brew/issues/18213 # This is a workaround for https://github.com/Homebrew/brew/issues/18213
get_retry_args << "--http1.1" if curl_version >= Version.new("8.7") && curl_version < Version.new("8.10") get_retry_args << "--http1.1" if curl_version >= Version.new("8.7") && curl_version < Version.new("8.10")
[[], get_retry_args].each do |request_args| [[], get_retry_args].each do |request_args|
result = curl_output( result = curl_output(*base_args, *request_args, *args, **options)
"--fail", "--location", "--silent", "--head", *request_args, *args,
**options
)
# We still receive usable headers with certain non-successful exit # We still receive usable headers with certain non-successful exit
# statuses, so we special case them below. # statuses, so we special case them below.
@ -295,6 +300,7 @@ module Utils
CURL_RECV_ERROR_EXIT_CODE, CURL_RECV_ERROR_EXIT_CODE,
].include?(result.exit_status) ].include?(result.exit_status)
parsed_output = parse_curl_output(result.stdout) parsed_output = parse_curl_output(result.stdout)
return parsed_output if is_post_request
if request_args.empty? if request_args.empty?
# If we didn't get any wanted header yet, retry using `GET`. # If we didn't get any wanted header yet, retry using `GET`.