aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2015-10-05 16:50:37 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2015-10-05 16:50:50 -0700
commit69009f4473637a44ade26d954ef5ddea6ff903f2 (patch)
tree4dae45acf6e72e2a6e6e7110c07e8677038fec2c /actionpack/lib/action_dispatch
parent76698441453821fb175799b99099322688bde6c1 (diff)
downloadrails-69009f4473637a44ade26d954ef5ddea6ff903f2.tar.gz
rails-69009f4473637a44ade26d954ef5ddea6ff903f2.tar.bz2
rails-69009f4473637a44ade26d954ef5ddea6ff903f2.zip
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.
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb40
1 files changed, 39 insertions, 1 deletions
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 }