mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Merge pull request from GHSA-7xx3-m584-x994
could monopolize a thread. Previously, this could make a DoS attack more severe. Co-authored-by: Evan Phoenix <evan@phx.io>
This commit is contained in:
parent
9f4f87cb60
commit
6baa4d8e1c
2 changed files with 22 additions and 1 deletions
|
@ -118,6 +118,13 @@ module Puma
|
||||||
# sending data back
|
# sending data back
|
||||||
WRITE_TIMEOUT = 10
|
WRITE_TIMEOUT = 10
|
||||||
|
|
||||||
|
# How many requests to attempt inline before sending a client back to
|
||||||
|
# the reactor to be subject to normal ordering. The idea here is that
|
||||||
|
# we amortize the cost of going back to the reactor for a well behaved
|
||||||
|
# but very "greedy" client across 10 requests. This prevents a not
|
||||||
|
# well behaved client from monopolizing the thread forever.
|
||||||
|
MAX_FAST_INLINE = 10
|
||||||
|
|
||||||
# The original URI requested by the client.
|
# The original URI requested by the client.
|
||||||
REQUEST_URI= 'REQUEST_URI'.freeze
|
REQUEST_URI= 'REQUEST_URI'.freeze
|
||||||
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
||||||
|
|
|
@ -466,6 +466,8 @@ module Puma
|
||||||
clean_thread_locals = @options[:clean_thread_locals]
|
clean_thread_locals = @options[:clean_thread_locals]
|
||||||
close_socket = true
|
close_socket = true
|
||||||
|
|
||||||
|
requests = 0
|
||||||
|
|
||||||
while true
|
while true
|
||||||
case handle_request(client, buffer)
|
case handle_request(client, buffer)
|
||||||
when false
|
when false
|
||||||
|
@ -479,7 +481,19 @@ module Puma
|
||||||
|
|
||||||
ThreadPool.clean_thread_locals if clean_thread_locals
|
ThreadPool.clean_thread_locals if clean_thread_locals
|
||||||
|
|
||||||
unless client.reset(@status == :run)
|
requests += 1
|
||||||
|
|
||||||
|
check_for_more_data = @status == :run
|
||||||
|
|
||||||
|
if requests >= MAX_FAST_INLINE
|
||||||
|
# This will mean that reset will only try to use the data it already
|
||||||
|
# has buffered and won't try to read more data. What this means is that
|
||||||
|
# every client, independent of their request speed, gets treated like a slow
|
||||||
|
# one once every MAX_FAST_INLINE requests.
|
||||||
|
check_for_more_data = false
|
||||||
|
end
|
||||||
|
|
||||||
|
unless client.reset(check_for_more_data)
|
||||||
close_socket = false
|
close_socket = false
|
||||||
client.set_timeout @persistent_timeout
|
client.set_timeout @persistent_timeout
|
||||||
@reactor.add client
|
@reactor.add client
|
||||||
|
|
Loading…
Reference in a new issue