about summary refs log tree commit homepage
path: root/test/unit/test_server.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/test_server.rb')
-rw-r--r--test/unit/test_server.rb109
1 files changed, 43 insertions, 66 deletions
diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb
index 8096955..5a2252f 100644
--- a/test/unit/test_server.rb
+++ b/test/unit/test_server.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # Copyright (c) 2005 Zed A. Shaw
 # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
@@ -16,13 +17,30 @@ class TestHandler
   def call(env)
     while env['rack.input'].read(4096)
     end
-    [200, { 'Content-Type' => 'text/plain' }, ['hello!\n']]
+    [200, { 'content-type' => 'text/plain' }, ['hello!\n']]
   rescue Unicorn::ClientShutdown, Unicorn::HttpParserError => e
     $stderr.syswrite("#{e.class}: #{e.message} #{e.backtrace.empty?}\n")
     raise e
   end
 end
 
+class TestRackAfterReply
+  def initialize
+    @called = false
+  end
+
+  def call(env)
+    while env['rack.input'].read(4096)
+    end
+
+    env["rack.after_reply"] << -> { @called = true }
+
+    [200, { 'content-type' => 'text/plain' }, ["after_reply_called: #{@called}"]]
+  rescue Unicorn::ClientShutdown, Unicorn::HttpParserError => e
+    $stderr.syswrite("#{e.class}: #{e.message} #{e.backtrace.empty?}\n")
+    raise e
+  end
+end
 
 class WebServerTest < Test::Unit::TestCase
 
@@ -53,7 +71,7 @@ class WebServerTest < Test::Unit::TestCase
       tmp.sysseek(0)
       tmp.truncate(0)
       tmp.syswrite($$)
-      lambda { |env| [ 200, { 'Content-Type' => 'text/plain' }, [ "#$$\n" ] ] }
+      lambda { |env| [ 200, { 'content-type' => 'text/plain' }, [ "#$$\n" ] ] }
     }
     redirect_test_io do
       @server = HttpServer.new(app, :listeners => [ "127.0.0.1:#@port"] )
@@ -84,18 +102,30 @@ class WebServerTest < Test::Unit::TestCase
     tmp.close!
   end
 
-  def test_broken_app
+  def test_after_reply
     teardown
-    app = lambda { |env| raise RuntimeError, "hello" }
-    # [200, {}, []] }
+
     redirect_test_io do
-      @server = HttpServer.new(app, :listeners => [ "127.0.0.1:#@port"] )
+      @server = HttpServer.new(TestRackAfterReply.new,
+                               :listeners => [ "127.0.0.1:#@port"])
       @server.start
     end
-    sock = TCPSocket.new('127.0.0.1', @port)
+
+    sock = tcp_socket('127.0.0.1', @port)
     sock.syswrite("GET / HTTP/1.0\r\n\r\n")
-    assert_match %r{\AHTTP/1.[01] 500\b}, sock.sysread(4096)
-    assert_nil sock.close
+
+    responses = sock.read(4096)
+    assert_match %r{\AHTTP/1.[01] 200\b}, responses
+    assert_match %r{^after_reply_called: false}, responses
+
+    sock = tcp_socket('127.0.0.1', @port)
+    sock.syswrite("GET / HTTP/1.0\r\n\r\n")
+
+    responses = sock.read(4096)
+    assert_match %r{\AHTTP/1.[01] 200\b}, responses
+    assert_match %r{^after_reply_called: true}, responses
+
+    sock.close
   end
 
   def test_simple_server
@@ -103,62 +133,9 @@ class WebServerTest < Test::Unit::TestCase
     assert_equal 'hello!\n', results[0], "Handler didn't really run"
   end
 
