class DataStyleSanitizer::Middleware
def call(env)
def call(env) status, headers, response = @app.call(env) if html_response?(headers) body = +"" response.each { |part| body << part } nonce = extract_nonce_from_env(env) processed = Processor.new(body, nonce: nonce).process headers["Content-Length"] = processed.bytesize.to_s [status, headers, [processed]] else [status, headers, response] end end
def call(env)
def call(env) status, headers, response = @app.call(env) if headers["Content-Type"]&.include?("text/html") body = +"" response.each { |part| body << part } nonce = extract_nonce(env) new_body = DataStyleSanitizer.process(body, nonce: nonce) headers["Content-Length"] = new_body.bytesize.to_s [status, headers, [new_body]] else [status, headers, response] end end
def extract_nonce(env)
def extract_nonce(env) if env.respond_to?(:dig) env.dig("action_dispatch.content_security_policy_nonce", :style) else # get nonce from meta tag # This is a fallback for older versions of Rails meta_tag = env["rack.session"]&.dig("meta_tags", "csp-nonce") if meta_tag meta_tag.match(/nonce="([^"]+)"/)[1] if /nonce="([^"]+)"/.match?(meta_tag) end end end
def extract_nonce_from_env(env)
def extract_nonce_from_env(env) if env["action_dispatch.content_security_policy_nonce"].respond_to?(:call) env["action_dispatch.content_security_policy_nonce"].call(:style) end end
def html_response?(headers)
def html_response?(headers) headers["Content-Type"]&.include?("text/html") end
def initialize(app)
def initialize(app) @app = app end
def initialize(app)
def initialize(app) @app = app end