about summary refs log tree commit homepage
path: root/lib
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 /lib
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)
Diffstat (limited to 'lib')
-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