about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/unicorn.rb27
-rw-r--r--lib/unicorn/configurator.rb3
-rw-r--r--lib/unicorn/const.rb3
-rw-r--r--lib/unicorn/http_request.rb37
-rw-r--r--lib/unicorn/http_response.rb15
-rw-r--r--lib/unicorn/socket_helper.rb (renamed from lib/unicorn/socket.rb)13
6 files changed, 34 insertions, 64 deletions
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index 208e6da..1f1dd45 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -1,7 +1,6 @@
-require 'logger'
 require 'fcntl'
 
-require 'unicorn/socket'
+require 'unicorn/socket_helper'
 require 'unicorn/const'
 require 'unicorn/http_request'
 require 'unicorn/http_response'
@@ -27,13 +26,13 @@ module Unicorn
     include ::Unicorn::SocketHelper
 
     SIG_QUEUE = []
-    DEFAULT_START_CTX = {
+    START_CTX = {
       :argv => ARGV.map { |arg| arg.dup },
       # don't rely on Dir.pwd here since it's not symlink-aware, and
       # symlink dirs are the default with Capistrano...
       :cwd => `/bin/sh -c pwd`.chomp("\n"),
       :zero => $0.dup,
-    }.freeze
+    }
 
     Worker = Struct.new(:nr, :tempfile) unless defined?(Worker)
     class Worker
@@ -48,9 +47,6 @@ module Unicorn
     # HttpServer.workers.join to join the thread that's processing
     # incoming requests on the socket.
     def initialize(app, options = {})
-      start_ctx = options.delete(:start_ctx)
-      @start_ctx = DEFAULT_START_CTX.dup
-      @start_ctx.merge!(start_ctx) if start_ctx
       @app = app
       @workers = Hash.new
       @io_purgatory = [] # prevents IO objects in here from being GC-ed
@@ -307,7 +303,7 @@ module Unicorn
       end
     end
 
-    # reexecutes the @start_ctx with a new binary
+    # reexecutes the START_CTX with a new binary
     def reexec
       if @reexec_pid > 0
         begin
@@ -337,8 +333,8 @@ module Unicorn
       @reexec_pid = fork do
         listener_fds = @listeners.map { |sock| sock.fileno }
         ENV['UNICORN_FD'] = listener_fds.join(',')
-        Dir.chdir(@start_ctx[:cwd])
-        cmd = [ @start_ctx[:zero] ] + @start_ctx[:argv]
+        Dir.chdir(START_CTX[:cwd])
+        cmd = [ START_CTX[:zero] ] + START_CTX[:argv]
 
         # avoid leaking FDs we don't know about, but let before_exec
         # unset FD_CLOEXEC, if anything else in the app eventually
@@ -379,9 +375,9 @@ module Unicorn
       (0...@worker_processes).each do |worker_nr|
         @workers.values.include?(worker_nr) and next
         begin
-          Dir.chdir(@start_ctx[:cwd])
+          Dir.chdir(START_CTX[:cwd])
         rescue Errno::ENOENT => err
-          logger.fatal "#{err.inspect} (#{@start_ctx[:cwd]})"
+          logger.fatal "#{err.inspect} (#{START_CTX[:cwd]})"
           SIG_QUEUE << :QUIT # forcibly emulate SIGQUIT
           return
         end
@@ -431,10 +427,11 @@ module Unicorn
       trap(:CHLD, 'DEFAULT')
       SIG_QUEUE.clear
       proc_name "worker[#{worker.nr}]"
+      START_CTX.clear
       @rd_sig.close if @rd_sig
       @wr_sig.close if @wr_sig
       @workers.values.each { |other| other.tempfile.close rescue nil }
-      @start_ctx = @workers = @rd_sig = @wr_sig = nil
+      @workers = @rd_sig = @wr_sig = nil
       @listeners.each { |sock| sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) }
       worker.tempfile.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
       @after_fork.call(self, worker) # can drop perms
@@ -588,8 +585,8 @@ module Unicorn
     end
 
     def proc_name(tag)
-      $0 = ([ File.basename(@start_ctx[:zero]), tag ] +
-              @start_ctx[:argv]).join(' ')
+      $0 = ([ File.basename(START_CTX[:zero]), tag ] +
+              START_CTX[:argv]).join(' ')
     end
 
   end
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index b27121e..bd06996 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -1,5 +1,4 @@
-require 'unicorn/socket'
-require 'unicorn/const'
+require 'socket'
 require 'logger'
 
 module Unicorn
diff --git a/lib/unicorn/const.rb b/lib/unicorn/const.rb
index 80731ab..c05d333 100644
--- a/lib/unicorn/const.rb
+++ b/lib/unicorn/const.rb
@@ -58,8 +58,6 @@ module Unicorn
 
     UNICORN_VERSION="0.5.3".freeze
 
-    UNICORN_TMP_BASE="unicorn".freeze
-
     DEFAULT_HOST = "0.0.0.0".freeze # default TCP listen host address
     DEFAULT_PORT = "8080".freeze    # default TCP listen port
     DEFAULT_LISTEN = "#{DEFAULT_HOST}:#{DEFAULT_PORT}".freeze
