Commit 6475a4d3a3bef0a553b844b13068b077e78f3146

Authored by Braulio Bhavamitra
Committed by Rodrigo Souto
1 parent bb031599

Force a browser to save file as after clicking a uploaded file link

(ActionItem2829)
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/fixtures/files/500.html 0 → 120000
... ... @@ -0,0 +1 @@
  1 +../../../public/500.html
0 2 \ No newline at end of file
... ...
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')
... ...