diff --git a/app/jobs/regular/pull_hotlinked_images.rb b/app/jobs/regular/pull_hotlinked_images.rb index e7142b9ee5a..fbeddbdf74d 100644 --- a/app/jobs/regular/pull_hotlinked_images.rb +++ b/app/jobs/regular/pull_hotlinked_images.rb @@ -21,6 +21,7 @@ module Jobs return unless post.present? raw = post.raw.dup + start_raw = raw.dup downloaded_urls = {} extract_images_from(post.cooked).each do |image| @@ -28,9 +29,10 @@ module Jobs src = "http:" + src if src.start_with?("//") if is_valid_image_url(src) + hotlinked = nil begin # have we already downloaded that file? - if !downloaded_urls.include?(src) + unless downloaded_urls.include?(src) begin hotlinked = FileHelper.download(src, @max_size, "discourse-hotlinked") rescue Discourse::InvalidParameters @@ -71,10 +73,15 @@ module Jobs end - # TODO: make sure the post hasn“t changed while we were downloading remote images - if raw != post.raw + post.reload + if start_raw != post.raw + # post was edited - start over (after 10 minutes) + backoff = args.fetch(:backoff, 1) + 1 + delay = SiteSetting.ninja_edit_window * args[:backoff] + Jobs.enqueue_in(delay.seconds.to_i, :pull_hotlinked_images, args.merge!(backoff: backoff)) + elsif raw != post.raw options = { edit_reason: I18n.t("upload.edit_reason") } - options[:bypass_bump] = true if args[:bypass_bump] == true + options[:bypass_bump] = !!args[:bypass_bump] post.revise(Discourse.system_user, raw, options) end end @@ -87,7 +94,8 @@ module Jobs def is_valid_image_url(src) src.present? && !Discourse.store.has_been_uploaded?(src) && - !src.start_with?(Discourse.asset_host || Discourse.base_url_no_prefix) + !src.start_with?(Discourse.asset_host || Discourse.base_url_no_prefix) && + SiteSetting.should_download_images?(src) end end diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index ee820aaed6b..f1636335bd2 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -72,6 +72,16 @@ class SiteSetting < ActiveRecord::Base .first end + def self.should_download_images?(src) + setting = disabled_image_download_domains + return true unless setting.present? + host = URI.parse(src).host + + return !(setting.split('|').include?(host)) + rescue URI::InvalidURIError + return true + end + def self.scheme use_https? ? "https" : "http" end diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 75334161005..7a3d729f12d 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -605,6 +605,7 @@ en: crawl_images: "Enable retrieving images from third party sources to insert width and height dimensions" download_remote_images_to_local: "Download a copy of remote images hotlinked in posts" download_remote_images_threshold: "Amount of minimum available disk space required to download remote images locally (in percent)" + disabled_image_download_domains: "A pipe-delimited list of domains from which linked images will never be downloaded." ninja_edit_window: "Number of seconds after posting where edits do not create a new version" post_edit_time_limit: "Amount of time in minutes in which posts can be edited and deleted by the author. Set to 0 to allow editing and deleting posts at any time." edit_history_visible_to_public: "Allow everyone to see previous versions of an edited post. When disabled, only staff members can view edit history." diff --git a/config/site_settings.yml b/config/site_settings.yml index fd08b32a69a..2362f9b939a 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -302,6 +302,9 @@ files: test: false default: true download_remote_images_threshold: 20 + disabled_image_download_domains: + list: true + default: '' create_thumbnails: true clean_up_uploads: false clean_orphan_uploads_grace_period_hours: 1