Skip to content
Permalink
Browse files
ensure propper handling of multiple Content-Length headers (#4705)
When multiple Content-Length headers are received, error out if all received values do not match.
Return a single Content-Length header value.
  • Loading branch information
Brandon McGinty-Carroll authored and RX14 committed Oct 14, 2017
1 parent 1d02669 commit e8d901972963ecb54a00277020399ab55e3d7124
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
@@ -347,5 +347,33 @@ module HTTP
request.host_with_port.should eq("host.example.org:3000")
end
end

it "doesn't raise on request with multiple Content_length headers" do
io = IO::Memory.new <<-REQ
GET / HTTP/1.1
Host: host
Content-Length: 5
Content-Length: 5
Content-Type: text/plain
abcde
REQ
HTTP::Request.from_io(io)
end

it "raises if request has multiple and differing content-length headers" do
io = IO::Memory.new <<-REQ
GET / HTTP/1.1
Host: host
Content-Length: 5
Content-Length: 6
Content-Type: text/plain
abcde
REQ
expect_raises(ArgumentError) do
HTTP::Request.from_io(io)
end
end
end
end
@@ -26,8 +26,7 @@ module HTTP
body = nil
if body_type.prohibited?
body = nil
elsif content_length = headers["Content-Length"]?
content_length = content_length.to_u64
elsif content_length = content_length(headers)
if content_length != 0
# Don't create IO for Content-Length == 0
body = FixedLengthContent.new(io, content_length)
@@ -166,7 +165,13 @@ module HTTP

# :nodoc:
def self.content_length(headers)
headers["Content-Length"]?.try &.to_u64?
length_headers = headers.get? "Content-Length"
return nil unless length_headers
first_header = length_headers[0]
if length_headers.size > 1 && length_headers.any? { |header| header != first_header }
raise ArgumentError.new("Multiple Content-Length headers received did not match: #{length_headers}")
end
first_header.to_u64
end

# :nodoc:

0 comments on commit e8d9019

Please sign in to comment.