about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-09-27 22:39:02 -0700
committerEric Wong <normalperson@yhbt.net>2010-10-04 21:01:27 +0000
commitfe94d80cb37ee441762ad2a8f5c25092f8eb57a8 (patch)
tree816e906d821dae64ac8949ed6886a69b03f17064
parent5b6a97ff54d029d433b79eee1549e6f99464c48b (diff)
downloadunicorn-fe94d80cb37ee441762ad2a8f5c25092f8eb57a8.tar.gz
Rainbows! will be able to reuse this.
-rw-r--r--lib/unicorn.rb4
-rw-r--r--lib/unicorn/http_request.rb33
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