about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-06-29 18:01:41 -0700
committerEric Wong <normalperson@yhbt.net>2009-06-29 18:17:36 -0700
commit41f6f65a6cb7152b5181704373d7da62704a62e8 (patch)
tree7ca9dd0d8618e11e42ca591b96d8b4f1d3f7942a
parent4f05fb1a3b44f8eab1a9dda26d5b115f33a149cd (diff)
downloadunicorn-41f6f65a6cb7152b5181704373d7da62704a62e8.tar.gz
This won't be heavily used enough to make preallocation worth
the effort.  While we're at it, don't enforce policy by forcing
the readpartial buffer to be Encoding::BINARY (even though it
/should/ be :), it's up to the user of the interface to decide.
-rw-r--r--lib/unicorn/chunked_reader.rb13
-rw-r--r--lib/unicorn/http_request.rb3
-rw-r--r--test/unit/test_chunked_reader.rb64
3 files changed, 38 insertions, 42 deletions
diff --git a/lib/unicorn/chunked_reader.rb b/lib/unicorn/chunked_reader.rb
index 41193d0..40d421d 100644
--- a/lib/unicorn/chunked_reader.rb
+++ b/lib/unicorn/chunked_reader.rb
@@ -6,22 +6,13 @@ module Unicorn; end
 module Unicorn
   class ChunkedReader
 
-    def initialize
-      @input = @buf = nil
-      @chunk_left = 0
-    end
-
-    def reopen(input, buf)
-      buf ||= Z.dup
-      buf.force_encoding(Encoding::BINARY) if buf.respond_to?(:force_encoding)
+    def initialize(input, buf)
       @input, @buf = input, buf
+      @chunk_left = 0
       parse_chunk_header
-      self
     end
 
     def readpartial(max, buf = Z.dup)
-      buf.force_encoding(Encoding::BINARY) if buf.respond_to?(:force_encoding)
-
       while @input && @chunk_left <= 0 && ! parse_chunk_header
         @buf << @input.readpartial(Const::CHUNK_SIZE, buf)
       end
diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb
index b1cd8ed..b2c72f3 100644
--- a/lib/unicorn/http_request.rb
+++ b/lib/unicorn/http_request.rb
@@ -22,7 +22,6 @@ module Unicorn
     }
 
     NULL_IO = StringIO.new(Z)
-    DECHUNKER = ChunkedReader.new
     LOCALHOST = '127.0.0.1'.freeze
 
     # Being explicitly single-threaded, we have certain advantages in
@@ -93,7 +92,7 @@ module Unicorn
 
         if te = PARAMS[Const::HTTP_TRANSFER_ENCODING]
           if /chunked/i =~ te
-            socket = DECHUNKER.reopen(socket, body)
+            socket = ChunkedReader.new(socket, body)
             length = body = nil
           end
         end
diff --git a/test/unit/test_chunked_reader.rb b/test/unit/test_chunked_reader.rb
index d9fc56f..ec5c68a 100644
--- a/test/unit/test_chunked_reader.rb
+++ b/test/unit/test_chunked_reader.rb
@@ -7,7 +7,6 @@ require 'digest/sha1'
 class TestChunkedReader < Test::Unit::TestCase
 
   def setup
-    @cr = Unicorn::ChunkedReader.new
     @rd, @wr = IO.pipe
     @rd.binmode
     @wr.binmode
@@ -22,32 +21,32 @@ class TestChunkedReader < Test::Unit::TestCase
   end
 
   def test_eof1
-    @cr.reopen(@rd, "0\r\n")
-    assert_raises(EOFError) { @cr.readpartial(8192) }
+    cr = bin_reader(@rd, "0\r\n")
+    assert_raises(EOFError) { cr.readpartial(8192) }
   end
 
   def test_eof2
-    @cr.reopen(@rd, "0\r\n\r\n")
-    assert_raises(EOFError) { @cr.readpartial(8192) }
+    cr = bin_reader(@rd, "0\r\n\r\n")
+    assert_raises(EOFError) { cr.readpartial(8192) }
   end
 
   def test_readpartial1
-    @cr.reopen(@rd, "4\r\nasdf\r\n0\r\n")
-    assert_equal 'asdf', @cr.readpartial(8192)
-    assert_raises(EOFError) { @cr.readpartial(8192) }
+    cr = bin_reader(@rd, "4\r\nasdf\r\n0\r\n")
+    assert_equal 'asdf', cr.readpartial(8192)
+    assert_raises(EOFError) { cr.readpartial(8192) }
   end
 
   def test_gets1
