about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-10-17 22:42:56 -0700
committerEric Wong <normalperson@yhbt.net>2009-10-17 22:42:56 -0700
commit0719c5a7ac09078c810507244a86ba44623757c4 (patch)
tree1ef6b171c24292fed0336459d78a30900b74359c /lib
parentb4d479681c257d91c7784a6698264719632be374 (diff)
downloadrainbows-0719c5a7ac09078c810507244a86ba44623757c4.tar.gz
Handling HTTP pipelining through recursion is not good since
several hundred kilobytes worth of GET/HEAD requests can be a
LOT of GET/HEAD requests...
Diffstat (limited to 'lib')
-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