diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-09-27 22:39:02 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-10-04 21:01:27 +0000 |
commit | fe94d80cb37ee441762ad2a8f5c25092f8eb57a8 (patch) | |
tree | 816e906d821dae64ac8949ed6886a69b03f17064 /lib | |
parent | 5b6a97ff54d029d433b79eee1549e6f99464c48b (diff) | |
download | unicorn-fe94d80cb37ee441762ad2a8f5c25092f8eb57a8.tar.gz |
Rainbows! will be able to reuse this.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/unicorn.rb | 4 | ||||
-rw-r--r-- | lib/unicorn/http_request.rb | 33 |
2 files changed, 20 insertions, 17 deletions
diff --git a/lib/unicorn.rb b/lib/unicorn.rb index c972f65..418b138 100644 --- a/lib/unicorn.rb +++ b/lib/unicorn.rb @@ -449,7 +449,7 @@ module Unicorn # Wake up every second anyways to run murder_lazy_workers def master_sleep(sec) IO.select([ SELF_PIPE[0] ], nil, nil, sec) or return - SELF_PIPE[0].read_nonblock(Const::CHUNK_SIZE, HttpRequest::BUF) + SELF_PIPE[0].read_nonblock(Const::CHUNK_SIZE) rescue Errno::EAGAIN, Errno::EINTR end @@ -599,7 +599,7 @@ module Unicorn r = app.call(env) end # r may be frozen or const, so don't modify it - HttpRequest::PARSER.headers? or r = [ r[0], nil, r[2] ] + REQUEST.response_headers? or r = [ r[0], nil, r[2] ] http_response_write(client, r) rescue => e handle_error(client, e) diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb index 65870ed..8abc945 100644 --- a/lib/unicorn/http_request.rb +++ b/lib/unicorn/http_request.rb @@ -21,11 +21,15 @@ module Unicorn NULL_IO = StringIO.new("") LOCALHOST = '127.0.0.1' - # Being explicitly single-threaded, we have certain advantages in - # not having to worry about variables being clobbered :) - BUF = "" - PARSER = HttpParser.new - REQ = {} + def initialize + @parser = Unicorn::HttpParser.new + @buf = "" + @env = {} + end + + def response_headers? + @parser.headers? + end # Does the majority of the IO processing. It has been written in # Ruby using about 8 different IO processing strategies. @@ -41,8 +45,8 @@ module Unicorn # This does minimal exception trapping and it is up to the caller # to handle any socket errors (e.g. user aborted upload). def read(socket) - REQ.clear - PARSER.reset + @env.clear + @parser.reset # From http://www.ietf.org/rfc/rfc3875: # "Script authors should be aware that the REMOTE_ADDR and @@ -51,21 +55,20 @@ module Unicorn # identify the client for the immediate request to the server; # that client may be a proxy, gateway, or other intermediary # acting on behalf of the actual source client." - REQ[Const::REMOTE_ADDR] = + @env[Const::REMOTE_ADDR] = TCPSocket === socket ? socket.peeraddr[-1] : LOCALHOST # short circuit the common case with small GET requests first - if PARSER.headers(REQ, socket.readpartial(Const::CHUNK_SIZE, BUF)).nil? + if @parser.headers(@env, socket.readpartial(Const::CHUNK_SIZE, @buf)).nil? # Parser is not done, queue up more data to read and continue parsing # an Exception thrown from the PARSER will throw us out of the loop begin - BUF << socket.readpartial(Const::CHUNK_SIZE) - end while PARSER.headers(REQ, BUF).nil? + @buf << socket.readpartial(Const::CHUNK_SIZE) + end while @parser.headers(@env, @buf).nil? end - REQ[Const::RACK_INPUT] = 0 == PARSER.content_length ? - NULL_IO : Unicorn::TeeInput.new(socket, REQ, PARSER, BUF) - REQ.update(DEFAULTS) + @env[Const::RACK_INPUT] = 0 == @parser.content_length ? + NULL_IO : Unicorn::TeeInput.new(socket, @env, @parser, @buf) + @env.merge!(DEFAULTS) end - end end |