mirror of
https://github.com/discourse/discourse.git
synced 2024-12-04 04:26:18 +08:00
ecf7a4f0c6
We add `Access-Control-Allow-Origin: *` to all asset requests which are requested via a configured CDN. This is particularly important now that we're using browser-native `import()` to load the highlightjs bundle. Unfortunately, user-configurable 'cors_origins' site setting was overriding the wldcard value on CDN assets and causing CORS errors. This commit updates the logic to give the `*` value precedence, and adds a spec for the situation. It also invalidates the cache of hljs assets (because CDNs will have cached the bad Access-Control-Allow-Origin header). The rack-cors middleware is also slightly tweaked so that it is always inserted. This makes things easier to test and more consistent.
59 lines
1.9 KiB
Ruby
59 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Discourse::Cors
|
|
ORIGINS_ENV = "Discourse_Cors_Origins"
|
|
|
|
def initialize(app, options = nil)
|
|
@app = app
|
|
if GlobalSetting.enable_cors && GlobalSetting.cors_origin.present?
|
|
@global_origins = GlobalSetting.cors_origin.split(",").map { |x| x.strip.chomp("/") }
|
|
end
|
|
end
|
|
|
|
def call(env)
|
|
return @app.call(env) if !GlobalSetting.enable_cors && !GlobalSetting.cdn_url
|
|
|
|
cors_origins = @global_origins || []
|
|
cors_origins += SiteSetting.cors_origins.split("|") if SiteSetting.cors_origins.present?
|
|
cors_origins = cors_origins.presence
|
|
|
|
if env["REQUEST_METHOD"] == ("OPTIONS") && env["HTTP_ACCESS_CONTROL_REQUEST_METHOD"]
|
|
return 200, Discourse::Cors.apply_headers(cors_origins, env, {}), []
|
|
end
|
|
|
|
env[Discourse::Cors::ORIGINS_ENV] = cors_origins if cors_origins
|
|
|
|
status, headers, body = @app.call(env)
|
|
headers ||= {}
|
|
|
|
Discourse::Cors.apply_headers(cors_origins, env, headers)
|
|
|
|
[status, headers, body]
|
|
end
|
|
|
|
def self.apply_headers(cors_origins, env, headers)
|
|
request_method = env["REQUEST_METHOD"]
|
|
|
|
if headers["Access-Control-Allow-Origin"]
|
|
# Already configured. Probably by ApplicationController#apply_cdn_headers
|
|
elsif cors_origins
|
|
origin = nil
|
|
if origin = env["HTTP_ORIGIN"]
|
|
origin = nil unless cors_origins.include?(origin)
|
|
end
|
|
|
|
headers["Access-Control-Allow-Origin"] = origin || cors_origins[0]
|
|
headers[
|
|
"Access-Control-Allow-Headers"
|
|
] = "Content-Type, Cache-Control, X-Requested-With, X-CSRF-Token, Discourse-Present, User-Api-Key, User-Api-Client-Id, Authorization"
|
|
headers["Access-Control-Allow-Credentials"] = "true"
|
|
headers["Access-Control-Allow-Methods"] = "POST, PUT, GET, OPTIONS, DELETE"
|
|
headers["Access-Control-Max-Age"] = "7200"
|
|
end
|
|
|
|
headers
|
|
end
|
|
end
|
|
|
|
Rails.configuration.middleware.insert_before ActionDispatch::Flash, Discourse::Cors
|