Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #1875 from esad/master

Fixed issue #1847
  • Loading branch information...
commit 4f372cf4d9f48b76ae3472009167addd26b7d941 2 parents 9921eca + 2a61d47
@josevalim josevalim authored
View
15 actionpack/lib/action_controller/metal/data_streaming.rb
@@ -26,8 +26,11 @@ module DataStreaming
# 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 @@ def send_file(path, options = {}) #:doc:
# * <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 @@ def send_data(data, options = {}) #:doc:
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 @@ def send_file_headers!(options)
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
View
12 actionpack/lib/action_dispatch/http/mime_types.rb
@@ -7,11 +7,23 @@
Mime::Type.register "text/css", :css
Mime::Type.register "text/calendar", :ics
Mime::Type.register "text/csv", :csv
+
+Mime::Type.register "image/png", :png, [], %w(png)
+Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe)
+Mime::Type.register "image/gif", :gif, [], %w(gif)
+Mime::Type.register "image/bmp", :bmp, [], %w(bmp)
+Mime::Type.register "image/tiff", :tiff, [], %w(tif tiff)
+
+Mime::Type.register "video/mpeg", :mpeg, [], %w(mpg mpeg mpe)
+
Mime::Type.register "application/xml", :xml, %w( text/xml application/x-xml )
Mime::Type.register "application/rss+xml", :rss
Mime::Type.register "application/atom+xml", :atom
Mime::Type.register "application/x-yaml", :yaml, %w( text/yaml )
+Mime::Type.register "application/pdf", :pdf, [], %w(pdf)
+Mime::Type.register "application/zip", :zip, [], %w(zip)
+
Mime::Type.register "multipart/form-data", :multipart_form
Mime::Type.register "application/x-www-form-urlencoded", :url_encoded_form
View
19 actionpack/test/controller/send_file_test.rb
@@ -138,6 +138,25 @@ def test_send_file_headers_with_bad_symbol
@controller.headers = {}
assert_raise(ArgumentError){ @controller.send(:send_file_headers!, options) }
end
+
+ def test_send_file_headers_guess_type_from_extension
+ {
+ 'image.png' => 'image/png',
+ 'image.jpeg' => 'image/jpeg',
+ 'image.jpg' => 'image/jpeg',
+ 'image.tif' => 'image/tiff',
+ 'image.gif' => 'image/gif',
+ 'movie.mpg' => 'video/mpeg',
+ 'file.zip' => 'application/zip',
+ 'file.unk' => 'application/octet-stream',
+ 'zip' => 'application/octet-stream'
+ }.each do |filename,expected_type|
+ options = { :filename => filename }
+ @controller.headers = {}
+ @controller.send(:send_file_headers!, options)
+ assert_equal expected_type, @controller.content_type
+ end
+ end
%w(file data).each do |method|
define_method "test_send_#{method}_status" do
Please sign in to comment.
Something went wrong with that request. Please try again.