aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller
diff options
context:
space:
mode:
authorEsad Hajdarevic <esad@esse.at>2011-06-28 06:57:41 +0200
committerEsad Hajdarevic <esad@esse.at>2011-06-28 06:58:28 +0200
commit2a61d47b5537bf94fae2f2c4cb97569a71a09fd7 (patch)
treeb7c167913424932d9c8732c22ea62a8dd5eebc2e /actionpack/lib/action_controller
parentd73269ba53992d8a01e5721aad3d23bc2b11dc4f (diff)
downloadrails-2a61d47b5537bf94fae2f2c4cb97569a71a09fd7.tar.gz
rails-2a61d47b5537bf94fae2f2c4cb97569a71a09fd7.tar.bz2
rails-2a61d47b5537bf94fae2f2c4cb97569a71a09fd7.zip
Make send_file guess content-type from file extension, if type wasn't supplied (Issue #1847). Update tests & documentation.
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r--actionpack/lib/action_controller/metal/data_streaming.rb15
1 files changed, 13 insertions, 2 deletions
diff --git a/actionpack/lib/action_controller/metal/data_streaming.rb b/actionpack/lib/action_controller/metal/data_streaming.rb
index 623a9873fc..50827d8107 100644
--- a/actionpack/lib/action_controller/metal/data_streaming.rb
+++ b/actionpack/lib/action_controller/metal/data_streaming.rb
@@ -26,8 +26,11 @@ module ActionController #:nodoc:
# Options:
# * <tt>:filename</tt> - suggests a filename for the browser to use.
# Defaults to <tt>File.basename(path)</tt>.
- # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
- # either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
+ # * <tt>:type</tt> - specifies an HTTP content type.
+ # You can specify either a string or a symbol for a registered type register with
+ # <tt>Mime::Type.register</tt>, for example :json
+ # If omitted, type will be guessed from the file extension specified in <tt>:filename</tt>.
+ # If no content type is registered for the extension, default type 'application/octet-stream' will be used.
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
# Valid values are 'inline' and 'attachment' (default).
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
@@ -84,6 +87,8 @@ module ActionController #:nodoc:
# * <tt>:filename</tt> - suggests a filename for the browser to use.
# * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
# either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
+ # If omitted, type will be guessed from the file extension specified in <tt>:filename</tt>.
+ # If no content type is registered for the extension, default type 'application/octet-stream' will be used.
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
# Valid values are 'inline' and 'attachment' (default).
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
@@ -108,6 +113,8 @@ module ActionController #:nodoc:
private
def send_file_headers!(options)
+ type_provided = options.has_key?(:type)
+
options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options))
[:type, :disposition].each do |arg|
raise ArgumentError, ":#{arg} option required" if options[arg].nil?
@@ -123,6 +130,10 @@ module ActionController #:nodoc:
raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension
self.content_type = extension
else
+ if !type_provided && options[:filename]
+ # If type wasn't provided, try guessing from file extension.
+ content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.tr('.','')) || content_type
+ end
self.content_type = content_type
end