From: Eric Wong Date: Tue, 22 Jan 2013 23:52:14 +0000 (+0000) Subject: ignore normal Rack response at request-time hijack X-Git-Tag: v4.6.0pre1~1^2 X-Git-Url: https://repo.or.cz/w/unicorn.git/commitdiff_plain/fedb5e50829e6dfad30ca18ea525c812eccbec70 ignore normal Rack response at request-time hijack Once a connection is hijacked, we ignore it completely and leave the connection at the mercy of the application. --- diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb index 3bc64edb..3795b3b5 100644 --- a/lib/unicorn/http_request.rb +++ b/lib/unicorn/http_request.rb @@ -106,6 +106,10 @@ class Unicorn::HttpParser RACK_HIJACK = "rack.hijack".freeze RACK_HIJACK_IO = "rack.hijack_io".freeze + def hijacked? + env.include?(RACK_HIJACK_IO) + end + def hijack_setup(e, socket) e[RACK_HIJACK] = proc { e[RACK_HIJACK_IO] ||= socket } end @@ -113,5 +117,9 @@ class Unicorn::HttpParser # old Rack, do nothing. def hijack_setup(e, _) end + + def hijacked? + false + end end end diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb index 2d8e4e12..cc0a705f 100644 --- a/lib/unicorn/http_server.rb +++ b/lib/unicorn/http_server.rb @@ -550,11 +550,13 @@ class Unicorn::HttpServer # in 3 easy steps: read request, call app, write app response def process_client(client) status, headers, body = @app.call(env = @request.read(client)) + return if @request.hijacked? if 100 == status.to_i client.write(expect_100_response) env.delete(Unicorn::Const::HTTP_EXPECT) status, headers, body = @app.call(env) + return if @request.hijacked? end @request.headers? or headers = nil http_response_write(client, status, headers, body, diff --git a/t/hijack.ru b/t/hijack.ru index 105e0d70..fcb0b6d4 100644 --- a/t/hijack.ru +++ b/t/hijack.ru @@ -17,7 +17,12 @@ run lambda { |env| io = env["rack.hijack"].call if io.respond_to?(:read_nonblock) && env["rack.hijack_io"].respond_to?(:read_nonblock) - return [ 200, {}, [ "hijack.OK\n" ] ] + + # exercise both, since we Rack::Lint may use different objects + env["rack.hijack_io"].write("HTTP/1.0 200 OK\r\n\r\n") + io.write("request.hijacked") + io.close + return [ 500, {}, DieIfUsed.new ] end end [ 500, {}, [ "hijack BAD\n" ] ] diff --git a/t/t0200-rack-hijack.sh b/t/t0200-rack-hijack.sh index 23a9ee44..f7720713 100755 --- a/t/t0200-rack-hijack.sh +++ b/t/t0200-rack-hijack.sh @@ -9,7 +9,7 @@ t_begin "setup and start" && { } t_begin "check request hijack" && { - test "xhijack.OK" = x"$(curl -sSfv http://$listen/hijack_req)" + test "xrequest.hijacked" = x"$(curl -sSfv http://$listen/hijack_req)" } t_begin "check response hijack" && {