about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/rainbows/event_machine.rb3
-rw-r--r--lib/rainbows/response.rb1
-rw-r--r--lib/rainbows/rev/heartbeat.rb2
-rw-r--r--lib/rainbows/revactor.rb2
-rwxr-xr-xt/t0017-keepalive-timeout-zero.sh43
5 files changed, 48 insertions, 3 deletions
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