hijacking support for Rack 1.5.x users
[rainbows.git] / lib / rainbows / writer_thread_pool / client.rb
blobe02d6a86f54c6039d3f650ad48bc04b627b30c21
1 # -*- encoding: binary -*-
2 # :enddoc:
3 # used to wrap a BasicSocket to use with +q+ for all writes
4 # this is compatible with IO.select
5 class Rainbows::WriterThreadPool::Client < Struct.new(:to_io, :q)
6   include Rainbows::SocketProxy
7   include Rainbows::ProcessClient
9   module Methods
10     def write_body_each(body)
11       return if @hp.hijacked?
12       q << [ to_io, :write_body_each, body ]
13     end
15     def write_response_close(status, headers, body, alive)
16       to_io.instance_variable_set(:@hp, @hp) # XXX ugh
17       return if @hp.hijacked?
18       Rainbows::SyncClose.new(body) { |sync_body|
19         q << [ to_io, :write_response, status, headers, sync_body, alive ]
20       }
21     end
23     if Rainbows::Response::COPY_STREAM || IO.method_defined?(:trysendfile)
24       def write_response(status, headers, body, alive)
25         if body.respond_to?(:close)
26           write_response_close(status, headers, body, alive)
27         elsif body.respond_to?(:to_path)
28           write_response_path(status, headers, body, alive)
29         else
30           super
31         end
32       end
34       def write_body_file(body, range)
35         q << [ to_io, :write_body_file, body, range ]
36       end
38       def write_body_stream(body)
39         q << [ to_io, :write_body_stream, body ]
40       end
41     else # each-only body response
42       def write_response(status, headers, body, alive)
43         if body.respond_to?(:close)
44           write_response_close(status, headers, body, alive)
45         else
46           super
47         end
48       end
49     end # each-only body response
50   end # module Methods
51   include Methods
53   def write(buf)
54     q << [ to_io, buf ]
55   end
57   def close
58     q << [ to_io, :close ]
59   end
61   def closed?
62     to_io.closed?
63   end
64 end