1 # -*- encoding: binary -*-
3 module Rainbows::ProcessClient
4 include Rainbows::Response
5 include Rainbows::Const
7 NULL_IO = Unicorn::HttpRequest::NULL_IO
8 RACK_INPUT = Unicorn::HttpRequest::RACK_INPUT
9 IC = Unicorn::HttpRequest.input_class
10 HBUFSIZ = Rainbows.client_header_buffer_size
13 @hp = hp = Rainbows::HttpParser.new
14 kgio_read!(HBUFSIZ, buf = hp.buf) or return
18 timed_read(buf2 ||= "") or return
23 env[REMOTE_ADDR] = kgio_addr
24 status, headers, body = APP.call(env.merge!(RACK_DEFAULTS))
27 write(EXPECT_100_RESPONSE)
28 env.delete(HTTP_EXPECT)
29 status, headers, body = APP.call(env)
31 write_response(status, headers, body, alive = @hp.next?)
33 # if we get any error, try to write something back to the client
34 # assuming we haven't closed the socket, but don't get hung up
35 # if the socket is already closed or broken. We'll always ensure
36 # the socket is closed at the end of this function
44 Rainbows::Error.write(self, e)
47 def set_input(env, hp)
48 env[RACK_INPUT] = 0 == hp.content_length ? NULL_IO : IC.new(self, hp)
51 def process_pipeline(env, hp)
54 env[REMOTE_ADDR] = kgio_addr
55 status, headers, body = APP.call(env.merge!(RACK_DEFAULTS))
57 write(EXPECT_100_RESPONSE)
58 env.delete(HTTP_EXPECT)
59 status, headers, body = APP.call(env)
61 write_response(status, headers, body, alive = hp.next?)
62 end while alive && pipeline_ready(hp)
68 # override this in subclass/module
69 def pipeline_ready(hp)