about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-06-28 04:45:16 +0000
committerEric Wong <normalperson@yhbt.net>2010-07-06 14:39:40 -0700
commit85d55f6450f3546d3211be247919a2dae03a1110 (patch)
treef8b40e8821a224973d3382245deacf82275299e5
parent2b07395f33f321d14c0a252abc37d9e2966f7627 (diff)
downloadunicorn-85d55f6450f3546d3211be247919a2dae03a1110.tar.gz
This affects Rainbows!, but Rainbows! is still using the Unicorn
1.x branch.  While we're at it, avoid redeclaring the "Unicorn"
module, it makes documentation noisier.
(cherry picked from commit 5769f313793ca84100f089b1911f2e22d0a31e9d)
-rw-r--r--lib/unicorn/http_response.rb115
1 files changed, 55 insertions, 60 deletions
diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index 96e484b..6f1cd48 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -1,75 +1,70 @@
 # -*- encoding: binary -*-
-
 require 'time'
 
-module Unicorn
-  # Writes a Rack response to your client using the HTTP/1.1 specification.
-  # You use it by simply doing:
-  #
-  #   status, headers, body = rack_app.call(env)
-  #   HttpResponse.write(socket, [ status, headers, body ])
-  #
-  # Most header correctness (including Content-Length and Content-Type)
-  # is the job of Rack, with the exception of the "Connection: close"
-  # and "Date" headers.
-  #
-  # A design decision was made to force the client to not pipeline or
-  # keepalive requests.  HTTP/1.1 pipelining really kills the
-  # performance due to how it has to be handled and how unclear the
-  # standard is.  To fix this the HttpResponse always gives a
-  # "Connection: close" header which forces the client to close right
-  # away.  The bonus for this is that it gives a pretty nice speed boost
-  # to most clients since they can close their connection immediately.
-
-  class HttpResponse
+# Writes a Rack response to your client using the HTTP/1.1 specification.
+# You use it by simply doing:
+#
+#   status, headers, body = rack_app.call(env)
+#   HttpResponse.write(socket, [ status, headers, body ])
+#
+# Most header correctness (including Content-Length and Content-Type)
+# is the job of Rack, with the exception of the "Connection: close"
+# and "Date" headers.
+#
+# A design decision was made to force the client to not pipeline or
+# keepalive requests.  HTTP/1.1 pipelining really kills the
+# performance due to how it has to be handled and how unclear the
+# standard is.  To fix this the HttpResponse always gives a
+# "Connection: close" header which forces the client to close right
+# away.  The bonus for this is that it gives a pretty nice speed boost
+# to most clients since they can close their connection immediately.
+module Unicorn::HttpResponse
 
-    # Every standard HTTP code mapped to the appropriate message.
-    CODES = Rack::Utils::HTTP_STATUS_CODES.inject({}) { |hash,(code,msg)|
-      hash[code] = "#{code} #{msg}"
-      hash
-    }
+  # Every standard HTTP code mapped to the appropriate message.
+  CODES = Rack::Utils::HTTP_STATUS_CODES.inject({}) { |hash,(code,msg)|
+    hash[code] = "#{code} #{msg}"
+    hash
+  }
 
-    # Rack does not set/require a Date: header.  We always override the
-    # Connection: and Date: headers no matter what (if anything) our
-    # Rack application sent us.
-    SKIP = { 'connection' => true, 'date' => true, 'status' => true }
+  # Rack does not set/require a Date: header.  We always override the
+  # Connection: and Date: headers no matter what (if anything) our
+  # Rack application sent us.
+  SKIP = { 'connection' => true, 'date' => true, 'status' => true }
 
-    # writes the rack_response to socket as an HTTP response
-    def self.write(socket, rack_response, have_header = true)
-      status, headers, body = rack_response
+  # writes the rack_response to socket as an HTTP response
+  def self.write(socket, rack_response, have_header = true)
+    status, headers, body = rack_response
 
-      if have_header
-        status = CODES[status.to_i] || status
-        out = []
+    if have_header
+      status = CODES[status.to_i] || status
+      out = []
 
-        # Don't bother enforcing duplicate supression, it's a Hash most of
-        # the time anyways so just hope our app knows what it's doing
-        headers.each do |key, value|
-          next if SKIP.include?(key.downcase)
-          if value =~ /\n/
-            # avoiding blank, key-only cookies with /\n+/
-            out.concat(value.split(/\n+/).map! { |v| "#{key}: #{v}\r\n" })
-          else
-            out << "#{key}: #{value}\r\n"
-          end
+      # Don't bother enforcing duplicate supression, it's a Hash most of
+      # the time anyways so just hope our app knows what it's doing
+      headers.each do |key, value|
+        next if SKIP.include?(key.downcase)
+        if value =~ /\n/
+          # avoiding blank, key-only cookies with /\n+/
+          out.concat(value.split(/\n+/).map! { |v| "#{key}: #{v}\r\n" })
+        else
+          out << "#{key}: #{value}\r\n"
         end
-
-        # Rack should enforce Content-Length or chunked transfer encoding,
-        # so don't worry or care about them.
-        # Date is required by HTTP/1.1 as long as our clock can be trusted.
-        # Some broken clients require a "Status" header so we accomodate them
-        socket.write("HTTP/1.1 #{status}\r\n" \
-                     "Date: #{Time.now.httpdate}\r\n" \
-                     "Status: #{status}\r\n" \
-                     "Connection: close\r\n" \
-                     "#{out.join('')}\r\n")
       end
 
-      body.each { |chunk| socket.write(chunk) }
-      socket.close # flushes and uncorks the socket immediately
-      ensure
-        body.respond_to?(:close) and body.close
+      # Rack should enforce Content-Length or chunked transfer encoding,
+      # so don't worry or care about them.
+      # Date is required by HTTP/1.1 as long as our clock can be trusted.
+      # Some broken clients require a "Status" header so we accomodate them
+      socket.write("HTTP/1.1 #{status}\r\n" \
+                   "Date: #{Time.now.httpdate}\r\n" \
+                   "Status: #{status}\r\n" \
+                   "Connection: close\r\n" \
+                   "#{out.join('')}\r\n")
     end
 
+    body.each { |chunk| socket.write(chunk) }
+    socket.close # flushes and uncorks the socket immediately
+    ensure
+      body.respond_to?(:close) and body.close
   end
 end