about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/rainbows/rev.rb34
1 files changed, 19 insertions, 15 deletions
diff --git a/lib/rainbows/rev.rb b/lib/rainbows/rev.rb
index cb0dd31..19e721a 100644
--- a/lib/rainbows/rev.rb
+++ b/lib/rainbows/rev.rb
@@ -66,21 +66,25 @@ module Rainbows
       end
 
       def app_call
-        @input.rewind
-        @env[RACK_INPUT] = @input
-        @env[REMOTE_ADDR] = @remote_addr
-        response = G.app.call(@env.update(RACK_DEFAULTS))
-        alive = @hp.keepalive? && G.alive
-        out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if @hp.headers?
-        HttpResponse.write(self, response, out)
-        if alive
-          @env.clear
-          @hp.reset
-          @state = :headers
-          on_read("") # in case next request was fully-buffered
-        else
-          @state = :close
-        end
+        begin
+          (@env[RACK_INPUT] = @input).rewind
+          alive = @hp.keepalive?
+          @env[REMOTE_ADDR] = @remote_addr
+          response = G.app.call(@env.update(RACK_DEFAULTS))
+          alive &&= G.alive
+          out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if @hp.headers?
+          HttpResponse.write(self, response, out)
+          if alive
+            @env.clear
+            @hp.reset
+            @state = :headers
+            # keepalive requests are always body-less, so @input is unchanged
+            @hp.headers(@env, @buf) and next
+          else
+            @state = :close
+          end
+          return
+        end while true
       end
 
       def on_write_complete