# the `gs` binary. Used to generate attachment thumbnails of PDF files.
#gs_command:
+ # Timeout when generating thumbnails using the `convert` or `gs` command.
+ # Timeout is set in seconds.
+ #thumbnails_generation_timeout: 10
+
# Configuration of MiniMagick font.
#
# Redmine uses MiniMagick in order to export a gantt chart to a PNG image.
'avatar_server_url' => 'https://www.gravatar.com',
'email_delivery' => nil,
'max_concurrent_ajax_uploads' => 2,
- 'common_mark_enable_hardbreaks' => true
+ 'common_mark_enable_hardbreaks' => true,
+ 'thumbnails_generation_timeout' => 10
}
@config = nil
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'fileutils'
+require 'timeout'
module Redmine
module Thumbnail
else
cmd = "#{shell_quote CONVERT_BIN} #{shell_quote source} -auto-orient -thumbnail #{shell_quote size_option} #{shell_quote target}"
end
- unless system(cmd)
- logger.error("Creating thumbnail failed (#{$?}):\nCommand: #{cmd}")
+
+ pid = nil
+ begin
+ Timeout.timeout(Redmine::Configuration['thumbnails_generation_timeout'].to_i) do
+ pid = Process.spawn(cmd)
+ _, status = Process.wait2(pid)
+ unless status.success?
+ logger.error("Creating thumbnail failed (#{status.exitstatus}):\nCommand: #{cmd}")
+ return nil
+ end
+ end
+ rescue Timeout::Error
+ Process.kill('KILL', pid)
+ logger.error("Creating thumbnail timed out:\nCommand: #{cmd}")
return nil
end
end
ensure
set_tmp_attachments_directory
end
+
+ def test_thumbnail_should_timeout
+ dummy_pid = 37530
+ Process.stubs(:spawn).returns(dummy_pid)
+ Process.stubs(:wait2).raises(Timeout::Error)
+ Process.stubs(:kill).returns(1)
+ Process.stubs(:wait).returns(dummy_pid)
+ Rails.logger.expects(:error).with(regexp_matches(/Creating thumbnail timed out/))
+
+ set_fixtures_attachments_directory
+ Attachment.clear_thumbnails
+
+ attachment = Attachment.find(16)
+ thumbnail = attachment.thumbnail
+
+ assert_nil thumbnail
+ ensure
+ set_tmp_attachments_directory
+ end
else
puts '(ImageMagick convert not available)'
end