FEATURE: Multisite support for S3 image stores (#6689)
* FEATURE: Multisite support for S3 image stores * Use File.join to concatenate all paths & fix linting on multisite/s3_store_spec.rb
This commit is contained in:
parent
5db50d6cdc
commit
05a4f3fb51
|
@ -28,6 +28,10 @@ module FileStore
|
||||||
not_implemented
|
not_implemented
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def upload_path
|
||||||
|
File.join("uploads", RailsMultisite::ConnectionManagement.current_db)
|
||||||
|
end
|
||||||
|
|
||||||
def has_been_uploaded?(url)
|
def has_been_uploaded?(url)
|
||||||
not_implemented
|
not_implemented
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,10 +32,6 @@ module FileStore
|
||||||
"#{Discourse.asset_host}#{relative_base_url}"
|
"#{Discourse.asset_host}#{relative_base_url}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def upload_path
|
|
||||||
"/uploads/#{RailsMultisite::ConnectionManagement.current_db}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def relative_base_url
|
def relative_base_url
|
||||||
"#{Discourse.base_uri}#{upload_path}"
|
"#{Discourse.base_uri}#{upload_path}"
|
||||||
end
|
end
|
||||||
|
@ -46,7 +42,7 @@ module FileStore
|
||||||
|
|
||||||
def download_url(upload)
|
def download_url(upload)
|
||||||
return unless upload
|
return unless upload
|
||||||
"#{relative_base_url}/#{upload.sha1}"
|
File.join(relative_base_url, upload.sha1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cdn_url(url)
|
def cdn_url(url)
|
||||||
|
@ -68,7 +64,7 @@ module FileStore
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_path_for(type, upload_id, sha, extension)
|
def get_path_for(type, upload_id, sha, extension)
|
||||||
"#{upload_path}/#{super(type, upload_id, sha, extension)}"
|
File.join("/", upload_path, super(type, upload_id, sha, extension))
|
||||||
end
|
end
|
||||||
|
|
||||||
def copy_file(file, path)
|
def copy_file(file, path)
|
||||||
|
@ -90,7 +86,7 @@ module FileStore
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_dir
|
def public_dir
|
||||||
"#{Rails.root}/public"
|
File.join(Rails.root, "public")
|
||||||
end
|
end
|
||||||
|
|
||||||
def tombstone_dir
|
def tombstone_dir
|
||||||
|
@ -105,15 +101,13 @@ module FileStore
|
||||||
private
|
private
|
||||||
|
|
||||||
def list_missing(model)
|
def list_missing(model)
|
||||||
public_directory = "#{Rails.root}/public"
|
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
model.find_each do |upload|
|
model.find_each do |upload|
|
||||||
|
|
||||||
# could be a remote image
|
# could be a remote image
|
||||||
next unless upload.url =~ /^\/[^\/]/
|
next unless upload.url =~ /^\/[^\/]/
|
||||||
|
|
||||||
path = "#{public_directory}#{upload.url}"
|
path = "#{public_dir}#{upload.url}"
|
||||||
bad = true
|
bad = true
|
||||||
begin
|
begin
|
||||||
bad = false if File.size(path) != 0
|
bad = false if File.size(path) != 0
|
||||||
|
|
|
@ -41,9 +41,12 @@ module FileStore
|
||||||
# add a "content disposition" header for "attachments"
|
# add a "content disposition" header for "attachments"
|
||||||
options[:content_disposition] = "attachment; filename=\"#{filename}\"" unless FileHelper.is_supported_image?(filename)
|
options[:content_disposition] = "attachment; filename=\"#{filename}\"" unless FileHelper.is_supported_image?(filename)
|
||||||
# if this fails, it will throw an exception
|
# if this fails, it will throw an exception
|
||||||
|
|
||||||
|
path.prepend(File.join(upload_path, "/")) if RailsMultisite::ConnectionManagement.current_db != "default"
|
||||||
path = @s3_helper.upload(file, path, options)
|
path = @s3_helper.upload(file, path, options)
|
||||||
|
|
||||||
# return the upload url
|
# return the upload url
|
||||||
"#{absolute_base_url}/#{path}"
|
File.join(absolute_base_url, path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_file(url, path)
|
def remove_file(url, path)
|
||||||
|
@ -93,7 +96,7 @@ module FileStore
|
||||||
return url if SiteSetting.Upload.s3_cdn_url.blank?
|
return url if SiteSetting.Upload.s3_cdn_url.blank?
|
||||||
schema = url[/^(https?:)?\/\//, 1]
|
schema = url[/^(https?:)?\/\//, 1]
|
||||||
folder = @s3_helper.s3_bucket_folder_path.nil? ? "" : "#{@s3_helper.s3_bucket_folder_path}/"
|
folder = @s3_helper.s3_bucket_folder_path.nil? ? "" : "#{@s3_helper.s3_bucket_folder_path}/"
|
||||||
url.sub("#{schema}#{absolute_base_url}/#{folder}", "#{SiteSetting.Upload.s3_cdn_url}/")
|
url.sub(File.join("#{schema}#{absolute_base_url}", folder), File.join(SiteSetting.Upload.s3_cdn_url, "/"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def cache_avatar(avatar, user_id)
|
def cache_avatar(avatar, user_id)
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
require 'file_store/s3_store'
|
||||||
|
|
||||||
|
RSpec.describe 'Multisite s3 uploads', type: :multisite do
|
||||||
|
let(:conn) { RailsMultisite::ConnectionManagement }
|
||||||
|
let(:uploaded_file) { file_from_fixtures("smallest.png") }
|
||||||
|
|
||||||
|
let(:upload) do
|
||||||
|
Fabricate(:upload, sha1: Digest::SHA1.hexdigest(File.read(uploaded_file)))
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:s3_client) { Aws::S3::Client.new(stub_responses: true) }
|
||||||
|
|
||||||
|
let(:s3_helper) do
|
||||||
|
S3Helper.new(SiteSetting.s3_upload_bucket, '', client: s3_client)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:store) { FileStore::S3Store.new(s3_helper) }
|
||||||
|
|
||||||
|
context 'uploading to s3' do
|
||||||
|
before(:each) do
|
||||||
|
SiteSetting.s3_upload_bucket = "some-really-cool-bucket"
|
||||||
|
SiteSetting.s3_access_key_id = "s3-access-key-id"
|
||||||
|
SiteSetting.s3_secret_access_key = "s3-secret-access-key"
|
||||||
|
SiteSetting.enable_s3_uploads = true
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#store_upload" do
|
||||||
|
it "returns the correct url for default and second multisite db" do
|
||||||
|
expect(store.store_upload(uploaded_file, upload)).to eq(
|
||||||
|
"//#{SiteSetting.s3_upload_bucket}.s3.dualstack.us-east-1.amazonaws.com/original/1X/c530c06cf89c410c0355d7852644a73fc3ec8c04.png"
|
||||||
|
)
|
||||||
|
|
||||||
|
conn.with_connection('second') do
|
||||||
|
expect(store.store_upload(uploaded_file, upload)).to eq(
|
||||||
|
"//#{SiteSetting.s3_upload_bucket}.s3.dualstack.us-east-1.amazonaws.com/uploads/second/original/1X/c530c06cf89c410c0355d7852644a73fc3ec8c04.png"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue