summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-12-03 01:12:08 +0000
committerEric Wong <normalperson@yhbt.net>2010-12-03 01:12:08 +0000
commitc096e735efea5050b0559748633403f0387ea3b3 (patch)
treed0dac89e2fd29069da04096bf7f70288c6377eb4
parent64889d9136fa5466269232c26a2f235dd763d8f0 (diff)
All synchronous models have this fixed in unicorn 3.0.1,
so only Rev and EventMachine-based concurrency models
require code changes.
-rw-r--r--lib/rainbows/ev_core.rb16
-rw-r--r--lib/rainbows/rev/client.rb10
-rwxr-xr-xt/t0106-rack-input-keepalive.sh72
-rw-r--r--t/test_isolate.rb2
4 files changed, 93 insertions, 7 deletions
diff --git a/lib/rainbows/ev_core.rb b/lib/rainbows/ev_core.rb
index e1f5918..8241584 100644
--- a/lib/rainbows/ev_core.rb
+++ b/lib/rainbows/ev_core.rb
@@ -26,6 +26,9 @@ module Rainbows::EvCore
     @state = :close
   end
 
+  def want_more
+  end
+
   def handle_error(e)
     msg = Rainbows::Error.response(e) and write(msg)
     ensure
@@ -62,7 +65,7 @@ module Rainbows::EvCore
     case @state
     when :headers
       @buf << data
-      @hp.parse or return
+      @hp.parse or return want_more
       @state = :body
       if 0 == @hp.content_length
         @input = NULL_IO
@@ -72,8 +75,13 @@ module Rainbows::EvCore
       end
     when :body
       if @hp.body_eof?
-        @state = :trailers
-        on_read(data)
+        if @hp.content_length
+          @input.rewind
+          app_call
+        else
+          @state = :trailers
+          on_read(data)
+        end
       elsif data.size > 0
         @hp.filter_body(@buf2, @buf << data)
         @input << @buf2
@@ -83,6 +91,8 @@ module Rainbows::EvCore
       if @hp.trailers(@env, @buf << data)
         @input.rewind
         app_call
+      else
+        want_more
       end
     end
     rescue => e
diff --git a/lib/rainbows/rev/client.rb b/lib/rainbows/rev/client.rb
index bc85fbd..296a33d 100644
--- a/lib/rainbows/rev/client.rb
+++ b/lib/rainbows/rev/client.rb
@@ -16,6 +16,10 @@ module Rainbows
         @deferred = nil
       end
 
+      def want_more
+        enable unless enabled?
+      end
+
       def quit
         super
         close if @deferred.nil? && @_write_buffer.empty?
@@ -143,13 +147,13 @@ module Rainbows
         when :close
           close if @_write_buffer.empty?
         when :headers
-          if @hp.parse
-            app_call
-          else
+          if @buf.empty?
             unless enabled?
               enable
               KATO[self] = Time.now
             end
+          else
+            on_read("")
           end
         end
         rescue => e
diff --git a/t/t0106-rack-input-keepalive.sh b/t/t0106-rack-input-keepalive.sh
new file mode 100755
index 0000000..c4a531d
--- /dev/null
+++ b/t/t0106-rack-input-keepalive.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+. ./test-lib.sh
+t_plan 7 "rack.input pipelining test"
+
+t_begin "setup and startup" && {
+        rainbows_setup $model
+        rtmpfiles req
+        rainbows -D sha1.ru -c $unicorn_config
+        body=hello
+        body_size=$(printf $body | wc -c)
+        body_sha1=$(printf $body | rsha1)
+        rainbows_wait_start
+}
+
+t_begin "send pipelined identity requests" && {
+
+        {
+                printf 'PUT / HTTP/1.0\r\n'
+                printf 'Connection: keep-alive\r\n'
+                printf 'Content-Length: %d\r\n\r\n%s' $body_size $body
+                printf 'PUT / HTTP/1.1\r\nHost: example.com\r\n'
+                printf 'Content-Length: %d\r\n\r\n%s' $body_size $body
+                printf 'PUT / HTTP/1.0\r\n'
+                printf 'Content-Length: %d\r\n\r\n%s' $body_size $body
+        } > $req
+        (
+                cat $fifo > $tmp &
+                cat $req
+                wait
+                echo ok > $ok
+        ) | socat - TCP4:$listen > $fifo
+        test x"$(cat $ok)" = xok
+}
+
+t_begin "check responses" && {
+        dbgcat tmp
+        test 3 -eq $(grep $body_sha1 $tmp | wc -l)
+}
+
+t_begin "send pipelined chunked requests" && {
+
+        {
+                printf 'PUT / HTTP/1.0\r\n'
+                printf 'Connection: keep-alive\r\n'
+                printf 'Transfer-Encoding: chunked\r\n\r\n'
+                printf '%x\r\n%s\r\n0\r\n\r\n' $body_size $body
+                printf 'PUT / HTTP/1.1\r\nHost: example.com\r\n'
+                printf 'Transfer-Encoding: chunked\r\n\r\n'
+                printf '%x\r\n%s\r\n0\r\n\r\n' $body_size $body
+                printf 'PUT / HTTP/1.0\r\n'
+                printf 'Transfer-Encoding: chunked\r\n\r\n'
+                printf '%x\r\n%s\r\n0\r\n\r\n' $body_size $body
+        } > $req
+        (
+                cat $fifo > $tmp &
+                cat $req
+                wait
+                echo ok > $ok
+        ) | socat - TCP4:$listen > $fifo
+        test x"$(cat $ok)" = xok
+}
+
+t_begin "check responses" && {
+        dbgcat tmp
+        test 3 -eq $(grep $body_sha1 $tmp | wc -l)
+}
+
+t_begin "kill server" && kill $rainbows_pid
+
+t_begin "no errors in stderr log" && check_stderr
+
+t_done
diff --git a/t/test_isolate.rb b/t/test_isolate.rb
index 5c7f21d..9c685f8 100644
--- a/t/test_isolate.rb
+++ b/t/test_isolate.rb
@@ -16,7 +16,7 @@ $stdout.reopen($stderr)
 Isolate.now!(opts) do
   gem 'rack', '1.1.0' # Cramp currently requires ~> 1.1.0
   gem 'kgio', '2.0.0'
-  gem 'unicorn', '3.0.0'
+  gem 'unicorn', '3.0.1'
   gem 'kcar', '0.1.1'
 
   if engine == "ruby"