From fe94d80cb37ee441762ad2a8f5c25092f8eb57a8 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 27 Sep 2010 22:39:02 -0700 Subject: http_request: avoid globals Rainbows! will be able to reuse this. --- lib/unicorn.rb | 4 ++-- lib/unicorn/http_request.rb | 33 ++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'lib') 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 -- cgit v1.2.3-24-ge0c7