diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/unicorn.rb | 6 | ||||
-rw-r--r-- | lib/unicorn/tee_input.rb | 11 |
2 files changed, 17 insertions, 0 deletions
diff --git a/lib/unicorn.rb b/lib/unicorn.rb index a696402..c6c311e 100644 --- a/lib/unicorn.rb +++ b/lib/unicorn.rb @@ -8,6 +8,12 @@ autoload :Rack, 'rack' # a Unicorn web server. It contains a minimalist HTTP server with just enough # functionality to service web application requests fast as possible. module Unicorn + + # raise this inside TeeInput when a client disconnects inside the + # application dispatch + class ClientShutdown < EOFError + end + autoload :Const, 'unicorn/const' autoload :HttpRequest, 'unicorn/http_request' autoload :HttpResponse, 'unicorn/http_response' diff --git a/lib/unicorn/tee_input.rb b/lib/unicorn/tee_input.rb index 69397c0..50ddb5b 100644 --- a/lib/unicorn/tee_input.rb +++ b/lib/unicorn/tee_input.rb @@ -135,10 +135,21 @@ module Unicorn end end finalize_input + rescue EOFError + # in case client only did a premature shutdown(SHUT_WR) + # we do support clients that shutdown(SHUT_WR) after the + # _entire_ request has been sent, and those will not have + # raised EOFError on us. + socket.close if socket + raise ClientShutdown, "bytes_read=#{@tmp.size}", [] end def finalize_input while parser.trailers(req, buf).nil? + # Don't worry about throw-ing :http_499 here on EOFError, tee() + # will catch EOFError when app is processing it, otherwise in + # initialize we never get any chance to enter the app so the + # EOFError will just get trapped by Unicorn and not the Rack app buf << socket.readpartial(Const::CHUNK_SIZE) end self.socket = nil |