diff options
author | Blake Williams <blake@blakewilliams.me> | 2020-12-08 16:47:16 -0500 |
---|---|---|
committer | Eric Wong <bofh@yhbt.net> | 2020-12-09 21:58:33 +0000 |
commit | 673c15e3f020bccc0336838617875b26c9a45f4e (patch) | |
tree | 79112011c77d624338a47cea0316684031322fad /test/unit/test_server.rb | |
parent | 2c347116305338710331d238fefa23f00e98cf54 (diff) | |
download | unicorn-673c15e3f020bccc0336838617875b26c9a45f4e.tar.gz |
This adds `rack.after_reply` functionality which allows rack middleware to pass lambdas that will be executed after the client connection has been closed. This was driven by a need to perform actions in a request that shouldn't block the request from completing but also don't make sense as background jobs. There is prior art of this being supported found in a few gems, as well as this functionality existing in other rack based servers (e.g. Puma). [ew: check if `env' is set in ensure statement] Acked-by: Eric Wong <e@80x24.org>
Diffstat (limited to 'test/unit/test_server.rb')
-rw-r--r-- | test/unit/test_server.rb | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb index 384fa6b..781750d 100644 --- a/test/unit/test_server.rb +++ b/test/unit/test_server.rb @@ -34,6 +34,24 @@ class TestEarlyHintsHandler 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 def setup @@ -114,6 +132,32 @@ class WebServerTest < Test::Unit::TestCase assert_match %r{^HTTP/1.[01] 200\b}, responses end + def test_after_reply + teardown + + redirect_test_io do + @server = HttpServer.new(TestRackAfterReply.new, + :listeners => [ "127.0.0.1:#@port"]) + @server.start + end + + sock = TCPSocket.new('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: false}, responses + + sock = TCPSocket.new('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_broken_app teardown app = lambda { |env| raise RuntimeError, "hello" } |