diff --git a/Library/Homebrew/test/utils/curl_spec.rb b/Library/Homebrew/test/utils/curl_spec.rb index d38d369eb3..3f0e6cfa28 100644 --- a/Library/Homebrew/test/utils/curl_spec.rb +++ b/Library/Homebrew/test/utils/curl_spec.rb @@ -112,6 +112,24 @@ describe "Utils::Curl" do }, } + response_hash[:duplicate_header] = { + status_code: "200", + status_text: "OK", + headers: { + "cache-control" => "max-age=604800", + "content-type" => "text/html; charset=UTF-8", + "date" => "Wed, 1 Jan 2020 01:23:45 GMT", + "expires" => "Wed, 31 Jan 2020 01:23:45 GMT", + "last-modified" => "Thu, 1 Jan 2019 01:23:45 GMT", + "content-length" => "123", + "set-cookie" => [ + "example1=first", + "example2=second; Expires Wed, 31 Jan 2020 01:23:45 GMT", + "example3=third", + ], + }, + } + response_hash } @@ -144,6 +162,13 @@ describe "Utils::Curl" do #{response_text[:ok]} EOS + response_text[:duplicate_header] = response_text[:ok].sub( + /\r\n\Z/, + "Set-Cookie: #{response_hash[:duplicate_header][:headers]["set-cookie"][0]}\r\n" \ + "Set-Cookie: #{response_hash[:duplicate_header][:headers]["set-cookie"][1]}\r\n" \ + "Set-Cookie: #{response_hash[:duplicate_header][:headers]["set-cookie"][2]}\r\n\r\n", + ) + response_text } @@ -312,6 +337,7 @@ describe "Utils::Curl" do it "returns a correct hash when given HTTP response text" do expect(parse_curl_response(response_text[:ok])).to eq(response_hash[:ok]) expect(parse_curl_response(response_text[:redirection])).to eq(response_hash[:redirection]) + expect(parse_curl_response(response_text[:duplicate_header])).to eq(response_hash[:duplicate_header]) end it "returns an empty hash when given an empty string" do diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb index fe71682353..08949d6360 100644 --- a/Library/Homebrew/utils/curl.rb +++ b/Library/Homebrew/utils/curl.rb @@ -484,10 +484,25 @@ module Utils response_text = response_text.sub(%r{^HTTP/.* (\d+).*$\s*}, "") # Create a hash from the header lines - response[:headers] = - response_text.split("\r\n") - .to_h { |header| header.split(/:\s*/, 2) } - .transform_keys(&:downcase) + response[:headers] = {} + response_text.split("\r\n").each do |line| + header_name, header_value = line.split(/:\s*/, 2) + next if header_name.blank? + + header_name = header_name.strip.downcase + header_value&.strip! + + case response[:headers][header_name] + when nil + response[:headers][header_name] = header_value + when String + response[:headers][header_name] = [response[:headers][header_name], header_value] + when Array + response[:headers][header_name].push(header_value) + end + + response[:headers][header_name] + end response end