mirror of
https://github.com/discourse/discourse.git
synced 2025-04-28 23:14:34 +08:00

Follow up from https://github.com/discourse/discourse/pull/31559. We expect some standard headers to be added from `Rails.application.config.action_dispatch.default_headers` for responses, however these were found to be removed in some error paths. For more detail on this behaviour, refer to https://github.com/discourse/discourse/pull/31619#issuecomment-2699644232. This PR adds those headers back if they aren't there, with the caveats that we don't add headers that are irrelevant for non-HTML responses, and neither do we add X-Frame-Options which is intentionally removed for embeddables.
40 lines
1009 B
Ruby
40 lines
1009 B
Ruby
# frozen_string_literal: true
|
|
|
|
module Middleware
|
|
class DefaultHeaders
|
|
HTML_ONLY_HEADERS = Set.new(%w[X-XSS-Protection])
|
|
EXCLUDED_HEADERS = Set.new(%w[X-Frame-Options])
|
|
|
|
def initialize(app, settings = {})
|
|
@app = app
|
|
end
|
|
|
|
def call(env)
|
|
status, headers, body = @app.call(env)
|
|
is_html_response = html_response?(headers)
|
|
|
|
default_headers =
|
|
Rails.application.config.action_dispatch.default_headers.to_h.except(*EXCLUDED_HEADERS)
|
|
|
|
default_headers.each do |header_name, value|
|
|
next if !is_html_response && HTML_ONLY_HEADERS.include?(header_name)
|
|
|
|
headers[header_name] ||= value
|
|
end
|
|
|
|
headers[
|
|
"Cross-Origin-Opener-Policy"
|
|
] = SiteSetting.cross_origin_opener_policy_header if is_html_response &&
|
|
headers["Cross-Origin-Opener-Policy"].nil?
|
|
|
|
[status, headers, body]
|
|
end
|
|
|
|
private
|
|
|
|
def html_response?(headers)
|
|
headers["Content-Type"] && headers["Content-Type"] =~ /html/
|
|
end
|
|
end
|
|
end
|