Class: Rainbows::Sendfile
- Inherits:
-
Struct
- Object
- Struct
- Rainbows::Sendfile
- Defined in:
- lib/rainbows/sendfile.rb
Overview
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 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 middleware is the opposite of Rack::Sendfile as it reverses the effect of Rack:::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'
},
[]
]
}
Defined Under Namespace
Classes: Body
Instance Attribute Summary collapse
-
#app ⇒ Object
Returns the value of attribute app.
Instance Method Summary collapse
-
#call(env) ⇒ Object
:nodoc:.
Instance Attribute Details
#app ⇒ Object
Returns the value of attribute app
49 50 51 |
# File 'lib/rainbows/sendfile.rb', line 49 def app @app end |
Instance Method Details
#call(env) ⇒ Object
:nodoc:
72 73 74 75 76 77 78 79 |
# File 'lib/rainbows/sendfile.rb', line 72 def call(env) # :nodoc: status, headers, body = app.call(env) headers = Rack::Utils::HeaderHash.new(headers) unless Hash === headers if path = headers.delete('X-Sendfile'.freeze) body = Body.new(path, headers) unless body.respond_to?(:to_path) end [ status, headers, body ] end |