diff options
Diffstat (limited to 'lib/rainbows/revactor')
-rw-r--r-- | lib/rainbows/revactor/client.rb | 59 | ||||
-rw-r--r-- | lib/rainbows/revactor/client/methods.rb (renamed from lib/rainbows/revactor/body.rb) | 29 | ||||
-rw-r--r-- | lib/rainbows/revactor/client/tee_socket.rb (renamed from lib/rainbows/revactor/tee_socket.rb) | 2 |
3 files changed, 74 insertions, 16 deletions
diff --git a/lib/rainbows/revactor/client.rb b/lib/rainbows/revactor/client.rb new file mode 100644 index 0000000..7c4b53d --- /dev/null +++ b/lib/rainbows/revactor/client.rb @@ -0,0 +1,59 @@ +# -*- encoding: binary -*- +# :enddoc: +require 'fcntl' +class Rainbows::Revactor::Client + autoload :TeeSocket, 'rainbows/revactor/client/tee_socket' + RD_ARGS = {} + RD_ARGS[:timeout] = Rainbows::G.kato if Rainbows::G.kato > 0 + attr_reader :kgio_addr + + def initialize(client) + @client, @rd_args, @ts = client, [ nil ], nil + io = client.instance_variable_get(:@_io) + io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + @kgio_addr = if Revactor::TCP::Socket === client + @rd_args << RD_ARGS + client.remote_addr + else + Kgio::LOCALHOST + end + end + + def kgio_read!(nr, buf) + buf.replace(@client.read) + end + + def write(buf) + @client.write(buf) + end + + def write_nonblock(buf) # only used for errors + @client.instance_variable_get(:@_io).write_nonblock(buf) + end + + def timed_read(buf2) + buf2.replace(@client.read(*@rd_args)) + end + + def set_input(env, hp) + env[RACK_INPUT] = 0 == hp.content_length ? + NULL_IO : IC.new(@ts = TeeSocket.new(@client), hp) + env[CLIENT_IO] = @client + end + + def close + @client.close + @client = nil + end + + def closed? + @client.nil? + end + + def self.setup + self.const_set(:IC, Unicorn::HttpRequest.input_class) + include Rainbows::ProcessClient + include Methods + end +end +require 'rainbows/revactor/client/methods' diff --git a/lib/rainbows/revactor/body.rb b/lib/rainbows/revactor/client/methods.rb index 9820df3..e9b39a3 100644 --- a/lib/rainbows/revactor/body.rb +++ b/lib/rainbows/revactor/client/methods.rb @@ -1,15 +1,10 @@ # -*- encoding: binary -*- # :enddoc: -module Rainbows::Revactor::Body - # TODO non-blocking splice(2) under Linux - ALIASES = { - :write_body_stream => :write_body_each - } - +module Rainbows::Revactor::Client::Methods if IO.method_defined?(:sendfile_nonblock) - def write_body_file_sendfile_revactor(client, body, range) - body = body_to_io(body) - sock = client.instance_variable_get(:@_io) + def write_body_file(body, range) + body, client = body_to_io(body), @client + sock = @client.instance_variable_get(:@_io) pfx = Revactor::TCP::Socket === client ? :tcp : :unix write_complete = T[:"#{pfx}_write_complete", client] closed = T[:"#{pfx}_closed", client] @@ -33,14 +28,18 @@ module Rainbows::Revactor::Body ensure close_if_private(body) end - ALIASES[:write_body_file] = :write_body_file_sendfile_revactor - else - ALIASES[:write_body] = :write_body_each + end + + def handle_error(e) + Revactor::TCP::ReadError === e or super + end + + def write_response(status, headers, body, alive) + super(status, headers, body, alive) + alive && @ts and @hp.buf << @ts.leftover end def self.included(klass) - ALIASES.each do |new_method, orig_method| - klass.__send__(:alias_method, new_method, orig_method) - end + klass.__send__ :alias_method, :write_body_stream, :write_body_each end end diff --git a/lib/rainbows/revactor/tee_socket.rb b/lib/rainbows/revactor/client/tee_socket.rb index 71aeb88..2f9f52e 100644 --- a/lib/rainbows/revactor/tee_socket.rb +++ b/lib/rainbows/revactor/client/tee_socket.rb @@ -5,7 +5,7 @@ # enough to avoid mucking with TeeInput internals. Fortunately # this code is not heavily used so we can usually avoid the overhead # of adding a userspace buffer. -class Rainbows::Revactor::TeeSocket +class Rainbows::Revactor::Client::TeeSocket def initialize(socket) # IO::Buffer is used internally by Rev which Revactor is based on # so we'll always have it available |