event_machine: factor out async.callback handling
[rainbows.git] / lib / rainbows / event_machine / response.rb
blob49bcbd521251f7231775e96d6a879693744edfa8
1 # -*- encoding: binary -*-
2 # :enddoc:
3 module Rainbows::EventMachine::Response
4   def write_response(status, headers, body, alive)
5     if body.respond_to?(:errback) && body.respond_to?(:callback)
6       @body = body
7       body.callback { quit }
8       body.errback { quit }
9       alive = true
10     elsif body.respond_to?(:to_path)
11       st = File.stat(path = body.to_path)
13       if st.file?
14         write_headers(status, headers, alive)
15         @body = stream_file_data(path)
16         @body.errback do
17           body.close if body.respond_to?(:close)
18           quit
19         end
20         @body.callback do
21           body.close if body.respond_to?(:close)
22           @body = nil
23           alive ? receive_data(nil) : quit
24         end
25         return
26       elsif st.socket? || st.pipe?
27         io = body_to_io(@body = body)
28         chunk = stream_response_headers(status, headers, alive)
29         m = chunk ? Rainbows::EventMachine::ResponseChunkPipe :
30                     Rainbows::EventMachine::ResponsePipe
31         return EM.watch(io, m, self).notify_readable = true
32       end
33       # char or block device... WTF? fall through to body.each
34     end
35     super(status, headers, body, alive)
36     quit unless alive
37   end
38 end