开发者

Get ordered list of middleware in a generic rack application?

The functionality I am looking for is similar to the rake middleware com开发者_高级运维mand in Rails, except for a generic rack application.


$ rake middleware

use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd148f9468>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
run 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 }
end

app = Rack::Builder.parse_file('config.ru').first; nil # trailing nil to avoid paging in an interactive console
p 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').first
sinatra_rack_builder = sinatra_app.build(sinatra_app)
sinatra_extended_app = sinatra_rack_builder.to_app
rack_app = sinatra_extended_app.app

pp 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.


Try the rack-graph gem by Konstantin Haase.

For some reason, Konstantin has not seen fit to publish this gem on rubygems, so you will either need to add it to your Gemfile using git or install and reference it locally.

# Gemfile
gem 'rack-graph', github: 'rkh/rack-graph'

$ bundle exec rackup -s Graph
# Locally (without bundler/Gemfile):
$ git clone https://github.com/rkh/rack-graph.git
$ ruby -I/path/to/rack-graph/lib $(which rackup) -s Graph

Given the following example Rack application:

# config.ru
Foo = proc { [200, {}, ['Foo']] }
App = proc { [200, {}, ['Ok']] }

map '/foo' do
  use Rack::Runtime
  use Rack::MethodOverride
  run Foo
end

run App

This is the output:

# Output:
Rack::ContentLength
 |- Rack::CommonLogger(stderr)
    |- Rack::ShowExceptions
       |- Rack::Lint
          |- Rack::TempfileReaper
             |- Rack::URLMap
                |- "/foo"
                |  |- Rack::Runtime
                |     |- Rack::MethodOverride
                |        |- Proc(0x00007fd93a97c2d0 /Users/steve/ruby/config.ru:1)
                |
                |- ""
                   |- Proc(0x00007fd93a97c2a8 /Users/steve/ruby/config.ru:2)


this is long overdue, I know

here's a nice thread, the definitive answer is the last post

UPDATED as per Marc-Andre's comment:

The following is the last post from this link

Rack does not have a mechanism for that and since not all middleware is added via @middleware, Sinatra can't tell you what middleware is used. Neither can rails, btw, it can just tell you what is possible. Middleware does not have to be a linear list (i.e. when using a Rack router or something).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