1 # -*- encoding: binary -*-
2 require 'rainbows/ev_core'
6 class Client < ::Rev::IO
7 include Rainbows::EvCore
14 @deferred_bodies = [] # for (fast) regular files only
17 # queued, optional response bodies, it should only be unpollable "fast"
18 # devices where read(2) is uninterruptable. Unfortunately, NFS and ilk
19 # are also part of this. We'll also stick DeferredResponse bodies in
20 # here to prevent connections from being closed on us.
21 def defer_body(io, out_headers)
22 @deferred_bodies << io
23 schedule_write unless out_headers # triggers a write
27 @_write_buffer.empty? && @deferred_bodies.empty? and close.nil?
33 @env[RACK_INPUT] = @input
34 @env[REMOTE_ADDR] = @remote_addr
35 response = APP.call(@env.update(RACK_DEFAULTS))
36 alive = @hp.keepalive? && G.alive
37 out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if @hp.headers?
39 DeferredResponse.write(self, response, out)
44 # keepalive requests are always body-less, so @input is unchanged
45 @hp.headers(@env, @buf) and next
55 if body = @deferred_bodies[0]
56 return if DeferredResponse === body
59 write(body.sysread(CHUNK_SIZE))
60 rescue EOFError # expected at file EOF
61 @deferred_bodies.shift
63 close if :close == @state && @deferred_bodies.empty?
69 close if :close == @state