mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Work around JRuby buffering the request inside #accept
This commit is contained in:
parent
4c2f6b452a
commit
70bbef66cf
4 changed files with 76 additions and 4 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
class IO
|
||||||
|
module WaitReadable
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
module Puma
|
module Puma
|
||||||
class Client
|
class Client
|
||||||
include Puma::Const
|
include Puma::Const
|
||||||
|
@ -17,10 +22,16 @@ module Puma
|
||||||
@buffer = nil
|
@buffer = nil
|
||||||
|
|
||||||
@timeout_at = nil
|
@timeout_at = nil
|
||||||
|
|
||||||
|
@requests_served = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :env, :to_io, :body, :io, :timeout_at, :ready
|
attr_reader :env, :to_io, :body, :io, :timeout_at, :ready
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
"#<Puma::Client:0x#{object_id.to_s(16)} @ready=#{@ready.inspect}>"
|
||||||
|
end
|
||||||
|
|
||||||
def set_timeout(val)
|
def set_timeout(val)
|
||||||
@timeout_at = Time.now + val
|
@timeout_at = Time.now + val
|
||||||
end
|
end
|
||||||
|
@ -65,6 +76,7 @@ module Puma
|
||||||
unless cl
|
unless cl
|
||||||
@buffer = body.empty? ? nil : body
|
@buffer = body.empty? ? nil : body
|
||||||
@body = EmptyBody
|
@body = EmptyBody
|
||||||
|
@requests_served += 1
|
||||||
@ready = true
|
@ready = true
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -74,6 +86,7 @@ module Puma
|
||||||
if remain <= 0
|
if remain <= 0
|
||||||
@body = StringIO.new(body)
|
@body = StringIO.new(body)
|
||||||
@buffer = nil
|
@buffer = nil
|
||||||
|
@requests_served += 1
|
||||||
@ready = true
|
@ready = true
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -119,8 +132,43 @@ module Puma
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def jruby_start_try_to_finish
|
||||||
|
return read_body unless @read_header
|
||||||
|
|
||||||
|
begin
|
||||||
|
data = @io.sysread_nonblock(CHUNK_SIZE)
|
||||||
|
rescue OpenSSL::SSL::SSLError => e
|
||||||
|
return false if e.kind_of? IO::WaitReadable
|
||||||
|
raise e
|
||||||
|
end
|
||||||
|
|
||||||
|
if @buffer
|
||||||
|
@buffer << data
|
||||||
|
else
|
||||||
|
@buffer = data
|
||||||
|
end
|
||||||
|
|
||||||
|
@parsed_bytes = @parser.execute(@env, @buffer, @parsed_bytes)
|
||||||
|
|
||||||
|
if @parser.finished?
|
||||||
|
return setup_body
|
||||||
|
elsif @parsed_bytes >= MAX_HEADER
|
||||||
|
raise HttpParserError,
|
||||||
|
"HEADER is longer than allowed, aborting client early."
|
||||||
|
end
|
||||||
|
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def eagerly_finish
|
def eagerly_finish
|
||||||
return true if @ready
|
return true if @ready
|
||||||
|
|
||||||
|
if defined?(JRUBY_VERSION) and
|
||||||
|
defined?(OpenSSL::SSL::SSLSocket) and
|
||||||
|
@io.kind_of? OpenSSL::SSL::SSLSocket
|
||||||
|
return true if jruby_start_try_to_finish
|
||||||
|
end
|
||||||
|
|
||||||
return false unless IO.select([@to_io], nil, nil, 0)
|
return false unless IO.select([@to_io], nil, nil, 0)
|
||||||
try_to_finish
|
try_to_finish
|
||||||
end
|
end
|
||||||
|
@ -142,6 +190,7 @@ module Puma
|
||||||
unless chunk
|
unless chunk
|
||||||
@body.close
|
@body.close
|
||||||
@buffer = nil
|
@buffer = nil
|
||||||
|
@requests_served += 1
|
||||||
@ready = true
|
@ready = true
|
||||||
raise EOFError
|
raise EOFError
|
||||||
end
|
end
|
||||||
|
@ -151,6 +200,7 @@ module Puma
|
||||||
if remain <= 0
|
if remain <= 0
|
||||||
@body.rewind
|
@body.rewind
|
||||||
@buffer = nil
|
@buffer = nil
|
||||||
|
@requests_served += 1
|
||||||
@ready = true
|
@ready = true
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,6 +31,10 @@ module Puma
|
||||||
# session.
|
# session.
|
||||||
PERSISTENT_TIMEOUT = 20
|
PERSISTENT_TIMEOUT = 20
|
||||||
|
|
||||||
|
# The default number of seconds to wait until we get the first data
|
||||||
|
# for the request
|
||||||
|
FIRST_DATA_TIMEOUT = 30
|
||||||
|
|
||||||
DATE = "Date".freeze
|
DATE = "Date".freeze
|
||||||
|
|
||||||
SCRIPT_NAME = "SCRIPT_NAME".freeze
|
SCRIPT_NAME = "SCRIPT_NAME".freeze
|
||||||
|
|
|
@ -46,11 +46,19 @@ module Puma
|
||||||
c.close
|
c.close
|
||||||
sockets.delete c
|
sockets.delete c
|
||||||
|
|
||||||
|
if c.timeout_at
|
||||||
|
@timeouts.delete c
|
||||||
|
end
|
||||||
|
|
||||||
@events.parse_error @server, c.env, e
|
@events.parse_error @server, c.env, e
|
||||||
|
|
||||||
rescue EOFError
|
rescue EOFError => e
|
||||||
c.close
|
c.close
|
||||||
sockets.delete c
|
sockets.delete c
|
||||||
|
|
||||||
|
if c.timeout_at
|
||||||
|
@timeouts.delete c
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -73,7 +81,15 @@ module Puma
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_in_thread
|
def run_in_thread
|
||||||
@thread = Thread.new { run }
|
@thread = Thread.new {
|
||||||
|
begin
|
||||||
|
run
|
||||||
|
rescue Exception => e
|
||||||
|
puts "MAJOR ERROR DETECTED"
|
||||||
|
p e
|
||||||
|
puts e.backtrace
|
||||||
|
end
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def calculate_sleep
|
def calculate_sleep
|
||||||
|
|
|
@ -56,6 +56,8 @@ module Puma
|
||||||
@persistent_timeout = PERSISTENT_TIMEOUT
|
@persistent_timeout = PERSISTENT_TIMEOUT
|
||||||
@persistent_check, @persistent_wakeup = IO.pipe
|
@persistent_check, @persistent_wakeup = IO.pipe
|
||||||
|
|
||||||
|
@first_data_timeout = FIRST_DATA_TIMEOUT
|
||||||
|
|
||||||
@unix_paths = []
|
@unix_paths = []
|
||||||
|
|
||||||
@proto_env = {
|
@proto_env = {
|
||||||
|
@ -199,7 +201,6 @@ module Puma
|
||||||
@status = :run
|
@status = :run
|
||||||
|
|
||||||
@thread_pool = ThreadPool.new(@min_threads, @max_threads) do |client|
|
@thread_pool = ThreadPool.new(@min_threads, @max_threads) do |client|
|
||||||
|
|
||||||
process_now = false
|
process_now = false
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -213,6 +214,7 @@ module Puma
|
||||||
if process_now
|
if process_now
|
||||||
process_client client
|
process_client client
|
||||||
else
|
else
|
||||||
|
client.set_timeout @first_data_timeout
|
||||||
@reactor.add client
|
@reactor.add client
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -315,7 +317,7 @@ module Puma
|
||||||
end
|
end
|
||||||
|
|
||||||
# The client disconnected while we were reading data
|
# The client disconnected while we were reading data
|
||||||
rescue EOFError, SystemCallError
|
rescue EOFError, SystemCallError => e
|
||||||
# Swallow them. The ensure tries to close +client+ down
|
# Swallow them. The ensure tries to close +client+ down
|
||||||
|
|
||||||
# The client doesn't know HTTP well
|
# The client doesn't know HTTP well
|
||||||
|
|
Loading…
Reference in a new issue