diff options
author | Eric Wong <ew@80x24.org> | 2017-12-16 01:22:40 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2017-12-16 01:33:46 +0000 |
commit | 30e3c6abe542c6a9f5955e1d65896a0c3bab534f (patch) | |
tree | 5cecdf58f29e130c423e7bf7b671800f56143eec /t | |
parent | 1a407d78c90695c03ec6ac1e0a8b7f0e466c975e (diff) | |
download | unicorn-30e3c6abe542c6a9f5955e1d65896a0c3bab534f.tar.gz |
Hijackers may capture and reuse `env' indefinitely, so we must not use it in those cases for future requests. For non-hijack requests, we continue to reuse the `env' object to reduce memory recycling. Reported-and-tested-by: Sam Saffron <sam.saffron@gmail.com>
Diffstat (limited to 't')
-rw-r--r-- | t/hijack.ru | 12 | ||||
-rwxr-xr-x | t/t0200-rack-hijack.sh | 23 |
2 files changed, 34 insertions, 1 deletions
diff --git a/t/hijack.ru b/t/hijack.ru index 4adec61..02260e2 100644 --- a/t/hijack.ru +++ b/t/hijack.ru @@ -11,11 +11,15 @@ class DieIfUsed warn "closed DieIfUsed #{@@n += 1}\n" end end + +envs = [] + run lambda { |env| case env["PATH_INFO"] when "/hijack_req" if env["rack.hijack?"] io = env["rack.hijack"].call + envs << env if io.respond_to?(:read_nonblock) && env["rack.hijack_io"].respond_to?(:read_nonblock) @@ -33,11 +37,19 @@ run lambda { |env| { "Content-Length" => r.bytesize.to_s, "rack.hijack" => proc do |io| + envs << env io.write(r) io.close end }, DieIfUsed.new ] + when "/normal_env_id" + b = "#{env.object_id}\n" + h = { + 'Content-Type' => 'text/plain', + 'Content-Length' => b.bytesize.to_s, + } + [ 200, h, [ b ] ] end } diff --git a/t/t0200-rack-hijack.sh b/t/t0200-rack-hijack.sh index de3eb82..fee0791 100755 --- a/t/t0200-rack-hijack.sh +++ b/t/t0200-rack-hijack.sh @@ -1,6 +1,6 @@ #!/bin/sh . ./test-lib.sh -t_plan 5 "rack.hijack tests (Rack 1.5+ (Rack::VERSION >= [ 1,2]))" +t_plan 9 "rack.hijack tests (Rack 1.5+ (Rack::VERSION >= [ 1,2]))" t_begin "setup and start" && { unicorn_setup @@ -8,14 +8,35 @@ t_begin "setup and start" && { unicorn_wait_start } +t_begin "normal env reused between requests" && { + env_a="$(curl -sSf http://$listen/normal_env_id)" + b="$(curl -sSf http://$listen/normal_env_id)" + test x"$env_a" = x"$b" +} + t_begin "check request hijack" && { test "xrequest.hijacked" = x"$(curl -sSfv http://$listen/hijack_req)" } +t_begin "env changed after request hijack" && { + env_b="$(curl -sSf http://$listen/normal_env_id)" + test x"$env_a" != x"$env_b" +} + t_begin "check response hijack" && { test "xresponse.hijacked" = x"$(curl -sSfv http://$listen/hijack_res)" } +t_begin "env changed after response hijack" && { + env_c="$(curl -sSf http://$listen/normal_env_id)" + test x"$env_b" != x"$env_c" +} + +t_begin "env continues to be reused between requests" && { + b="$(curl -sSf http://$listen/normal_env_id)" + test x"$env_c" = x"$b" +} + t_begin "killing succeeds after hijack" && { kill $unicorn_pid } |