From a5c51c33862580674c997be91dc705c2cf000a36 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 3 May 2009 22:10:54 +0000 Subject: http_request: switch to readpartial over sysread readpartial is actually as low-level as sysread is, except it's less likely to throw exceptions and won't change the blocking/non-blocking status of a file descriptor (we explicitly enable blocking I/O) --- lib/unicorn/http_request.rb | 17 ++++------------- test/unit/test_request.rb | 4 +++- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb index a51e029..e786d79 100644 --- a/lib/unicorn/http_request.rb +++ b/lib/unicorn/http_request.rb @@ -76,15 +76,15 @@ module Unicorn TCPSocket === socket ? socket.peeraddr.last : LOCALHOST # short circuit the common case with small GET requests first - PARSER.execute(PARAMS, read_socket(socket)) and + PARSER.execute(PARAMS, socket.readpartial(Const::CHUNK_SIZE, BUFFER)) and return handle_body(socket) - data = BUFFER.dup # read_socket will clobber BUFFER + data = BUFFER.dup # socket.readpartial will clobber BUFFER # Parser is not done, queue up more data to read and continue parsing # an Exception thrown from the PARSER will throw us out of the loop begin - data << read_socket(socket) + data << socket.readpartial(Const::CHUNK_SIZE, BUFFER) PARSER.execute(PARAMS, data) and return handle_body(socket) end while true rescue HttpParserError => e @@ -141,7 +141,7 @@ module Unicorn def read_body(socket, remain, body) while remain > 0 # writes always write the requested amount on a POSIX filesystem - remain -= body.syswrite(read_socket(socket)) + remain -= body.syswrite(socket.readpartial(Const::CHUNK_SIZE, BUFFER)) end rescue Object => e @logger.error "Error reading HTTP body: #{e.inspect}" @@ -153,14 +153,5 @@ module Unicorn raise e end - # read(2) on "slow" devices like sockets can be interrupted by signals - def read_socket(socket) - begin - socket.sysread(Const::CHUNK_SIZE, BUFFER) - rescue Errno::EINTR - retry - end - end - end end diff --git a/test/unit/test_request.rb b/test/unit/test_request.rb index 060da24..a6cb13c 100644 --- a/test/unit/test_request.rb +++ b/test/unit/test_request.rb @@ -14,7 +14,9 @@ include Unicorn class RequestTest < Test::Unit::TestCase - class MockRequest < StringIO; end + class MockRequest < StringIO + alias_method :readpartial, :sysread + end def setup @request = HttpRequest.new(Logger.new($stderr)) -- cgit v1.2.3-24-ge0c7