mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
parse_curl_response: Handle duplicate headers
`Curl#parse_curl_response` only includes the last instance of a given header in its `:headers` hash (replicating pre-existing behavior). This is a problem for headers like `Set-Cookie`, which can appear more than once in a response. This commit addresses the issue by collecting duplicate headers into an array instead. Headers that only appear once in the response will still have a string value but headers that appear more than once will be an array of strings. Whenever headers from `#parse_curl_response` are used (directly or indirectly), it's important to conditionally handle the expected types.
This commit is contained in:
parent
14ff6be6d0
commit
94449d07c0
@ -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
|
response_hash
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +162,13 @@ describe "Utils::Curl" do
|
|||||||
#{response_text[:ok]}
|
#{response_text[:ok]}
|
||||||
EOS
|
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
|
response_text
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +337,7 @@ describe "Utils::Curl" do
|
|||||||
it "returns a correct hash when given HTTP response text" 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[:ok])).to eq(response_hash[:ok])
|
||||||
expect(parse_curl_response(response_text[:redirection])).to eq(response_hash[:redirection])
|
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
|
end
|
||||||
|
|
||||||
it "returns an empty hash when given an empty string" do
|
it "returns an empty hash when given an empty string" do
|
||||||
|
@ -484,10 +484,25 @@ module Utils
|
|||||||
response_text = response_text.sub(%r{^HTTP/.* (\d+).*$\s*}, "")
|
response_text = response_text.sub(%r{^HTTP/.* (\d+).*$\s*}, "")
|
||||||
|
|
||||||
# Create a hash from the header lines
|
# Create a hash from the header lines
|
||||||
response[:headers] =
|
response[:headers] = {}
|
||||||
response_text.split("\r\n")
|
response_text.split("\r\n").each do |line|
|
||||||
.to_h { |header| header.split(/:\s*/, 2) }
|
header_name, header_value = line.split(/:\s*/, 2)
|
||||||
.transform_keys(&:downcase)
|
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
|
response
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user