diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-11-25 01:44:34 -0800 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-11-25 03:13:12 -0800 |
commit | 4d8304bf0aa5665e8f8474dfb96019297fa0c2b9 (patch) | |
tree | 676418a49b5575209c00fb3bcb83db10df8834bc /lib/rainbows/fiber.rb | |
parent | 2bc6e7a3c4e972ee3227d931e79bc4057ba278ca (diff) | |
download | rainbows-4d8304bf0aa5665e8f8474dfb96019297fa0c2b9.tar.gz |
This one seems a easy to get working and supports everything we need to support from the server perspective. Apps will need modified drivers, but it doesn't seem too hard to add more/better support for wrapping IO objects with Fiber::IO.
Diffstat (limited to 'lib/rainbows/fiber.rb')
-rw-r--r-- | lib/rainbows/fiber.rb | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/rainbows/fiber.rb b/lib/rainbows/fiber.rb new file mode 100644 index 0000000..e7d64ca --- /dev/null +++ b/lib/rainbows/fiber.rb @@ -0,0 +1,53 @@ +# -*- encoding: binary -*- +require 'fiber' +require 'rainbows/fiber/io' + +module Rainbows + module Fiber + RD = {} + WR = {} + + module Base + include Rainbows::Base + + def process_client(client) + G.cur += 1 + io = client.to_io + buf = client.read_timeout or return + hp = HttpParser.new + env = {} + alive = true + remote_addr = TCPSocket === io ? io.peeraddr.last : LOCALHOST + + begin # loop + while ! hp.headers(env, buf) + buf << client.read_timeout or return + end + + env[RACK_INPUT] = 0 == hp.content_length ? + HttpRequest::NULL_IO : TeeInput.new(client, env, hp, buf) + env[REMOTE_ADDR] = remote_addr + response = APP.call(env.update(RACK_DEFAULTS)) + + if 100 == response.first.to_i + client.write(EXPECT_100_RESPONSE) + env.delete(HTTP_EXPECT) + response = APP.call(env) + end + + alive = hp.keepalive? && G.alive + out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if hp.headers? + HttpResponse.write(client, response, out) + end while alive and hp.reset.nil? and env.clear + io.close + rescue => e + handle_error(io, e) + ensure + G.cur -= 1 + RD.delete(client) + WR.delete(client) + end + + end + end +end |