-    @cr.reopen(@rd, "4\r\nasdf\r\n0\r\n")
+    cr = bin_reader(@rd, "4\r\nasdf\r\n0\r\n")
     STDOUT.sync = true
-    assert_equal 'asdf', @cr.gets
-    assert_raises(EOFError) { @cr.readpartial(8192) }
+    assert_equal 'asdf', cr.gets
+    assert_raises(EOFError) { cr.readpartial(8192) }
   end
 
   def test_gets2
-    @cr.reopen(@rd, "4\r\nasd\n\r\n0\r\n\r\n")
-    assert_equal "asd\n", @cr.gets
-    assert_nil @cr.gets
+    cr = bin_reader(@rd, "4\r\nasd\n\r\n0\r\n\r\n")
+    assert_equal "asd\n", cr.gets
+    assert_nil cr.gets
   end
 
   def test_gets3
@@ -55,12 +54,12 @@ class TestChunkedReader < Test::Unit::TestCase
     str = ('a' * max).freeze
     first = 5
     last = str.size - first
-    @cr.reopen(@rd,
+    cr = bin_reader(@rd,
       "#{'%x' % first}\r\n#{str[0, first]}\r\n" \
       "#{'%x' % last}\r\n#{str[-last, last]}\r\n" \
       "0\r\n")
-    assert_equal str, @cr.gets
-    assert_nil @cr.gets
+    assert_equal str, cr.gets
+    assert_nil cr.gets
   end
 
   def test_readpartial_gets_mixed1
@@ -68,17 +67,17 @@ class TestChunkedReader < Test::Unit::TestCase
     str = ('a' * max).freeze
     first = 5
     last = str.size - first
-    @cr.reopen(@rd,
+    cr = bin_reader(@rd,
       "#{'%x' % first}\r\n#{str[0, first]}\r\n" \
       "#{'%x' % last}\r\n#{str[-last, last]}\r\n" \
       "0\r\n")
-    partial = @cr.readpartial(16384)
+    partial = cr.readpartial(16384)
     assert String === partial
 
     len = max - partial.size
-    assert_equal(str[-len, len], @cr.gets)
-    assert_raises(EOFError) { @cr.readpartial(1) }
-    assert_nil @cr.gets
+    assert_equal(str[-len, len], cr.gets)
+    assert_raises(EOFError) { cr.readpartial(1) }
+    assert_nil cr.gets
   end
 
   def test_gets_mixed_readpartial
@@ -86,16 +85,16 @@ class TestChunkedReader < Test::Unit::TestCase
     str = ("z\n" * max).freeze
     first = 5
     last = str.size - first
-    @cr.reopen(@rd,
+    cr = bin_reader(@rd,
       "#{'%x' % first}\r\n#{str[0, first]}\r\n" \
       "#{'%x' % last}\r\n#{str[-last, last]}\r\n" \
       "0\r\n")
-    assert_equal("z\n", @cr.gets)
-    assert_equal("z\n", @cr.gets)
+    assert_equal("z\n", cr.gets)
+    assert_equal("z\n", cr.gets)
   end
 
   def test_dd
-    @cr.reopen(@rd, "6\r\nhello\n\r\n")
+    cr = bin_reader(@rd, "6\r\nhello\n\r\n")
     tmp = Tempfile.new('test_dd')
     tmp.sync = true
 
@@ -122,11 +121,11 @@ class TestChunkedReader < Test::Unit::TestCase
         exit 0
       end while true
     }
-    assert_equal "hello\n", @cr.gets
+    assert_equal "hello\n", cr.gets
     sha1 = Digest::SHA1.new
-    buf = ''
+    buf = Unicorn::Z.dup
     begin
-      @cr.readpartial(16384, buf)
+      cr.readpartial(16384, buf)
       sha1.update(buf)
     rescue EOFError
       break
@@ -142,4 +141,11 @@ class TestChunkedReader < Test::Unit::TestCase
     assert_equal sha1_file.hexdigest, sha1.hexdigest
   end
 
+private
+
+  def bin_reader(sock, buf)
+    buf.force_encoding(Encoding::BINARY) if buf.respond_to?(:force_encoding)
+    Unicorn::ChunkedReader.new(sock, buf)
+  end
+
 end