diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b26b81c939f..6ad17dfbce5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -65,6 +65,12 @@ module ApplicationHelper if GlobalSetting.cdn_url path = path.gsub(GlobalSetting.cdn_url, GlobalSetting.s3_cdn_url) else + # we must remove the subfolder path here, assets are uploaded to s3 + # without it getting involved + if ActionController::Base.config.relative_url_root + path = path.sub(ActionController::Base.config.relative_url_root, "") + end + path = "#{GlobalSetting.s3_cdn_url}#{path}" end diff --git a/lib/file_store/s3_store.rb b/lib/file_store/s3_store.rb index b2f9c20988b..076ea2171ab 100644 --- a/lib/file_store/s3_store.rb +++ b/lib/file_store/s3_store.rb @@ -91,7 +91,7 @@ module FileStore return url if SiteSetting.Upload.s3_cdn_url.blank? schema = url[/^(https?:)?\/\//, 1] 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}#{Discourse.base_uri}/") + url.sub("#{schema}#{absolute_base_url}/#{folder}", "#{SiteSetting.Upload.s3_cdn_url}/") end def cache_avatar(avatar, user_id) diff --git a/spec/components/file_store/s3_store_spec.rb b/spec/components/file_store/s3_store_spec.rb index 99e46fe4ccc..49e72cf954b 100644 --- a/spec/components/file_store/s3_store_spec.rb +++ b/spec/components/file_store/s3_store_spec.rb @@ -285,17 +285,18 @@ describe FileStore::S3Store do describe '.cdn_url' do - it 'uses the correct path' do - url = "//s3-upload-bucket.s3-us-west-2.amazonaws.com/livechat/original/1X/2252ae522257fc537351e47bbdd34698936b6c38.jpeg" - expect(store.cdn_url(url)).to end_with('/livechat/original/1X/2252ae522257fc537351e47bbdd34698936b6c38.jpeg') - end - it 'supports subfolder' do - SiteSetting.s3_upload_bucket = 's3-upload-bucket/livechat/community' - GlobalSetting.stubs(:relative_url_root).returns('/community') + SiteSetting.s3_upload_bucket = 's3-upload-bucket/livechat' + SiteSetting.s3_cdn_url = 'https://rainbow.com' + + # none of this should matter at all + # subfolder should not leak into uploads + global_setting :relative_url_root, '/community' Discourse.stubs(:base_uri).returns("/community") - url = "//s3-upload-bucket.s3-us-west-2.amazonaws.com/livechat/community/original/1X/2252ae522257fc537351e47bbdd34698936b6c38.jpeg" - expect(store.cdn_url(url)).to end_with('/livechat/community/original/1X/2252ae522257fc537351e47bbdd34698936b6c38.jpeg') + + url = "//s3-upload-bucket.s3.amazonaws.com/livechat/original/gif.png" + + expect(store.cdn_url(url)).to eq("https://rainbow.com/original/gif.png") end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 69a50d2ca52..06553a4fde4 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -23,6 +23,15 @@ describe ApplicationHelper do set_env "COMPRESS_BROTLI", "1" end + after do + ActionController::Base.config.relative_url_root = nil + end + + it "deals correctly with subfolder" do + ActionController::Base.config.relative_url_root = "/community" + expect(helper.preload_script("application")).to include('https://s3cdn.com/assets/application.js') + end + it "returns magic brotli mangling for brotli requests" do helper.request.env["HTTP_ACCEPT_ENCODING"] = 'br' diff --git a/test/javascripts/lib/discourse-test.js.es6 b/test/javascripts/lib/discourse-test.js.es6 index 9627eafdbb9..94498a16462 100644 --- a/test/javascripts/lib/discourse-test.js.es6 +++ b/test/javascripts/lib/discourse-test.js.es6 @@ -9,3 +9,18 @@ QUnit.test("getURL on subfolder install", assert => { "relative url has subfolder" ); }); + +QUnit.test("getURLWithCDN on subfolder install with S3", assert => { + Discourse.BaseUri = "/forum"; + + Discourse.S3CDN = "https://awesome.cdn/site"; + Discourse.S3BaseUrl = "//test.s3-us-west-1.amazonaws.com/site"; + + let url = "//test.s3-us-west-1.amazonaws.com/site/forum/awesome.png"; + let expected = "https://awesome.cdn/site/forum/awesome.png"; + + assert.equal(Discourse.getURLWithCDN(url), expected, "at correct path"); + + Discourse.S3CDN = null; + Discourse.S3BaseUrl = null; +});