From 32d3b1f052810eb15362d001d1501be0e2da88d8 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 28 Aug 2010 06:50:51 +0000 Subject: "keepalive_timeout 0" (really) disables keepalive Although this behavior is mentioned on the documentation, this was broken under EventMachine, Rev*, and Revactor. Furthermore, we set the "Connection: close" header to allow the client to optimize is handling of non-keepalive connections. --- lib/rainbows/event_machine.rb | 3 ++- lib/rainbows/response.rb | 1 + lib/rainbows/rev/heartbeat.rb | 2 +- lib/rainbows/revactor.rb | 2 +- t/t0017-keepalive-timeout-zero.sh | 43 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100755 t/t0017-keepalive-timeout-zero.sh diff --git a/lib/rainbows/event_machine.rb b/lib/rainbows/event_machine.rb index 2a41015..cf59cbf 100644 --- a/lib/rainbows/event_machine.rb +++ b/lib/rainbows/event_machine.rb @@ -95,7 +95,8 @@ module Rainbows # long-running async response (response.nil? || -1 == response[0]) and return @state = :close - em_write_response(response, alive = @hp.keepalive? && G.alive) + alive = @hp.keepalive? && G.alive && G.kato > 0 + em_write_response(response, alive) if alive @env.clear @hp.reset diff --git a/lib/rainbows/response.rb b/lib/rainbows/response.rb index 3e196d1..ac09d6c 100644 --- a/lib/rainbows/response.rb +++ b/lib/rainbows/response.rb @@ -34,6 +34,7 @@ module Rainbows::Response # called after forking def self.setup(klass) + Rainbows::G.kato == 0 and KEEP_ALIVE.replace(CLOSE) range_class = body_class = klass case Rainbows::Const::RACK_DEFAULTS['rainbows.model'] when :WriterThreadSpawn diff --git a/lib/rainbows/rev/heartbeat.rb b/lib/rainbows/rev/heartbeat.rb index da1a1e2..f348a08 100644 --- a/lib/rainbows/rev/heartbeat.rb +++ b/lib/rainbows/rev/heartbeat.rb @@ -11,7 +11,7 @@ module Rainbows class Heartbeat < ::Rev::TimerWatcher def on_timer - if (ot = G.kato) > 0 + if (ot = G.kato) >= 0 ot = Time.now - ot KATO.delete_if { |client, time| time < ot and client.timeout? } end diff --git a/lib/rainbows/revactor.rb b/lib/rainbows/revactor.rb index 10b7d3c..388efa6 100644 --- a/lib/rainbows/revactor.rb +++ b/lib/rainbows/revactor.rb @@ -62,7 +62,7 @@ module Rainbows::Revactor if hp.headers? headers = HH.new(headers) range = make_range!(env, status, headers) and status = range.shift - env = false unless hp.keepalive? && G.alive + env = false unless hp.keepalive? && G.alive && G.kato > 0 headers[CONNECTION] = env ? KEEP_ALIVE : CLOSE client.write(response_header(status, headers)) end diff --git a/t/t0017-keepalive-timeout-zero.sh b/t/t0017-keepalive-timeout-zero.sh new file mode 100755 index 0000000..4ba5dd0 --- /dev/null +++ b/t/t0017-keepalive-timeout-zero.sh @@ -0,0 +1,43 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 6 "keepalive_timeout 0 tests for $model" + +t_begin "setup and start" && { + rainbows_setup $model 2 0 + grep 'keepalive_timeout 0' $unicorn_config + rainbows -D env.ru -c $unicorn_config + rainbows_wait_start +} + +t_begin 'check server responds with Connection: close' && { + curl -sSfi http://$listen/ | grep 'Connection: close' +} + +t_begin "send keepalive response that does not expect close" && { + req='GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' + t0=$(date +%s) + ( + cat $fifo > $tmp & + printf "$req" + wait + date +%s > $ok + ) | socat - TCP:$listen > $fifo + now="$(cat $ok)" + elapsed=$(( $now - $t0 )) + t_info "elapsed=$elapsed (expecting <=3)" + test $elapsed -le 3 +} + +t_begin "'Connection: close' header set" && { + grep 'Connection: close' $tmp +} + +t_begin "killing succeeds" && { + kill $rainbows_pid +} + +t_begin "check stderr" && { + check_stderr +} + +t_done -- cgit v1.2.3-24-ge0c7