-  def test_client_shutdown_writes
-    bs = 15609315 * rand
-    sock = TCPSocket.new('127.0.0.1', @port)
-    sock.syswrite("PUT /hello HTTP/1.1\r\n")
-    sock.syswrite("Host: example.com\r\n")
-    sock.syswrite("Transfer-Encoding: chunked\r\n")
-    sock.syswrite("Trailer: X-Foo\r\n")
-    sock.syswrite("\r\n")
-    sock.syswrite("%x\r\n" % [ bs ])
-    sock.syswrite("F" * bs)
-    sock.syswrite("\r\n0\r\nX-")
-    "Foo: bar\r\n\r\n".each_byte do |x|
-      sock.syswrite x.chr
-      sleep 0.05
-    end
-    # we wrote the entire request before shutting down, server should
-    # continue to process our request and never hit EOFError on our sock
-    sock.shutdown(Socket::SHUT_WR)
-    buf = sock.read
-    assert_equal 'hello!\n', buf.split(/\r\n\r\n/).last
-    next_client = Net::HTTP.get(URI.parse("http://127.0.0.1:#@port/"))
-    assert_equal 'hello!\n', next_client
-    lines = File.readlines("test_stderr.#$$.log")
-    assert lines.grep(/^Unicorn::ClientShutdown: /).empty?
-    assert_nil sock.close
-  end
-
-  def test_client_shutdown_write_truncates
-    bs = 15609315 * rand
-    sock = TCPSocket.new('127.0.0.1', @port)
-    sock.syswrite("PUT /hello HTTP/1.1\r\n")
-    sock.syswrite("Host: example.com\r\n")
-    sock.syswrite("Transfer-Encoding: chunked\r\n")
-    sock.syswrite("Trailer: X-Foo\r\n")
-    sock.syswrite("\r\n")
-    sock.syswrite("%x\r\n" % [ bs ])
-    sock.syswrite("F" * (bs / 2.0))
-
-    # shutdown prematurely, this will force the server to abort
-    # processing on us even during app dispatch
-    sock.shutdown(Socket::SHUT_WR)
-    IO.select([sock], nil, nil, 60) or raise "Timed out"
-    buf = sock.read
-    assert_equal "", buf
-    next_client = Net::HTTP.get(URI.parse("http://127.0.0.1:#@port/"))
-    assert_equal 'hello!\n', next_client
-    lines = File.readlines("test_stderr.#$$.log")
-    lines = lines.grep(/^Unicorn::ClientShutdown: bytes_read=\d+/)
-    assert_equal 1, lines.size
-    assert_match %r{\AUnicorn::ClientShutdown: bytes_read=\d+ true$}, lines[0]
-    assert_nil sock.close
-  end
-
   def test_client_malformed_body
     bs = 15653984
-    sock = TCPSocket.new('127.0.0.1', @port)
+    sock = tcp_socket('127.0.0.1', @port)
     sock.syswrite("PUT /hello HTTP/1.1\r\n")
     sock.syswrite("Host: example.com\r\n")
     sock.syswrite("Transfer-Encoding: chunked\r\n")
@@ -180,7 +157,7 @@ class WebServerTest < Test::Unit::TestCase
 
   def do_test(string, chunk, close_after=nil, shutdown_delay=0)
     # Do not use instance variables here, because it needs to be thread safe
-    socket = TCPSocket.new("127.0.0.1", @port);
+    socket = tcp_socket("127.0.0.1", @port);
     request = StringIO.new(string)
     chunks_out = 0
 
@@ -225,14 +202,14 @@ class WebServerTest < Test::Unit::TestCase
   end
 
   def test_bad_client_400
-    sock = TCPSocket.new('127.0.0.1', @port)
+    sock = tcp_socket('127.0.0.1', @port)
     sock.syswrite("GET / HTTP/1.0\r\nHost: foo\rbar\r\n\r\n")
     assert_match %r{\AHTTP/1.[01] 400\b}, sock.sysread(4096)
     assert_nil sock.close
   end
 
   def test_http_0_9
-    sock = TCPSocket.new('127.0.0.1', @port)
+    sock = tcp_socket('127.0.0.1', @port)
     sock.syswrite("GET /hello\r\n")
     assert_match 'hello!\n', sock.sysread(4096)
     assert_nil sock.close