From 15631717fce044fbad2f386a7b1c7daf4bdd83d2 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 21 Oct 2010 16:25:39 -0700 Subject: code shuffling for kgio Despite the large number of changes, most of it is code movement here. --- lib/rainbows/process_client.rb | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 lib/rainbows/process_client.rb (limited to 'lib/rainbows/process_client.rb') diff --git a/lib/rainbows/process_client.rb b/lib/rainbows/process_client.rb new file mode 100644 index 0000000..5e200e5 --- /dev/null +++ b/lib/rainbows/process_client.rb @@ -0,0 +1,61 @@ +# -*- encoding: binary -*- +# :enddoc: +module Rainbows::ProcessClient + G = Rainbows::G + include Rainbows::Response + HttpParser = Unicorn::HttpParser + NULL_IO = Unicorn::HttpRequest::NULL_IO + RACK_INPUT = Unicorn::HttpRequest::RACK_INPUT + TeeInput = Rainbows::TeeInput + include Rainbows::Const + + def wait_headers_readable(client) + IO.select([client], nil, nil, G.kato) + end + + # once a client is accepted, it is processed in its entirety here + # in 3 easy steps: read request, call app, write app response + # this is used by synchronous concurrency models + # Base, ThreadSpawn, ThreadPool + def process_client(client) # :nodoc: + hp = HttpParser.new + client.readpartial(16384, buf = hp.buf) + remote_addr = client.kgio_addr + + begin # loop + until env = hp.parse + wait_headers_readable(client) or return + buf << client.readpartial(16384) + end + + env[CLIENT_IO] = client + env[RACK_INPUT] = 0 == hp.content_length ? + NULL_IO : TeeInput.new(client, hp) + env[REMOTE_ADDR] = remote_addr + status, headers, body = APP.call(env.update(RACK_DEFAULTS)) + + if 100 == status.to_i + client.write(EXPECT_100_RESPONSE) + env.delete(HTTP_EXPECT) + status, headers, body = APP.call(env) + end + + if hp.headers? + headers = HH.new(headers) + range = make_range!(env, status, headers) and status = range.shift + env = hp.keepalive? && G.alive + headers[CONNECTION] = env ? KEEP_ALIVE : CLOSE + client.write(response_header(status, headers)) + end + write_body(client, body, range) + end while env && hp.reset.nil? + # if we get any error, try to write something back to the client + # assuming we haven't closed the socket, but don't get hung up + # if the socket is already closed or broken. We'll always ensure + # the socket is closed at the end of this function + rescue => e + Rainbows::Error.write(client, e) + ensure + client.close unless client.closed? + end +end -- cgit v1.2.3-24-ge0c7