diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index aa8bbeec9..2135b3f57 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -20,6 +20,8 @@ class AttachmentsController < ApplicationController include ActionView::Helpers::NumberHelper + BROWSER_CACHE_LIFETIME = 1.day + before_action :find_attachment, :only => [:show, :download, :thumbnail, :update, :destroy] before_action :find_container, :only => [:edit_all, :update_all, :download_all] before_action :find_downloadable_attachments, :only => :download_all @@ -74,6 +76,7 @@ class AttachmentsController < ApplicationController @attachment.increment_download end + expires_in BROWSER_CACHE_LIFETIME if stale?(:etag => @attachment.digest, :template => false) # images are sent inline send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename), @@ -84,6 +87,9 @@ class AttachmentsController < ApplicationController def thumbnail if @attachment.thumbnailable? && tbnail = @attachment.thumbnail(:size => params[:size]) + # Should not be cached if params[:size] is not explicitly set + # because the content varies depending on Setting.thumbnails_size + expires_in BROWSER_CACHE_LIFETIME if params[:size].present? if stale?(:etag => tbnail, :template => false) send_file( tbnail, diff --git a/test/functional/attachments_controller_test.rb b/test/functional/attachments_controller_test.rb index 43d7c35e0..42232c1aa 100644 --- a/test/functional/attachments_controller_test.rb +++ b/test/functional/attachments_controller_test.rb @@ -304,6 +304,7 @@ class AttachmentsControllerTest < Redmine::ControllerTest assert_equal 'application/x-ruby', @response.media_type etag = @response.etag assert_not_nil etag + assert_equal ['max-age=86400', 'private'], response.headers['Cache-Control'].split(', ').sort @request.env["HTTP_IF_NONE_MATCH"] = etag get(:download, :params => {:id => 4}) @@ -442,6 +443,31 @@ class AttachmentsControllerTest < Redmine::ControllerTest ) assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fthumbnail%2F16' end + + def test_thumbnail_should_set_cache_control_header + Attachment.clear_thumbnails + @request.session[:user_id] = 2 + get( + :thumbnail, + :params => { + :id => 16, + :size => 200 + } + ) + assert_response :success + assert_equal ['max-age=86400', 'private'], response.headers['Cache-Control'].split(', ').sort + + get( + :thumbnail, + :params => { + :id => 16 + } + ) + assert_response :success + # Should not be cached if params[:size] is not explicitly set + # because the content varies depending on Setting.thumbnails_size + assert_equal ['private'], response.headers['Cache-Control'].split(', ').sort + end else puts '(ImageMagick convert not available)' end