storage manager: use canonical URL for image URLs.

Generate image URLs relative to the site's canonical URL instead of
relative to the domain of the current request.

This means that all subdomains of Danbooru - safebooru.donmai.us,
shima.donmai.us, saitou.donmai.us, and kagamihara.donmai.us - will use
image URLs from https://danbooru.donmai.us, instead of from the current
domain.

The main reason we did this before was so that we could generate either
http:// or https:// image URLs, depending on whether the current request
was HTTP or HTTPS, back when we tried to support both at the same time.
Now we support only HTTPS in production, so there's no need for this. It
was also pretty hacky, since it required storing the URL of the current
request in a per-request global variable in `CurrentUser`.

This also improves caching slightly, since users of safebooru.donmai.us
will receive cached images from danbooru.donmai.us.

Downstream boorus should make sure that the `canonical_url` and
`storage_manager` config options are set correctly. If you don't support
https:// in development, you should make sure to set the canonical_url
option to http:// instead of https://.
This commit is contained in:
evazion
2021-03-15 01:58:21 -05:00
parent f93b1fe478
commit 0f90ae0fed
4 changed files with 10 additions and 18 deletions

View File

@@ -140,7 +140,6 @@ class ApplicationController < ActionController::Base
CurrentUser.user = nil CurrentUser.user = nil
CurrentUser.ip_addr = nil CurrentUser.ip_addr = nil
CurrentUser.safe_mode = false CurrentUser.safe_mode = false
CurrentUser.root_url = root_url.chomp("/")
end end
# Skip setting the session cookie if the response is being publicly cached to # Skip setting the session cookie if the response is being publicly cached to

View File

@@ -1,5 +1,5 @@
class CurrentUser < ActiveSupport::CurrentAttributes class CurrentUser < ActiveSupport::CurrentAttributes
attribute :user, :ip_addr, :country, :root_url, :safe_mode attribute :user, :ip_addr, :country, :safe_mode
alias_method :safe_mode?, :safe_mode alias_method :safe_mode?, :safe_mode
delegate :id, to: :user, allow_nil: true delegate :id, to: :user, allow_nil: true
@@ -20,8 +20,4 @@ class CurrentUser < ActiveSupport::CurrentAttributes
scoped(user, &block) scoped(user, &block)
end end
def self.root_url
attributes[:root_url] || "https://#{Danbooru.config.hostname}"
end
end end

View File

@@ -1,11 +1,9 @@
class StorageManager class StorageManager
class Error < StandardError; end class Error < StandardError; end
DEFAULT_BASE_DIR = "#{Rails.root}/public/data"
attr_reader :base_url, :base_dir, :hierarchical, :tagged_filenames, :original_subdir attr_reader :base_url, :base_dir, :hierarchical, :tagged_filenames, :original_subdir
def initialize(base_url: default_base_url, base_dir: DEFAULT_BASE_DIR, hierarchical: false, tagged_filenames: Danbooru.config.enable_seo_post_urls, original_subdir: "") def initialize(base_url:, base_dir:, hierarchical: false, tagged_filenames: Danbooru.config.enable_seo_post_urls, original_subdir: "")
@base_url = base_url.chomp("/") @base_url = base_url.chomp("/")
@base_dir = base_dir @base_dir = base_dir
@hierarchical = hierarchical @hierarchical = hierarchical
@@ -13,10 +11,6 @@ class StorageManager
@original_subdir = original_subdir @original_subdir = original_subdir
end end
def default_base_url
"#{CurrentUser.root_url}/data"
end
# Store the given file at the given path. If a file already exists at that # Store the given file at the given path. If a file already exists at that
# location it should be overwritten atomically. Either the file is fully # location it should be overwritten atomically. Either the file is fully
# written, or an error is raised and the original file is left unchanged. The # written, or an error is raised and the original file is left unchanged. The

View File

@@ -28,14 +28,17 @@ module Danbooru
Socket.gethostname Socket.gethostname
end end
# The canonical url for the site (e.g. https://danbooru.donmai.us) # The canonical root url for the site (e.g. https://danbooru.donmai.us).
# Images will be served from this URL by default. Change this to http:// if
# you don't support HTTPS. Protip: use ngrok.com for easy HTTPS support
# during development.
def canonical_url def canonical_url
"https://#{hostname}" "https://#{Danborou.config.hostname}"
end end
# Contact email address of the admin. # Contact email address of the admin.
def contact_email def contact_email
"webmaster@#{hostname}" "webmaster@#{Danbooru.config.hostname}"
end end
# System actions, such as sending automated dmails, will be performed with # System actions, such as sending automated dmails, will be performed with
@@ -148,10 +151,10 @@ module Danbooru
def storage_manager def storage_manager
# Store files on the local filesystem. # Store files on the local filesystem.
# base_dir - where to store files (default: under public/data) # base_dir - where to store files (default: under public/data)
# base_url - where to serve files from (default: http://#{hostname}/data) # base_url - where to serve files from (default: https://#{hostname}/data)
# hierarchical: false - store files in a single directory # hierarchical: false - store files in a single directory
# hierarchical: true - store files in a hierarchical directory structure, based on the MD5 hash # hierarchical: true - store files in a hierarchical directory structure, based on the MD5 hash
StorageManager::Local.new(base_url: "#{CurrentUser.root_url}/data", base_dir: Rails.root.join("public/data"), hierarchical: false) StorageManager::Local.new(base_url: "#{Danbooru.config.canonical_url}/data", base_dir: Rails.root.join("public/data"), hierarchical: false)
# Store files on one or more remote host(s). Configure SSH settings in # Store files on one or more remote host(s). Configure SSH settings in
# ~/.ssh_config or in the ssh_options param (ref: http://net-ssh.github.io/net-ssh/Net/SSH.html#method-c-start) # ~/.ssh_config or in the ssh_options param (ref: http://net-ssh.github.io/net-ssh/Net/SSH.html#method-c-start)