about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-09-03 10:55:11 -0700
committerEric Wong <normalperson@yhbt.net>2009-09-03 10:55:11 -0700
commitd4fd801ceebf56fe9204a3b2829138fb4c433d39 (patch)
tree435290909d2a5c9021fb25d4db27aff0cbeb96f4
parent52c2c6273e7c007543de776937a25827c27d0ff1 (diff)
downloadunicorn-d4fd801ceebf56fe9204a3b2829138fb4c433d39.tar.gz
HTTP/0.9 GET requests expect responses without headers.  Some
weird applications/tools still use the ancient HTTP/0.9
protocol for weird reasons, so we'll support them.

ref: rfc 1945, section 4.1
-rw-r--r--lib/unicorn.rb3
-rw-r--r--lib/unicorn/http_response.rb11
-rw-r--r--test/unit/test_server.rb10
3 files changed, 19 insertions, 5 deletions
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index b185b25..88391f6 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -447,8 +447,7 @@ module Unicorn
         env.delete(Const::HTTP_EXPECT)
         response = app.call(env)
       end
-
-      HttpResponse.write(client, response)
+      HttpResponse.write(client, response, HttpRequest::PARSER.headers?)
     # if we get any error, try to write something back to the client
     # assuming we haven't closed the socket, but don't get hung up
     # if the socket is already closed or broken.  We'll always ensure
diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index 5602a43..0835820 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -33,9 +33,7 @@ module Unicorn
     SKIP = { 'connection' => true, 'date' => true, 'status' => true }.freeze
     OUT = [] # :nodoc
 
-    # writes the rack_response to socket as an HTTP response
-    def self.write(socket, rack_response)
-      status, headers, body = rack_response
+    def self.write_header(socket, status, headers)
       status = CODES[status.to_i] || status
       OUT.clear
 
@@ -59,6 +57,13 @@ module Unicorn
                    "Status: #{status}\r\n" \
                    "Connection: close\r\n" \
                    "#{OUT.join(Z)}\r\n")
+
+    end
+
+    # writes the rack_response to socket as an HTTP response
+    def self.write(socket, rack_response, have_header = true)
+      status, headers, body = rack_response
+      write_header(socket, status, headers) if have_header
       body.each { |chunk| socket.write(chunk) }
       socket.close # flushes and uncorks the socket immediately
       ensure
diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb
index 0b409ba..fff7f89 100644
--- a/test/unit/test_server.rb
+++ b/test/unit/test_server.rb
@@ -148,6 +148,16 @@ class WebServerTest < Test::Unit::TestCase
     assert_nothing_raised { sock.close }
   end
 
+  def test_http_0_9
+    sock = nil
+    assert_nothing_raised do
+      sock = TCPSocket.new('127.0.0.1', @port)
+      sock.syswrite("GET /hello\r\n")
+    end
+    assert_match 'hello!\n', sock.sysread(4096)
+    assert_nothing_raised { sock.close }
+  end
+
   def test_header_is_too_long
     redirect_test_io do
       long = "GET /test HTTP/1.1\r\n" + ("X-Big: stuff\r\n" * 15000) + "\r\n"