@@ -82,7 +80,6 @@ module Unicorn
     CONTENT_LENGTH="CONTENT_LENGTH".freeze
     REMOTE_ADDR="REMOTE_ADDR".freeze
     HTTP_X_FORWARDED_FOR="HTTP_X_FORWARDED_FOR".freeze
-    QUERY_STRING="QUERY_STRING".freeze
     RACK_INPUT="rack.input".freeze
   end
 
diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb
index 399aee5..24da085 100644
--- a/lib/unicorn/http_request.rb
+++ b/lib/unicorn/http_request.rb
@@ -1,5 +1,4 @@
 require 'tempfile'
-require 'uri'
 require 'stringio'
 
 # compiled extension
@@ -19,11 +18,11 @@ module Unicorn
        "rack.multiprocess" => true,
        "rack.multithread" => false,
        "rack.run_once" => false,
-       "rack.version" => [0, 1],
-       "SCRIPT_NAME" => "",
+       "rack.version" => [0, 1].freeze,
+       "SCRIPT_NAME" => "".freeze,
 
        # this is not in the Rack spec, but some apps may rely on it
-       "SERVER_SOFTWARE" => "Unicorn #{Const::UNICORN_VERSION}"
+       "SERVER_SOFTWARE" => "Unicorn #{Const::UNICORN_VERSION}".freeze
      }.freeze
 
     def initialize(logger)
@@ -56,6 +55,16 @@ 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)
+      # From http://www.ietf.org/rfc/rfc3875:
+      # "Script authors should be aware that the REMOTE_ADDR and
+      #  REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
+      #  may not identify the ultimate source of the request.  They
+      #  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."
+      @params[Const::REMOTE_ADDR] =
+                    TCPSocket === socket ? socket.peeraddr.last : '127.0.0.1'
+
       # short circuit the common case with small GET requests first
       @parser.execute(@params, read_socket(socket)) and
           return handle_body(socket)
@@ -71,7 +80,7 @@ module Unicorn
       rescue HttpParserError => e
         @logger.error "HTTP parse error, malformed request " \
                       "(#{@params[Const::HTTP_X_FORWARDED_FOR] ||
-                          socket.unicorn_peeraddr}): #{e.inspect}"
+                          @params[Const::REMOTE_ADDR]}): #{e.inspect}"
         @logger.error "REQUEST DATA: #{data.inspect}\n---\n" \
                       "PARAMS: #{@params.inspect}\n---\n"
         raise e
@@ -87,7 +96,7 @@ module Unicorn
       remain = content_length - http_body.length
 
       # must read more data to complete body
-      @body = remain < Const::MAX_BODY ? StringIO.new : Tempfile.new('')
+      @body = remain < Const::MAX_BODY ? StringIO.new : Tempfile.new('unicorn')
       @body.binmode
       @body.sync = true
       @body.syswrite(http_body)
@@ -116,22 +125,6 @@ module Unicorn
       # over the HTTP response.
       # @params["unicorn.client"] = socket
 
-      # From http://www.ietf.org/rfc/rfc3875:
-      # "Script authors should be aware that the REMOTE_ADDR and
-      #  REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
-      #  may not identify the ultimate source of the request.  They
-      #  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."
-      @params[Const::REMOTE_ADDR] = socket.unicorn_peeraddr
-
-      # It might be a dumbass full host request header
-      @params[Const::PATH_INFO] = (
-          @params[Const::REQUEST_PATH] ||=
-              URI.parse(@params[Const::REQUEST_URI]).path) or
-         raise "No REQUEST_PATH"
-
-      @params[Const::QUERY_STRING] ||= ''
       @params[Const::RACK_INPUT] = @body
       @params.update(DEF_PARAMS)
     end
diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index b355ad4..6b6fa07 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -64,15 +64,12 @@ module Unicorn
       # write(2) can return short on slow devices like sockets as well
       # as fail with EINTR if a signal was caught.
       def self.socket_write(socket, buffer)
-        loop do
-          begin
-            written = socket.syswrite(buffer)
-            return written if written == buffer.length
-            buffer = buffer[written..-1]
-          rescue Errno::EINTR
-            retry
-          end
-        end
+        begin
+          written = socket.syswrite(buffer)
+          return written if written == buffer.length
+          buffer = buffer[written..-1]
+        rescue Errno::EINTR
+        end while true
       end
 
   end
diff --git a/lib/unicorn/socket.rb b/lib/unicorn/socket_helper.rb
index 5a3bfd7..850ad85 100644
--- a/lib/unicorn/socket.rb
+++ b/lib/unicorn/socket_helper.rb
@@ -1,18 +1,5 @@
 require 'socket'
 
-class UNIXSocket
-  UNICORN_PEERADDR = '127.0.0.1'.freeze
-  def unicorn_peeraddr
-    UNICORN_PEERADDR
-  end
-end
-
-class TCPSocket
-  def unicorn_peeraddr
-    peeraddr.last
-  end
-end
-
 module Unicorn
   module SocketHelper
     include Socket::Constants