Skip to content

Commit

Permalink
#send_file leans on Rack::Sendfile to X-Accel-Redirect the file's pat…
Browse files Browse the repository at this point in the history
…h, so opening the file to set the response body is wasteful. Set a FileBody wrapper instead that responds to to_path and streams the file if needed.
  • Loading branch information
jeremy committed Apr 12, 2012
1 parent 8248f42 commit 5c51cd0
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion actionpack/lib/action_controller/metal/data_streaming.rb
Expand Up @@ -74,7 +74,27 @@ def send_file(path, options = {}) #:doc:

self.status = options[:status] || 200
self.content_type = options[:content_type] if options.key?(:content_type)
self.response_body = File.open(path, "rb")
self.response_body = FileBody.new(path)
end

# Avoid having to pass an open file handle as the response body.
# Rack::Sendfile will usually intercepts the response and just uses
# the path directly, so no reason to open the file.
class FileBody #:nodoc:
attr_reader :to_path

def initialize(path)
@to_path = path
end

# Stream the file's contents if Rack::Sendfile isn't present.
def each
File.open(to_path, 'rb') do |file|
while chunk = file.read(16384)
yield chunk
end
end
end
end

# Sends the given binary data to the browser. This method is similar to
Expand Down

0 comments on commit 5c51cd0

Please sign in to comment.