From 25c9cf0d8420a971840297d9ca62e7dd9c05b09e Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 7 Jan 2011 17:07:48 -0800 Subject: event_machine: fold write_response back into client No point in having too many modules to search around (for both hackers and the runtime). --- lib/rainbows/event_machine/client.rb | 57 ++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) (limited to 'lib/rainbows/event_machine/client.rb') diff --git a/lib/rainbows/event_machine/client.rb b/lib/rainbows/event_machine/client.rb index ff77d2b..b13d6fb 100644 --- a/lib/rainbows/event_machine/client.rb +++ b/lib/rainbows/event_machine/client.rb @@ -1,10 +1,8 @@ # -*- encoding: binary -*- # :enddoc: -require 'rainbows/event_machine/response' class Rainbows::EventMachine::Client < EM::Connection attr_writer :body include Rainbows::EvCore - include Rainbows::EventMachine::Response def initialize(io) @_io = io @@ -44,7 +42,60 @@ class Rainbows::EventMachine::Client < EM::Connection } (nil == status || -1 == status) or - write_response(status, headers, body, @hp.next?) + ev_write_response(status, headers, body, @hp.next?) + end + + def deferred_errback(orig_body) + @body.errback do + orig_body.close if orig_body.respond_to?(:close) + quit + end + end + + def deferred_callback(orig_body, alive) + @body.callback do + orig_body.close if orig_body.respond_to?(:close) + @body = nil + alive ? receive_data(nil) : quit + end + end + + def ev_write_response(status, headers, body, alive) + @state = :headers if alive + if body.respond_to?(:errback) && body.respond_to?(:callback) + @body = body + deferred_errback(body) + deferred_callback(body, alive) + elsif body.respond_to?(:to_path) + st = File.stat(path = body.to_path) + + if st.file? + write_headers(status, headers, alive) + @body = stream_file_data(path) + deferred_errback(body) + deferred_callback(body, alive) + return + elsif st.socket? || st.pipe? + io = body_to_io(@body = body) + chunk = stream_response_headers(status, headers, alive) + m = chunk ? Rainbows::EventMachine::ResponseChunkPipe : + Rainbows::EventMachine::ResponsePipe + return EM.watch(io, m, self).notify_readable = true + end + # char or block device... WTF? fall through to body.each + end + write_response(status, headers, body, alive) + if alive + if @body.nil? + if @buf.empty? + set_comm_inactivity_timeout(Rainbows.keepalive_timeout) + else + EM.next_tick { receive_data(nil) } + end + end + else + quit unless @body + end end def next! -- cgit v1.2.3-24-ge0c7