Get ordered list of middleware in a generic rack application? Get ordered list of middleware in a generic rack application? ruby ruby

Get ordered list of middleware in a generic rack application?


$ rake middlewareuse ActionDispatch::Staticuse Rack::Lockuse #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd148f9468>use Rack::Runtimeuse Rack::MethodOverrideuse ActionDispatch::RequestIduse Rails::Rack::Loggeruse ActionDispatch::ShowExceptionsuse ActionDispatch::DebugExceptionsuse ActionDispatch::RemoteIpuse ActionDispatch::Reloaderuse ActionDispatch::Callbacksuse ActiveRecord::Migration::CheckPendinguse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacheuse ActionDispatch::Cookiesuse ActionDispatch::Session::CookieStoreuse ActionDispatch::Flashuse ActionDispatch::ParamsParseruse Rack::Headuse Rack::ConditionalGetuse Rack::ETagrun RackTest::Application.routes

http://pothibo.com/2013/11/ruby-on-rails-inside-actiondispatch-and-rack/


This will return a list of all the middleware for a rack application:

def middleware_classes(app)  app.instance_variable_get(:@use).map{|middleware| middleware.call.class.name }endapp = Rack::Builder.parse_file('config.ru').first; nil # trailing nil to avoid paging in an interactive consolep middleware_classes(app)


If you're using a Sinatra app that extends Sinatra::Base, I had to use a slightly modified version of Michael Hale's answer:

require 'rack'def middleware_classes(app)  r = [app]  ​  while ((next_app = r.last.instance_variable_get(:@app)) != nil)    r << next_app  end  ​  r.map{|e| e.instance_variable_defined?(:@app) ? e.class : e }end​sinatra_app = Rack::Builder.parse_file('config.ru').firstsinatra_rack_builder = sinatra_app.build(sinatra_app)sinatra_extended_app = sinatra_rack_builder.to_apprack_app = sinatra_extended_app.apppp middleware_classes(rack_app)

​After putting this into a file such as dump_middleware.rb I was able to see the middleware as expected:

$ bundle exec ruby ./dump_middleware.rb[Rack::Head, Rack::NullLogger, Rack::Session::Cookie, Rack::Protection::FrameOptions, Rack::Protection::HttpOrigin, Rack::Protection::IPSpoofing, Rack::Protection::JsonCsrf, Rack::Protection::PathTraversal, Rack::Protection::RemoteToken, Rack::Protection::SessionHijacking, Rack::Protection::XSSHeader, Warden::Manager, SinatraApp]

There might be a cleaner way to do this.