What if you tried some Rack Middleware? Questions here, here, and here seem to have answers that use this approach. With Rails 4.5, I found the body
of the Rack::Response
to be immutable, so this answer proved particularly useful. Here is the code I ended up with:
module AfterRender
require 'rack'
CONTENT_LENGTH = 'Content-Length'
class SanitizeResponse
def initialize(app)
@app=app
end
def call(env)
status, headers, response = @app.call(env)
if response.present? and response.respond_to? :body
new_response_body = sanitize_body(response.body)
headers[CONTENT_LENGTH] = new_response_body.length.to_s if headers[CONTENT_LENGTH].present?
new_response = Rack::Response.new([new_response_body], status, headers)
return [status, headers, new_response]
end
return [status, headers, response]
end
def sanitizeBody(body)
to_ret = body.dup
to_ret.gsub!('string_to_be_replaced', 'replacement_string')
to_ret
end
end
end
I check that response.body
is defined to ensure no funkiness occurs while sending over files for my angular app (they use Sprockets::Asset
instead of Rack::Response
). I don't want to be sanitizing those files, anyway. We also only reset the headers['Content-Length']
if it was already defined, which is not likely the case if Transfer-Encoding
is chunked. new_response
could simply be an array (e.g. [new_response_body]
), but I find it safer to send response
out the same way it came in, as a Rack::Response
. This documentation is helpful to understand how the return of call
must be shaped (i.e. as an array).
To ensure this middleware is actually used, I placed it in a new file, found at app/middleware/after_render.rb
. In my config/application.rb
, I added require_relative '../app/middleware/after_render.rb'
at the top and config.middleware.use AfterRender::SanitizeResponse
inside the Application
class. It looks something like this:
require File.expand_path('../boot', __FILE__)
require_relative '../app/middleware/after_render.rb'
require 'rails/all'
module MyModule
class Application < Rails::Application
config.autoload_paths << "#{Rails.root}/app"
config.middleware.use AfterRender::SanitizeResponse
end
end
Hope this helps!