Commit 6475a4d3a3bef0a553b844b13068b077e78f3146
Committed by
Rodrigo Souto
1 parent
bb031599
Exists in
master
and in
22 other branches
Force a browser to save file as after clicking a uploaded file link
(ActionItem2829)
Showing
5 changed files
with
36 additions
and
6 deletions
Show diff stats
app/controllers/public/content_viewer_controller.rb
| ... | ... | @@ -53,8 +53,9 @@ class ContentViewerController < ApplicationController |
| 53 | 53 | # At this point the page will be showed |
| 54 | 54 | @page.hit |
| 55 | 55 | |
| 56 | - unless @page.mime_type == 'text/html' || (@page.image? && params[:view]) | |
| 56 | + if @page.download? params[:view] | |
| 57 | 57 | headers['Content-Type'] = @page.mime_type |
| 58 | + headers.merge! @page.download_headers | |
| 58 | 59 | data = @page.data |
| 59 | 60 | |
| 60 | 61 | # TODO test the condition |
| ... | ... | @@ -70,7 +71,7 @@ class ContentViewerController < ApplicationController |
| 70 | 71 | |
| 71 | 72 | #FIXME see a better way to do this. It's not need to pass this variable anymore |
| 72 | 73 | @comment = Comment.new |
| 73 | - | |
| 74 | + | |
| 74 | 75 | if @page.has_posts? |
| 75 | 76 | posts = if params[:year] and params[:month] |
| 76 | 77 | filter_date = DateTime.parse("#{params[:year]}-#{params[:month]}-01") | ... | ... |
app/models/article.rb
| ... | ... | @@ -188,7 +188,7 @@ class Article < ActiveRecord::Base |
| 188 | 188 | pending_categorizations.clear |
| 189 | 189 | end |
| 190 | 190 | |
| 191 | - acts_as_taggable | |
| 191 | + acts_as_taggable | |
| 192 | 192 | N_('Tag list') |
| 193 | 193 | |
| 194 | 194 | acts_as_filesystem |
| ... | ... | @@ -268,7 +268,7 @@ class Article < ActiveRecord::Base |
| 268 | 268 | end |
| 269 | 269 | |
| 270 | 270 | # returns the data of the article. Must be overriden in each subclass to |
| 271 | - # provide the correct content for the article. | |
| 271 | + # provide the correct content for the article. | |
| 272 | 272 | def data |
| 273 | 273 | body |
| 274 | 274 | end |
| ... | ... | @@ -360,6 +360,16 @@ class Article < ActiveRecord::Base |
| 360 | 360 | false |
| 361 | 361 | end |
| 362 | 362 | |
| 363 | + def download? view = nil | |
| 364 | + (self.uploaded_file? and not self.image?) or | |
| 365 | + (self.image? and view.blank?) or | |
| 366 | + (not self.uploaded_file? and self.mime_type != 'text/html') | |
| 367 | + end | |
| 368 | + | |
| 369 | + def download_headers | |
| 370 | + {} | |
| 371 | + end | |
| 372 | + | |
| 363 | 373 | named_scope :native_translations, :conditions => { :translation_of_id => nil } |
| 364 | 374 | |
| 365 | 375 | def translatable? | ... | ... |
app/models/uploaded_file.rb
| ... | ... | @@ -86,6 +86,12 @@ class UploadedFile < Article |
| 86 | 86 | self.name = self.filename |
| 87 | 87 | end |
| 88 | 88 | |
| 89 | + def download_headers | |
| 90 | + { | |
| 91 | + 'Content-Disposition' => "attachment; filename=\"#{self.filename}\"", | |
| 92 | + } | |
| 93 | + end | |
| 94 | + | |
| 89 | 95 | def data |
| 90 | 96 | File.read(self.full_filename) |
| 91 | 97 | end | ... | ... |
test/functional/content_viewer_controller_test.rb
| ... | ... | @@ -64,7 +64,19 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 64 | 64 | assert_response :missing |
| 65 | 65 | end |
| 66 | 66 | |
| 67 | - should 'produce a download-like when article is not text/html' do | |
| 67 | + should 'produce a download-link when article is a uploaded file' do | |
| 68 | + profile = create_user('someone').person | |
| 69 | + html = UploadedFile.create! :uploaded_data => fixture_file_upload('/files/500.html', 'text/html'), :profile => profile | |
| 70 | + html.save! | |
| 71 | + | |
| 72 | + get :view_page, :profile => 'someone', :page => [ '500.html' ] | |
| 73 | + | |
| 74 | + assert_response :success | |
| 75 | + assert_match /^text\/html/, @response.headers['Content-Type'] | |
| 76 | + assert @response.headers['Content-Disposition'].present? | |
| 77 | + end | |
| 78 | + | |
| 79 | + should 'produce a download-link when article is not text/html' do | |
| 68 | 80 | |
| 69 | 81 | # for example, RSS feeds |
| 70 | 82 | profile = create_user('someone').person |
| ... | ... | @@ -1254,7 +1266,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1254 | 1266 | |
| 1255 | 1267 | get 'view_page', :profile => profile.identifier, :page => article.path.split('/') |
| 1256 | 1268 | assert_tag :tag => 'a', :attributes => { :href => "/#{profile.identifier}/#{article.path}?comment_page=2", :rel => 'next' } |
| 1257 | - end | |
| 1269 | + end | |
| 1258 | 1270 | |
| 1259 | 1271 | should 'not escape acceptable HTML in list of blog posts' do |
| 1260 | 1272 | login_as('testinguser') | ... | ... |