about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-02-25 19:43:06 -0800
committerEric Wong <normalperson@yhbt.net>2011-02-25 19:43:06 -0800
commite4ab2cc40bdbd1698f4bcf138e83c4823d118f81 (patch)
treeed48282dc431920b3163164f0224381c624ee69a
parentfcf99bd7e3323ea99c5bfc8a3a15fbbc18cc8285 (diff)
downloadraindrops-e4ab2cc40bdbd1698f4bcf138e83c4823d118f81.tar.gz
We need to do this for apps that depend on things like the
sendfile() optimizations in Rainbows!
-rw-r--r--lib/raindrops/middleware.rb41
-rw-r--r--test/test_middleware.rb17
2 files changed, 43 insertions, 15 deletions
diff --git a/lib/raindrops/middleware.rb b/lib/raindrops/middleware.rb
index 79496fc..ea19ffc 100644
--- a/lib/raindrops/middleware.rb
+++ b/lib/raindrops/middleware.rb
@@ -31,29 +31,44 @@ class Raindrops::Middleware
 
   # standard Rack endpoint
   def call(env)
-    env[PATH_INFO] == @path ? stats_response : dup._call(env)
-  end
+    env[PATH_INFO] == @path and return stats_response
 
-  def _call(env)
     @stats.incr_calling
-    status, headers, @app = @app.call(env)
+
+    status, headers, body = @app.call(env)
+    rv = [ status, headers, Proxy.new(body, @stats) ]
 
     # the Rack server will start writing headers soon after this method
     @stats.incr_writing
-    [ status, headers, self ]
+    rv
     ensure
       @stats.decr_calling
   end
 
-  # yield to the Rack server here for writing
-  def each
-    @app.each { |x| yield x }
-  end
+  class Proxy
+    def initialize(body, stats)
+      @body, @stats = body, stats
+    end
+
+    # yield to the Rack server here for writing
+    def each
+      @body.each { |x| yield x }
+    end
 
-  # the Rack server should call this after #each (usually ensure-d)
-  def close
-    @stats.decr_writing
-    @app.close if @app.respond_to?(:close)
+    # the Rack server should call this after #each (usually ensure-d)
+    def close
+      @stats.decr_writing
+      @body.close if @body.respond_to?(:close)
+    end
+
+    def to_path
+      @body.to_path
+    end
+
+    def respond_to?(m)
+      m = m.to_sym
+      :close == m || @body.respond_to?(m)
+    end
   end
 
   def stats_response
diff --git a/test/test_middleware.rb b/test/test_middleware.rb
index e2fdc38..eedf04a 100644
--- a/test/test_middleware.rb
+++ b/test/test_middleware.rb
@@ -14,7 +14,7 @@ class TestMiddleware < Test::Unit::TestCase
     app = Raindrops::Middleware.new(@app)
     response = app.call({})
     assert_equal @response[0,2], response[0,2]
-    assert response.last.kind_of?(Raindrops::Middleware)
+    assert response.last.kind_of?(Raindrops::Middleware::Proxy)
     assert response.last.object_id != app.object_id
     tmp = []
     response.last.each { |y| tmp << y }
@@ -35,7 +35,7 @@ class TestMiddleware < Test::Unit::TestCase
     assert_equal 0, stats.calling
     assert_equal 1, stats.writing
     assert_equal 200, response[0]
-    assert response.last.kind_of?(Raindrops::Middleware)
+    assert response.last.kind_of?(Raindrops::Middleware::Proxy)
     tmp = []
     response.last.each do |y|
       assert_equal 1, stats.writing
@@ -108,4 +108,17 @@ class TestMiddleware < Test::Unit::TestCase
     assert_equal expect, response
   end
 
+  def test_middleware_proxy_to_path_missing
+    app = Raindrops::Middleware.new(@app)
+    response = app.call({})
+    body = response[2]
+    assert_kind_of Raindrops::Middleware::Proxy, body
+    assert ! body.respond_to?(:to_path)
+    assert body.respond_to?(:close)
+    orig_body = @response[2]
+
+    def orig_body.to_path; "/dev/null"; end
+    assert body.respond_to?(:to_path)
+    assert_equal "/dev/null", body.to_path
+  end
 end