require 'addressable/uri' module ReverseProxy module Controller def reverse_proxy(proxy_url, options = {}) proxy_uri = Addressable::URI.parse(proxy_url) client = ReverseProxy::Client.new(proxy_url) do |config| config.on_response do |code, response| blacklist = [ 'Connection', # Always close connection 'Transfer-Encoding', # Let Rails calculate this 'Content-Length' # Let Rails calculate this ] response.each_capitalized do |key, value| next if blacklist.include?(key) headers[key] = value end end config.on_set_cookies do |code, response, set_cookies| set_cookies.each do |key, attributes| cookies[key] = attributes end end config.on_redirect do |code, response, redirect_url| request_uri = Addressable::URI.parse(request.url) redirect_uri = Addressable::URI.parse(redirect_url) # Make redirect uri absolute if it's relative by # joining it with the request url redirect_uri = request_uri.join(redirect_url) if redirect_uri.host.nil? unless redirect_uri.port.nil? # Make sure it's consistent with our request port redirect_uri.port = request.port if redirect_uri.port == proxy_uri.port end redirect_to redirect_uri.to_s, status: code and return end config.on_complete do |code, response| content_type = response['Content-Type'] body = response.body.to_s if content_type and content_type.match /image/ send_data body, content_type: content_type, disposition: "inline", status: code else render body: body, content_type: content_type, status: code end end yield(config) if block_given? end client.request(request.env, options) end end end