about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-06-04 07:48:08 +0000
committerEric Wong <normalperson@yhbt.net>2010-06-04 08:18:28 +0000
commit761b4a346865267c3fef79a62b9bebcbf6277319 (patch)
tree32e764b071195faa06a6777202bb6f4041d0ca89
parent8ac80b06424350fd6088c1363661a12620040ae8 (diff)
downloadrainbows-761b4a346865267c3fef79a62b9bebcbf6277319.tar.gz
-rw-r--r--lib/rainbows/sendfile.rb65
1 files changed, 49 insertions, 16 deletions
diff --git a/lib/rainbows/sendfile.rb b/lib/rainbows/sendfile.rb
index 1fa832c..e418fd1 100644
--- a/lib/rainbows/sendfile.rb
+++ b/lib/rainbows/sendfile.rb
@@ -1,29 +1,62 @@
 # -*- encoding: binary -*-
 module Rainbows
 
-# Convert X-Sendfile headers into Rack response bodies that respond
-# to the +to_path+ method which allows certain concurrency models to
-# serve efficiently using sendfile() or similar.  With multithreaded
-# models under Ruby 1.9, IO.copy_stream will be used.
+# This middleware handles X-\Sendfile headers generated by applications
+# or middlewares down the stack.  It should be placed at the top
+# (outermost layer) of the middleware stack to avoid having its
+# +to_path+ method clobbered by another middleware.
 #
-# This middleware is recommended for EventMachine users regardless
-# of Ruby version and 1.9 users with any Thread-based concurrency
-# models.  DO NOT use this middleware if you're proxying \Rainbows!
-# with a server (e.g. Apache, Lighttpd) that understands X-Sendfile
-# natively.
+# This converts X-\Sendfile responses to bodies which respond to the
+# +to_path+ method which allows certain concurrency models to serve
+# efficiently using sendfile() or similar.  With multithreaded models
+# under Ruby 1.9, IO.copy_stream will be used.
 #
-# This does NOT understand X-Accel-Redirect headers intended for
-# nginx, that is much more complicated to configure and support
-# as it is highly coupled with the corresponding nginx configuration.
+# This middleware is the opposite of Rack::Contrib::Sendfile as it
+# reverses the effect of Rack::Contrib::Sendfile.  Unlike many Ruby
+# web servers, some configurations of \Rainbows! are capable of
+# serving static files efficiently.
+#
+# === Compatibility (via IO.copy_stream in Ruby 1.9):
+# * ThreadSpawn
+# * ThreadPool
+# * WriterThreadPool
+# * WriterThreadSpawn
+#
+# === Compatibility (Ruby 1.8 and 1.9)
+# * EventMachine
+# * NeverBlock (using EventMachine)
+#
+# DO NOT use this middleware if you're proxying to \Rainbows! with a
+# server that understands X-\Sendfile (e.g. Apache, Lighttpd) natively.
+#
+# This does NOT understand X-Accel-Redirect headers intended for nginx.
+# X-Accel-Redirect requires the application to be highly coupled with
+# the corresponding nginx configuration, and is thus too complicated to
+# be worth supporting.
+#
+# Example config.ru:
+#
+#    use Rainbows::Sendfile
+#    run lambda { |env|
+#      path = "#{Dir.pwd}/random_blob"
+#      [ 200,
+#        {
+#          'X-Sendfile' => path,
+#          'Content-Type' => 'application/octet-stream'
+#        },
+#        []
+#      ]
+#    }
 
 class Sendfile < Struct.new(:app)
 
-  # :nodoc:
+  # :stopdoc:
   HH = Rack::Utils::HeaderHash
+  # :startdoc:
 
   # Body wrapper, this allows us to fall back gracefully to
-  # #each in case a given concurrency model does not optimize
-  # #to_path calls.
+  # +each+ in case a given concurrency model does not optimize
+  # +to_path+ calls.
   class Body < Struct.new(:to_io)
 
     def initialize(path, headers)
@@ -41,7 +74,7 @@ class Sendfile < Struct.new(:app)
       to_io.path
     end
 
-    # fallback in case our #to_path doesn't get handled for whatever reason
+    # fallback in case our +to_path+ doesn't get handled for whatever reason
     def each(&block)
       buf = ''
       while to_io.read(0x4000, buf)