about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-05-03 22:10:54 +0000
committerEric Wong <normalperson@yhbt.net>2009-05-03 22:10:54 +0000
commita5c51c33862580674c997be91dc705c2cf000a36 (patch)
treec753cc06a095988bd75d84f4a93b7ccc870cb143
parent80079f0d94498c87293b79376935645ee13b0972 (diff)
downloadunicorn-a5c51c33862580674c997be91dc705c2cf000a36.tar.gz
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)
-rw-r--r--lib/unicorn/http_request.rb17
-rw-r--r--test/unit/test_request.rb4
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))