about summary refs log tree commit homepage
path: root/test/unit/test_tee_input.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/test_tee_input.rb')
-rw-r--r--test/unit/test_tee_input.rb117
1 files changed, 78 insertions, 39 deletions
diff --git a/test/unit/test_tee_input.rb b/test/unit/test_tee_input.rb
index a127882..96eb268 100644
--- a/test/unit/test_tee_input.rb
+++ b/test/unit/test_tee_input.rb
@@ -4,12 +4,15 @@ require 'test/unit'
 require 'digest/sha1'
 require 'unicorn'
 
+class TeeInput < Unicorn::TeeInput
+  attr_accessor :tmp, :len
+end
+
 class TestTeeInput < Test::Unit::TestCase
 
   def setup
     @rs = $/
-    @env = {}
-    @rd, @wr = IO.pipe
+    @rd, @wr = Kgio::UNIXSocket.pair
     @rd.sync = @wr.sync = true
     @start_pid = $$
   end
@@ -27,8 +30,8 @@ class TestTeeInput < Test::Unit::TestCase
   end
 
   def test_gets_long
-    init_parser("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size)
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    r = init_request("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size)
+    ti = TeeInput.new(@rd, r)
     status = line = nil
     pid = fork {
       @rd.close
@@ -48,8 +51,8 @@ class TestTeeInput < Test::Unit::TestCase
   end
 
   def test_gets_short
-    init_parser("hello", 5 + "#$/foo".size)
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    r = init_request("hello", 5 + "#$/foo".size)
+    ti = TeeInput.new(@rd, r)
     status = line = nil
     pid = fork {
       @rd.close
@@ -67,8 +70,8 @@ class TestTeeInput < Test::Unit::TestCase
   end
 
   def test_small_body
-    init_parser('hello')
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    r = init_request('hello')
+    ti = TeeInput.new(@rd, r)
     assert_equal 0, @parser.content_length
     assert @parser.body_eof?
     assert_equal StringIO, ti.tmp.class
@@ -77,11 +80,12 @@ class TestTeeInput < Test::Unit::TestCase
     assert_equal 'hello', ti.read
     assert_equal '', ti.read
     assert_nil ti.read(4096)
+    assert_equal 5, ti.size
   end
 
   def test_read_with_buffer
-    init_parser('hello')
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    r = init_request('hello')
+    ti = TeeInput.new(@rd, r)
     buf = ''
     rv = ti.read(4, buf)
     assert_equal 'hell', rv
@@ -95,8 +99,8 @@ class TestTeeInput < Test::Unit::TestCase
   end
 
   def test_big_body
-    init_parser('.' * Unicorn::Const::MAX_BODY << 'a')
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    r = init_request('.' * Unicorn::Const::MAX_BODY << 'a')
+    ti = TeeInput.new(@rd, r)
     assert_equal 0, @parser.content_length
     assert @parser.body_eof?
     assert_kind_of File, ti.tmp
@@ -106,9 +110,9 @@ class TestTeeInput < Test::Unit::TestCase
 
   def test_read_in_full_if_content_length
     a, b = 300, 3
-    init_parser('.' * b, 300)
+    r = init_request('.' * b, 300)
     assert_equal 300, @parser.content_length
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    ti = TeeInput.new(@rd, r)
     pid = fork {
       @wr.write('.' * 197)
       sleep 1 # still a *potential* race here that would make the test moot...
@@ -121,13 +125,12 @@ class TestTeeInput < Test::Unit::TestCase
   end
 
   def test_big_body_multi
-    init_parser('.', Unicorn::Const::MAX_BODY + 1)
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    r = init_request('.', Unicorn::Const::MAX_BODY + 1)
+    ti = TeeInput.new(@rd, r)
     assert_equal Unicorn::Const::MAX_BODY, @parser.content_length
     assert ! @parser.body_eof?
     assert_kind_of File, ti.tmp
     assert_equal 0, ti.tmp.pos
-    assert_equal 1, ti.tmp.size
     assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
     nr = Unicorn::Const::MAX_BODY / 4
     pid = fork {
@@ -138,8 +141,8 @@ class TestTeeInput < Test::Unit::TestCase
     @wr.close
     assert_equal '.', ti.read(1)
     assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
-    nr.times {
-      assert_equal '....', ti.read(4)
+    nr.times { |x|
+      assert_equal '....', ti.read(4), "nr=#{x}"
       assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
     }
     assert_nil ti.read(1)
@@ -150,12 +153,12 @@ class TestTeeInput < Test::Unit::TestCase
 
   def test_chunked
     @parser = Unicorn::HttpParser.new
-    @buf = "POST / HTTP/1.1\r\n" \
-           "Host: localhost\r\n" \
-           "Transfer-Encoding: chunked\r\n" \
-           "\r\n"
-    assert_equal @env, @parser.headers(@env, @buf)
-    assert_equal "", @buf
+    @parser.buf << "POST / HTTP/1.1\r\n" \
+                   "Host: localhost\r\n" \
+                   "Transfer-Encoding: chunked\r\n" \
+                   "\r\n"
+    assert @parser.parse
+    assert_equal "", @parser.buf
 
     pid = fork {
       @rd.close
@@ -163,7 +166,7 @@ class TestTeeInput < Test::Unit::TestCase
       @wr.write("0\r\n\r\n")
     }
     @wr.close
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    ti = TeeInput.new(@rd, @parser)
     assert_nil @parser.content_length
     assert_nil ti.len
     assert ! @parser.body_eof?
@@ -185,12 +188,13 @@ class TestTeeInput < Test::Unit::TestCase
 
   def test_chunked_ping_pong
     @parser = Unicorn::HttpParser.new
-    @buf = "POST / HTTP/1.1\r\n" \
+    buf = @parser.buf
+    buf << "POST / HTTP/1.1\r\n" \
            "Host: localhost\r\n" \
            "Transfer-Encoding: chunked\r\n" \
            "\r\n"
-    assert_equal @env, @parser.headers(@env, @buf)
-    assert_equal "", @buf
+    assert @parser.parse
+    assert_equal "", buf
     chunks = %w(aa bbb cccc dddd eeee)
     rd, wr = IO.pipe
 
@@ -201,7 +205,7 @@ class TestTeeInput < Test::Unit::TestCase
       end
       @wr.write("0\r\n\r\n")
     }
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    ti = TeeInput.new(@rd, @parser)
     assert_nil @parser.content_length
     assert_nil ti.len
     assert ! @parser.body_eof?
@@ -215,13 +219,14 @@ class TestTeeInput < Test::Unit::TestCase
 
   def test_chunked_with_trailer
     @parser = Unicorn::HttpParser.new
-    @buf = "POST / HTTP/1.1\r\n" \
+    buf = @parser.buf
+    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
+    assert @parser.parse
+    assert_equal "", buf
 
     pid = fork {
       @rd.close
@@ -230,28 +235,62 @@ class TestTeeInput < Test::Unit::TestCase
       @wr.write("Hello: World\r\n\r\n")
     }
     @wr.close
-    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    ti = TeeInput.new(@rd, @parser)
     assert_nil @parser.content_length
     assert_nil ti.len
     assert ! @parser.body_eof?
     assert_equal 25, ti.size
-    assert_equal "World", @env['HTTP_HELLO']
+    assert_equal "World", @parser.env['HTTP_HELLO']
     status = nil
     assert_nothing_raised { pid, status = Process.waitpid2(pid) }
     assert status.success?
   end
 
+  def test_chunked_and_size_slow
+    @parser = Unicorn::HttpParser.new
+    buf = @parser.buf
+    buf << "POST / HTTP/1.1\r\n" \
+           "Host: localhost\r\n" \
+           "Trailer: Hello\r\n" \
+           "Transfer-Encoding: chunked\r\n" \
+           "\r\n"
+    assert @parser.parse
+    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", @parser.env['HTTP_HELLO']
+  end
+
+  def test_gets_read_mix
+    r = init_request("hello\nasdfasdf")
+    ti = Unicorn::TeeInput.new(@rd, r)
+    assert_equal "hello\n", ti.gets
+    assert_equal "asdfasdf", ti.read(9)
+    assert_nil ti.read(9)
+  end
+
 private
 
-  def init_parser(body, size = nil)
+  def init_request(body, size = nil)
     @parser = Unicorn::HttpParser.new
     body = body.to_s.freeze
-    @buf = "POST / HTTP/1.1\r\n" \
+    buf = @parser.buf
+    buf << "POST / HTTP/1.1\r\n" \
            "Host: localhost\r\n" \
            "Content-Length: #{size || body.size}\r\n" \
            "\r\n#{body}"
-    assert_equal @env, @parser.headers(@env, @buf)
-    assert_equal body, @buf
+    assert @parser.parse
+    assert_equal body, buf
+    @buf = buf
+    @parser
   end
 
 end