public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Allow use of symbols for :type option of 
ActionController::Streaming#send_file/#send_data [#1232 state:resolved]

Signed-off-by: Frederick Cheung <frederick.cheung@gmail.com>
metatribe (author)
Sun Dec 21 10:58:55 -0800 2008
fcheung (committer)
Sun Dec 21 10:58:55 -0800 2008
commit  fcd58dc27a99085b161f2463988d4ee373d44ec6
tree    b137e8fcc185c97068aeae54d8927c6bb3d8f243
parent  7cda0df7f1511a10c515165dbce76e5c68b654ff
...
24
25
26
27
 
 
28
29
30
...
107
108
109
110
 
 
111
112
113
...
143
144
145
 
 
 
 
 
 
 
146
147
148
 
149
150
151
...
24
25
26
 
27
28
29
30
31
...
108
109
110
 
111
112
113
114
115
...
145
146
147
148
149
150
151
152
153
154
155
156
 
157
158
159
160
0
@@ -24,7 +24,8 @@ module ActionController #:nodoc:
0
       # Options:
0
       # * <tt>:filename</tt> - suggests a filename for the browser to use.
0
       #   Defaults to <tt>File.basename(path)</tt>.
0
-      # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
0
+      # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
0
+      #   either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
0
       # * <tt>:length</tt> - used to manually override the length (in bytes) of the content that
0
       #   is going to be sent to the client. Defaults to <tt>File.size(path)</tt>.
0
       # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
0
@@ -107,7 +108,8 @@ module ActionController #:nodoc:
0
       #
0
       # Options:
0
       # * <tt>:filename</tt> - suggests a filename for the browser to use.
0
-      # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
0
+      # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
0
+      #   either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
0
       # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
0
       #   Valid values are 'inline' and 'attachment' (default).
0
       # * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
0
@@ -143,9 +145,16 @@ module ActionController #:nodoc:
0
 
0
         disposition <<= %(; filename="#{options[:filename]}") if options[:filename]
0
 
0
+        content_type = options[:type]
0
+        if content_type.is_a?(Symbol)
0
+          raise ArgumentError, "Unknown MIME type #{options[:type]}" unless Mime::EXTENSION_LOOKUP.has_key?(content_type.to_s)
0
+          content_type = Mime::Type.lookup_by_extension(content_type.to_s)
0
+        end
0
+        content_type = content_type.to_s.strip # fixes a problem with extra '\r' with some browsers
0
+
0
         headers.update(
0
           'Content-Length'            => options[:length],
0
-          'Content-Type'              => options[:type].to_s.strip,  # fixes a problem with extra '\r' with some browsers
0
+          'Content-Type'              => content_type,
0
           'Content-Disposition'       => disposition,
0
           'Content-Transfer-Encoding' => 'binary'
0
         )
...
119
120
121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
123
124
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
0
@@ -119,6 +119,31 @@ class SendFileTest < Test::Unit::TestCase
0
     assert_equal 'private', h['Cache-Control']
0
   end
0
 
0
+  def test_send_file_headers_with_mime_lookup_with_symbol
0
+    options = {
0
+      :length => 1,
0
+      :type => :png
0
+    }
0
+
0
+    @controller.headers = {}
0
+    @controller.send(:send_file_headers!, options)
0
+
0
+    headers = @controller.headers
0
+
0
+    assert_equal 'image/png', headers['Content-Type']
0
+  end
0
+  
0
+
0
+  def test_send_file_headers_with_bad_symbol
0
+    options = {
0
+      :length => 1,
0
+      :type => :this_type_is_not_registered
0
+    }
0
+
0
+    @controller.headers = {}
0
+    assert_raises(ArgumentError){ @controller.send(:send_file_headers!, options) }
0
+  end
0
+
0
   %w(file data).each do |method|
0
     define_method "test_send_#{method}_status" do
0
       @controller.options = { :stream => false, :status => 500 }

Comments