about summary refs log tree commit homepage
path: root/lib/rainbows/event_machine
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-12-27 20:25:39 -0800
committerEric Wong <normalperson@yhbt.net>2010-12-28 17:12:28 -0800
commit3495d59763e6159975debf32728dc53fc41c5ea1 (patch)
tree949415250af66075cc9ca98040a85ddc2ad84380 /lib/rainbows/event_machine
parent53afe0b23fc67c5b25541cddbd68f905c649e756 (diff)
downloadrainbows-3495d59763e6159975debf32728dc53fc41c5ea1.tar.gz
Some middlewares require the Rack env to be preserved all
the way through to close, so we'll ensure all request models
preserve it.

We also need to better response body wrappers/proxies always get
fired properly when returning.  IO.copy_stream and "sendfile"
gem users could hit cases where wrappers did not fire properly.
Diffstat (limited to 'lib/rainbows/event_machine')
-rw-r--r--lib/rainbows/event_machine/client.rb27
-rw-r--r--lib/rainbows/event_machine/response_pipe.rb3
2 files changed, 18 insertions, 12 deletions
diff --git a/lib/rainbows/event_machine/client.rb b/lib/rainbows/event_machine/client.rb
index fab1dbc..49552f3 100644
--- a/lib/rainbows/event_machine/client.rb
+++ b/lib/rainbows/event_machine/client.rb
@@ -16,11 +16,13 @@ class Rainbows::EventMachine::Client < EM::Connection
     # (often a static file), we do not attempt to process another
     # request on the same connection until the first is complete
     if @body
-      @buf << data
-      @_io.shutdown(Socket::SHUT_RD) if @buf.size > 0x1c000
-      EM.next_tick { receive_data('') }
+      if data
+        @buf << data
+        @_io.shutdown(Socket::SHUT_RD) if @buf.size > 0x1c000
+      end
+      EM.next_tick { receive_data(nil) } unless @buf.empty?
     else
-      on_read(data)
+      on_read(data || "") if (@buf.size > 0) || data
     end
   end
 
@@ -43,15 +45,16 @@ class Rainbows::EventMachine::Client < EM::Connection
     # long-running async response
     (response.nil? || -1 == response[0]) and return @state = :close
 
-    alive = @hp.next? && G.alive && G.kato > 0
-    em_write_response(response, alive)
-    if alive
+    if @hp.next? && G.alive && G.kato > 0
       @state = :headers
+      em_write_response(response, true)
       if @buf.empty?
         set_comm_inactivity_timeout(G.kato)
-      else
-        EM.next_tick { receive_data('') }
+      elsif @body.nil?
+        EM.next_tick { receive_data(nil) }
       end
+    else
+      em_write_response(response, false)
     end
   end
 
@@ -84,7 +87,7 @@ class Rainbows::EventMachine::Client < EM::Connection
         @body.callback do
           body.close if body.respond_to?(:close)
           @body = nil
-          alive ? receive_data('') : quit
+          alive ? receive_data(nil) : quit
         end
         return
       elsif st.socket? || st.pipe?
@@ -102,6 +105,10 @@ class Rainbows::EventMachine::Client < EM::Connection
     quit unless alive
   end
 
+  def next!
+    @hp.keepalive? ? receive_data(@body = nil) : quit
+  end
+
   def unbind
     async_close = @env[ASYNC_CLOSE] and async_close.succeed
     @body.respond_to?(:fail) and @body.fail
diff --git a/lib/rainbows/event_machine/response_pipe.rb b/lib/rainbows/event_machine/response_pipe.rb
index 2417dbe..3da2417 100644
--- a/lib/rainbows/event_machine/response_pipe.rb
+++ b/lib/rainbows/event_machine/response_pipe.rb
@@ -22,9 +22,8 @@ module Rainbows::EventMachine::ResponsePipe
   end
 
   def unbind
-    @client.body = nil
-    @alive ? @client.on_read('') : @client.quit
     @body.close if @body.respond_to?(:close)
+    @client.next!
     @io.close unless @io.closed?
   end
 end