From 69009f4473637a44ade26d954ef5ddea6ff903f2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 5 Oct 2015 16:50:37 -0700 Subject: move file sending to the response object Just a slight refactor that delegates file sending to the response object. This gives us the advantage that if a webserver (in the future) provides a response object that knows how to do accelerated file serving, it can implement this method. --- actionpack/lib/action_dispatch/http/response.rb | 40 ++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index a27ff67114..d4a534d892 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -39,7 +39,7 @@ module ActionDispatch # :nodoc: end def []=(k,v) - if @response.committed? + if @response.sending? || @response.sent? raise ActionDispatch::IllegalStateError, 'header already sent' end @@ -279,6 +279,10 @@ module ActionDispatch # :nodoc: @stream.body end + def write(string) + @stream.write string + end + EMPTY = " " # Allows you to manually set or override the response body. @@ -294,6 +298,40 @@ module ActionDispatch # :nodoc: end end + # Avoid having to pass an open file handle as the response body. + # Rack::Sendfile will usually intercept the response and uses + # the path directly, so there is no reason to open the file. + class FileBody #:nodoc: + attr_reader :to_path + + def initialize(path) + @to_path = path + end + + def body + File.binread(to_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 + + # Send the file stored at +path+ as the response body. + def send_file(path) + commit! + @stream = FileBody.new(path) + end + + def reset_body! + @stream = build_buffer(self, []) + end + def body_parts parts = [] @stream.each { |x| parts << x } -- cgit v1.2.3