about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-11-13 16:41:10 +0800
committerEric Wong <normalperson@yhbt.net>2010-11-13 16:41:10 +0800
commit17a734a9f6ccea8c969a574f09b5d8dd3d568a9c (patch)
tree30c3b8cccaa7b4807d105feebf6766166ad8e6b8
parent855c02a9720a17854a2f1c715efbe502cdba54e2 (diff)
downloadunicorn-17a734a9f6ccea8c969a574f09b5d8dd3d568a9c.tar.gz
It's possible for an application to call size after it has read
a few bytes/lines, so do not screw up a user's read offset when
consuming input.
-rw-r--r--lib/unicorn/tee_input.rb3
-rw-r--r--test/unit/test_tee_input.rb22
2 files changed, 24 insertions, 1 deletions
diff --git a/lib/unicorn/tee_input.rb b/lib/unicorn/tee_input.rb
index 0e937ff..ee3effd 100644
--- a/lib/unicorn/tee_input.rb
+++ b/lib/unicorn/tee_input.rb
@@ -43,8 +43,9 @@ class Unicorn::TeeInput < Unicorn::StreamInput
   # specified +length+ in a loop until it returns +nil+.
   def size
     @len and return @len
+    pos = @bytes_read
     consume!
-    @tmp.rewind
+    @tmp.pos = pos
     @len = @bytes_read
   end
 
diff --git a/test/unit/test_tee_input.rb b/test/unit/test_tee_input.rb
index b44f609..e69c8f1 100644
--- a/test/unit/test_tee_input.rb
+++ b/test/unit/test_tee_input.rb
@@ -245,6 +245,28 @@ class TestTeeInput < Test::Unit::TestCase
     assert status.success?
   end
 
+  def test_chunked_and_size_slow
+    @parser = Unicorn::HttpParser.new
+    @buf = "POST / HTTP/1.1\r\n" \
+           "Host: localhost\r\n" \
+           "Trailer: Hello\r\n" \
+           "Transfer-Encoding: chunked\r\n" \
+           "\r\n"
+    assert_equal @env, @parser.headers(@env, @buf)
+    assert_equal "", @buf
+
+    @wr.write("9\r\nabcde")
+    ti = TeeInput.new(@rd, @parser)
+    assert_nil @parser.content_length
+    assert_equal "abcde", ti.read(9)
+    assert ! @parser.body_eof?
+    @wr.write("fghi\r\n0\r\nHello: World\r\n\r\n")
+    assert_equal 9, ti.size
+    assert_equal "fghi", ti.read(9)
+    assert_equal nil, ti.read(9)
+    assert_equal "World", @env['HTTP_HELLO']
+  end
+
 private
 
   def init_request(body, size = nil)