about summary refs log tree commit homepage
path: root/lib/clogger/pure.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-06-06 05:17:14 +0000
committerEric Wong <normalperson@yhbt.net>2010-06-06 06:26:45 +0000
commitb895d3d0393a647d3602783bc53bf68e223e51c9 (patch)
treedb7a7ed6d0f3200f27617a79aacd402d809eb722 /lib/clogger/pure.rb
parentbc1d1df38d7803ce9fdae05fc5129051eeed89e0 (diff)
downloadclogger-b895d3d0393a647d3602783bc53bf68e223e51c9.tar.gz
Certain configurations of Rainbows! (and Zbatery) are able to
use the return value of body.to_path to serve static files
more efficiently.

This also allows middleware like Rack::Contrib::Sendfile to
work properly higher up the stack, too.
Diffstat (limited to 'lib/clogger/pure.rb')
-rw-r--r--lib/clogger/pure.rb24
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/clogger/pure.rb b/lib/clogger/pure.rb
index 50e4f6e..0dd5021 100644
--- a/lib/clogger/pure.rb
+++ b/lib/clogger/pure.rb
@@ -5,6 +5,9 @@
 # the original C extension code so it's not very Ruby-ish...
 class Clogger
 
+  attr_accessor :env, :status, :headers, :body
+  attr_writer :body_bytes_sent
+
   def initialize(app, opts = {})
     # trigger autoload to avoid thread-safety issues later on
     Rack::Utils::HeaderHash.new({})
@@ -30,8 +33,13 @@ class Clogger
     headers = Rack::Utils::HeaderHash.new(headers) if @need_resp
     if @wrap_body
       @reentrant = env['rack.multithread'] if @reentrant.nil?
-      @env, @status, @headers, @body = env, status, headers, body
-      return [ status, headers, @reentrant ? self.dup : self ]
+      wbody = @reentrant ? self.dup : self
+      wbody.env = env
+      wbody.status = status
+      wbody.headers = headers
+      wbody.body = body
+      wbody = Clogger::ToPath.new(wbody) if body.respond_to?(:to_path)
+      return [ status, headers, wbody ]
     end
     log(env, status, headers)
     [ status, headers, body ]
@@ -139,4 +147,16 @@ private
     }.join('')
   end
 
+  class ToPath
+    def to_path
+      rv = (body = clogger.body).to_path
+
+      # try to avoid unnecessary path lookups with to_io.stat instead of
+      # File.stat
+      clogger.body_bytes_sent =
+        (body.respond_to?(:to_io) ? body.to_io.stat : File.stat(rv)).size
+      rv
+    end
+  end
+
 end