Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/net/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2497,11 +2497,17 @@ def transport_request(req)
# still read the received response.
end

informational_count = 0
begin
res = HTTPResponse.read_new(@socket)
res.decode_content = req.decode_content
res.body_encoding = @response_body_encoding
res.ignore_eof = @ignore_eof
if res.kind_of?(HTTPInformation)
informational_count += 1
raise HTTPBadResponse, 'too many informational responses' if
informational_count > HTTPResponse::MAX_INFORMATIONAL_RESPONSES
end
end while res.kind_of?(HTTPInformation)

res.uri = req.uri
Expand Down
4 changes: 4 additions & 0 deletions lib/net/http/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ class Net::HTTPResponse
# The maximum total size in bytes of the response header.
MAX_RESPONSE_HEADER_LENGTH = 1024 * 1024 # 1 MiB

# The maximum number of informational (1xx) responses accepted before the
# final response.
MAX_INFORMATIONAL_RESPONSES = 100

class << self
# true if the response has a body.
def body_permitted?
Expand Down
42 changes: 42 additions & 0 deletions test/net/http/test_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,48 @@ def test_info
end
end

class TestNetHTTPInformationalResponses < Test::Unit::TestCase
CONFIG = {
'host' => '127.0.0.1',
'proxy_host' => nil,
'proxy_port' => nil,
}

include TestNetHTTPUtils

def mount_informational(count)
@server.mount('/info', proc {|req, res|
count.times { req.continue }
res.body = 'BODY'
})
end

def test_informational_responses
mount_informational 3
start {|http|
res = http.get('/info')
assert_equal('BODY', res.body)
}
end

def test_max_informational_responses
mount_informational Net::HTTPResponse::MAX_INFORMATIONAL_RESPONSES
start {|http|
res = http.get('/info')
assert_equal('BODY', res.body)
}
end

def test_too_many_informational_responses
mount_informational Net::HTTPResponse::MAX_INFORMATIONAL_RESPONSES + 1
start {|http|
assert_raise(Net::HTTPBadResponse) {
http.get('/info')
}
}
end
end

class TestNetHTTPKeepAlive < Test::Unit::TestCase
CONFIG = {
'host' => '127.0.0.1',
Expand Down