diff options
-rw-r--r-- | lib/webrick/httprequest.rb | 9 | ||||
-rw-r--r-- | test/webrick/test_httpserver.rb | 17 |
2 files changed, 25 insertions, 1 deletions
diff --git a/lib/webrick/httprequest.rb b/lib/webrick/httprequest.rb index 10cf72d288..551ef0b08f 100644 --- a/lib/webrick/httprequest.rb +++ b/lib/webrick/httprequest.rb @@ -414,9 +414,13 @@ module WEBrick MAX_URI_LENGTH = 2083 # :nodoc: + # same as Mongrel, Thin and Puma + MAX_HEADER_LENGTH = (112 * 1024) # :nodoc: + def read_request_line(socket) @request_line = read_line(socket, MAX_URI_LENGTH) if socket - if @request_line.bytesize >= MAX_URI_LENGTH and @request_line[-1, 1] != LF + @request_bytes = @request_line.bytesize + if @request_bytes >= MAX_URI_LENGTH and @request_line[-1, 1] != LF raise HTTPStatus::RequestURITooLarge end @request_time = Time.now @@ -435,6 +439,9 @@ module WEBrick if socket while line = read_line(socket) break if /\A(#{CRLF}|#{LF})\z/om =~ line + if (@request_bytes += line.bytesize) > MAX_HEADER_LENGTH + raise HTTPStatus::RequestEntityTooLarge, 'headers too large' + end @raw_header << line end end diff --git a/test/webrick/test_httpserver.rb b/test/webrick/test_httpserver.rb index 5ae105dabe..acb15791ad 100644 --- a/test/webrick/test_httpserver.rb +++ b/test/webrick/test_httpserver.rb @@ -441,4 +441,21 @@ class TestWEBrickHTTPServer < Test::Unit::TestCase s&.shutdown th&.join end + + def test_gigantic_request_header + log_tester = lambda {|log, access_log| + assert_equal 1, log.size + assert log[0].include?('ERROR headers too large') + } + TestWEBrick.start_httpserver({}, log_tester){|server, addr, port, log| + server.mount('/', WEBrick::HTTPServlet::FileHandler, __FILE__) + TCPSocket.open(addr, port) do |c| + c.write("GET / HTTP/1.0\r\n") + junk = -"X-Junk: #{' ' * 1024}\r\n" + assert_raise(Errno::ECONNRESET, Errno::EPIPE) do + loop { c.write(junk) } + end + end + } + end end |