about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/rainbows/event_machine.rb20
-rw-r--r--t/fast-pipe-response.ru12
-rwxr-xr-xt/t0030-fast-pipe-response.sh36
3 files changed, 63 insertions, 5 deletions
diff --git a/lib/rainbows/event_machine.rb b/lib/rainbows/event_machine.rb
index 77fc962..4d5156e 100644
--- a/lib/rainbows/event_machine.rb
+++ b/lib/rainbows/event_machine.rb
@@ -106,11 +106,8 @@ module Rainbows
         else
           do_chunk = false
         end
-        if do_chunk
-          EM.watch(io, ResponseChunkPipe, self).notify_readable = true
-        else
-          EM.enable_proxy(EM.attach(io, ResponsePipe, self), self, 16384)
-        end
+        mod = do_chunk ? ResponseChunkPipe : ResponsePipe
+        EM.watch(io, mod, self).notify_readable = true
       end
 
       def em_write_response(response, alive = false)
@@ -165,6 +162,19 @@ module Rainbows
         @client = client
       end
 
+      def notify_readable
+        begin
+          @client.write(@io.read_nonblock(16384))
+        rescue Errno::EINTR
+          retry
+        rescue Errno::EAGAIN
+          return
+        rescue EOFError
+          detach
+          return
+        end while true
+      end
+
       def unbind
         @io.close
         @client.quit
diff --git a/t/fast-pipe-response.ru b/t/fast-pipe-response.ru
new file mode 100644
index 0000000..01f4d59
--- /dev/null
+++ b/t/fast-pipe-response.ru
@@ -0,0 +1,12 @@
+# must be run without Rack::Lint since that clobbers to_path
+use Rainbows::DevFdResponse
+run(lambda { |env|
+  env['rainbows.autochunk'] = false
+  [ 200,
+    {
+      'X-Rainbows-Autochunk' => 'no',
+      'Content-Length' => ::File.stat('random_blob').size.to_s,
+      'Content-Type' => 'application/octet-stream',
+    },
+    IO.popen('cat random_blob', 'rb') ]
+})
diff --git a/t/t0030-fast-pipe-response.sh b/t/t0030-fast-pipe-response.sh
new file mode 100755
index 0000000..5acbc01
--- /dev/null
+++ b/t/t0030-fast-pipe-response.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+. ./test-lib.sh
+test -r random_blob || die "random_blob required, run with 'make $0'"
+
+t_plan 6 "fast pipe response for $model"
+
+t_begin "setup and startup" && {
+        rtmpfiles err
+        rainbows_setup $model
+        rainbows -E none -D fast-pipe-response.ru -c $unicorn_config
+        rainbows_wait_start
+}
+
+t_begin "read random blob sha1" && {
+        random_blob_sha1=$(rsha1 < random_blob)
+}
+
+t_begin "single request matches" && {
+        sha1=$(curl -sSfv 2> $err http://$listen/ | rsha1)
+        test -n "$sha1"
+        test x"$sha1" = x"$random_blob_sha1"
+}
+
+t_begin "Content-Length header preserved in response" && {
+        grep "^< Content-Length:" $err
+}
+
+t_begin "shutdown server" && {
+        kill -QUIT $rainbows_pid
+}
+
+dbgcat r_err
+
+t_begin "check stderr" && check_stderr
+
+t_done