mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 17:13:25 +08:00
FEATURE: allow users to pick a CDN for s3 assets
This commit is contained in:
@ -135,9 +135,6 @@ module Discourse
|
|||||||
# supports etags (post 1.7)
|
# supports etags (post 1.7)
|
||||||
config.middleware.delete Rack::ETag
|
config.middleware.delete Rack::ETag
|
||||||
|
|
||||||
require 'middleware/apply_cdn'
|
|
||||||
config.middleware.use Middleware::ApplyCDN
|
|
||||||
|
|
||||||
# route all exceptions via our router
|
# route all exceptions via our router
|
||||||
config.exceptions_app = self.routes
|
config.exceptions_app = self.routes
|
||||||
|
|
||||||
|
@ -945,6 +945,7 @@ en:
|
|||||||
s3_access_key_id: "The Amazon S3 access key id that will be used to upload images."
|
s3_access_key_id: "The Amazon S3 access key id that will be used to upload images."
|
||||||
s3_secret_access_key: "The Amazon S3 secret access key that will be used to upload images."
|
s3_secret_access_key: "The Amazon S3 secret access key that will be used to upload images."
|
||||||
s3_region: "The Amazon S3 region name that will be used to upload images."
|
s3_region: "The Amazon S3 region name that will be used to upload images."
|
||||||
|
s3_cdn_url: "The CDN URL to use for all s3 assets (for example: https://cdn.somewhere.com). WARNING: after changing this setting you must rebake all old posts."
|
||||||
|
|
||||||
avatar_sizes: "List of automatically generated avatar sizes."
|
avatar_sizes: "List of automatically generated avatar sizes."
|
||||||
|
|
||||||
|
@ -531,7 +531,10 @@ files:
|
|||||||
enum: 'S3RegionSiteSetting'
|
enum: 'S3RegionSiteSetting'
|
||||||
s3_upload_bucket:
|
s3_upload_bucket:
|
||||||
default: ''
|
default: ''
|
||||||
regex: "^[^A-Z._]+$"
|
regex: '^[^A-Z._]+$'
|
||||||
|
s3_cdn_url:
|
||||||
|
default: ''
|
||||||
|
regex: '^https?:\/\/.+[^\/]$'
|
||||||
allow_profile_backgrounds:
|
allow_profile_backgrounds:
|
||||||
client: true
|
client: true
|
||||||
default: true
|
default: true
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
module Middleware
|
|
||||||
|
|
||||||
class ApplyCDN
|
|
||||||
|
|
||||||
def initialize(app, settings={})
|
|
||||||
@app = app
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(env)
|
|
||||||
status, headers, response = @app.call(env)
|
|
||||||
|
|
||||||
if Discourse.asset_host.present? &&
|
|
||||||
Discourse.store.external? &&
|
|
||||||
(headers["Content-Type"].start_with?("text/") ||
|
|
||||||
headers["Content-Type"].start_with?("application/json"))
|
|
||||||
response.body = response.body.gsub(Discourse.store.absolute_base_url, Discourse.asset_host)
|
|
||||||
end
|
|
||||||
|
|
||||||
[status, headers, response]
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -208,18 +208,33 @@ module PrettyText
|
|||||||
options[:topicId] = opts[:topic_id]
|
options[:topicId] = opts[:topic_id]
|
||||||
|
|
||||||
sanitized = markdown(text.dup, options)
|
sanitized = markdown(text.dup, options)
|
||||||
sanitized = add_rel_nofollow_to_user_content(sanitized) if !options[:omit_nofollow] && SiteSetting.add_rel_nofollow_to_user_content
|
|
||||||
sanitized
|
doc = Nokogiri::HTML.fragment(sanitized)
|
||||||
|
|
||||||
|
if !options[:omit_nofollow] && SiteSetting.add_rel_nofollow_to_user_content
|
||||||
|
add_rel_nofollow_to_user_content(doc)
|
||||||
|
end
|
||||||
|
|
||||||
|
if SiteSetting.s3_cdn_url.present? && SiteSetting.enable_s3_uploads
|
||||||
|
add_s3_cdn(doc)
|
||||||
|
end
|
||||||
|
|
||||||
|
doc.to_html
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.add_rel_nofollow_to_user_content(html)
|
def self.add_s3_cdn(doc)
|
||||||
|
doc.css("img").each do |img|
|
||||||
|
img["src"] = img["src"].sub(Discourse.store.absolute_base_url, SiteSetting.s3_cdn_url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.add_rel_nofollow_to_user_content(doc)
|
||||||
whitelist = []
|
whitelist = []
|
||||||
|
|
||||||
domains = SiteSetting.exclude_rel_nofollow_domains
|
domains = SiteSetting.exclude_rel_nofollow_domains
|
||||||
whitelist = domains.split('|') if domains.present?
|
whitelist = domains.split('|') if domains.present?
|
||||||
|
|
||||||
site_uri = nil
|
site_uri = nil
|
||||||
doc = Nokogiri::HTML.fragment(html)
|
|
||||||
doc.css("a").each do |l|
|
doc.css("a").each do |l|
|
||||||
href = l["href"].to_s
|
href = l["href"].to_s
|
||||||
begin
|
begin
|
||||||
@ -238,7 +253,6 @@ module PrettyText
|
|||||||
l["rel"] = "nofollow"
|
l["rel"] = "nofollow"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
doc.to_html
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class DetectedLink
|
class DetectedLink
|
||||||
|
@ -308,4 +308,17 @@ describe PrettyText do
|
|||||||
expect(PrettyText.cook("```cpp\ncpp\n```")).to match_html("<p></p><pre><code class='lang-cpp'>cpp</code></pre>")
|
expect(PrettyText.cook("```cpp\ncpp\n```")).to match_html("<p></p><pre><code class='lang-cpp'>cpp</code></pre>")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'can substitute s3 cdn correctly' do
|
||||||
|
SiteSetting.enable_s3_uploads = true
|
||||||
|
SiteSetting.s3_access_key_id = "XXX"
|
||||||
|
SiteSetting.s3_secret_access_key = "XXX"
|
||||||
|
SiteSetting.s3_upload_bucket = "test"
|
||||||
|
SiteSetting.s3_cdn_url = "https://awesome.cdn"
|
||||||
|
|
||||||
|
raw = "<img src='#{Discourse.store.absolute_base_url}/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg'"
|
||||||
|
cooked = "<p><img src='https://awesome.cdn/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg'></p>"
|
||||||
|
|
||||||
|
expect(PrettyText.cook(raw)).to match_html(cooked)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user