1 # -*- encoding: binary -*-
3 # TODO: handle large responses without having it all in memory
4 module Rainbows::ReverseProxy::Coolio
5 LOOP = Cool.io::Loop.default
7 class Backend < Cool.io::IO
8 include Rainbows::ReverseProxy::EvClient
10 def initialize(env, addr, input)
14 @parser = Kcar::Parser.new
15 @response = @body = nil
16 @headers = Rack::Utils::HeaderHash.new
17 super(UpstreamSocket.start(addr)) # kgio-enabled socket
22 buf = @input.read(16384, @junk) and return write(buf)
28 # avoiding IO#read_nonblock since that's expensive in 1.9.2
29 case buf = @_io.kgio_tryread(16384, @junk)
35 @env[AsyncCallback].call(@response)
37 end while true # we always read until EAGAIN or EOF
41 when Errno::ECONNRESET
42 @env[AsyncCallback].call(@response)
46 Unicorn.log_error(@env["rack.logger"], "on_readable", e)
48 @env[AsyncCallback].call(Rainbows::ReverseProxy::E502)
54 input = prepare_input!(env)
55 sock = Backend.new(env, pick_upstream(env), input).attach(LOOP)
56 sock.write(build_headers(env, input))