From 705cf5fcf8ccb37deef5d2b922d6d78d34765c5b Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 22 Jan 2013 11:04:52 +0000 Subject: support for Rack hijack in request and response Rack 1.5.0 (protocol version [1,2]) adds support for hijacking the client socket (removing it from the control of unicorn (or any other Rack webserver)). Tested with rack 1.5.0. --- t/hijack.ru | 37 +++++++++++++++++++++++++++++++++++++ t/t0005-working_directory_app.rb.sh | 5 ++++- t/t0200-rack-hijack.sh | 27 +++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 t/hijack.ru create mode 100755 t/t0200-rack-hijack.sh (limited to 't') diff --git a/t/hijack.ru b/t/hijack.ru new file mode 100644 index 0000000..105e0d7 --- /dev/null +++ b/t/hijack.ru @@ -0,0 +1,37 @@ +use Rack::Lint +use Rack::ContentLength +use Rack::ContentType, "text/plain" +class DieIfUsed + def each + abort "body.each called after response hijack\n" + end + + def close + abort "body.close called after response hijack\n" + end +end +run lambda { |env| + case env["PATH_INFO"] + when "/hijack_req" + if env["rack.hijack?"] + io = env["rack.hijack"].call + if io.respond_to?(:read_nonblock) && + env["rack.hijack_io"].respond_to?(:read_nonblock) + return [ 200, {}, [ "hijack.OK\n" ] ] + end + end + [ 500, {}, [ "hijack BAD\n" ] ] + when "/hijack_res" + r = "response.hijacked" + [ 200, + { + "Content-Length" => r.bytesize.to_s, + "rack.hijack" => proc do |io| + io.write(r) + io.close + end + }, + DieIfUsed.new + ] + end +} diff --git a/t/t0005-working_directory_app.rb.sh b/t/t0005-working_directory_app.rb.sh index 37c6fa7..0fbab4f 100755 --- a/t/t0005-working_directory_app.rb.sh +++ b/t/t0005-working_directory_app.rb.sh @@ -11,7 +11,10 @@ t_begin "setup and start" && { cat > $t_pfx.app/fooapp.rb <<\EOF class Fooapp def self.call(env) - [ 200, [%w(Content-Type text/plain), %w(Content-Length 2)], %w(HI) ] + # Rack::Lint in 1.5.0 requires headers to be a hash + h = [%w(Content-Type text/plain), %w(Content-Length 2)] + h = Rack::Utils::HeaderHash.new(h) + [ 200, h, %w(HI) ] end end EOF diff --git a/t/t0200-rack-hijack.sh b/t/t0200-rack-hijack.sh new file mode 100755 index 0000000..23a9ee4 --- /dev/null +++ b/t/t0200-rack-hijack.sh @@ -0,0 +1,27 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 5 "rack.hijack tests (Rack 1.5+ (Rack::VERSION >= [ 1,2]))" + +t_begin "setup and start" && { + unicorn_setup + unicorn -D -c $unicorn_config hijack.ru + unicorn_wait_start +} + +t_begin "check request hijack" && { + test "xhijack.OK" = x"$(curl -sSfv http://$listen/hijack_req)" +} + +t_begin "check response hijack" && { + test "xresponse.hijacked" = x"$(curl -sSfv http://$listen/hijack_res)" +} + +t_begin "killing succeeds" && { + kill $unicorn_pid +} + +t_begin "check stderr" && { + check_stderr +} + +t_done -- cgit v1.2.3-24-ge0c7