どのように私は特定のパスのためにのみラックミドルウェアを使用していますか?

StackOverflow https://stackoverflow.com/questions/920719

  •  06-09-2019
  •  | 
  •  

質問

私は唯一の特定のパスについて、私のラックアプリでMyMiddleware実行を持っているしたいと思います。私はRack::Builderまたは少なくともRack::URLMapを使用するように期待していたが、私は非常にどのように把握することはできません。

このはしません、私が仕事だろうと思ったものですが、ます:

# in my rackup file or Rails environment.rb:
map '/foo' do
  use MyMiddleware, { :some => 'options' }
end

それとも、いっそ、正規表現でます:

map /^foo/ do
  use MyMiddleware, { :some => 'options' }
end

しかし、最後にアプリを要求するmapようです。それだけでその親に戻って制御を渡すに戻って落ちることはありません。 (実際のエラーがラックundefined method 'each' for nil:NilClassにそのdo...endブロックの終わりをオンにしようとしたときから「app」である。)

ミドルウェアの配列とパスを受け取り、パスが一致した場合にのみ、それらを実行しますそこにミドルウェアがありますか?

役に立ちましたか?

解決

あなたは、パスを確認し、それが一致した場合にミドルウェアの次の部分に制御を渡すことはありませMyMiddleware可能性があります。

class MyMiddleware
  def initialize app
    @app = app
  end
  def call env
    middlewary_stuff if env['PATH_INFO'] == '/foo'
    @app.call env
  end

  def middlewary_stuff
    #...
  end
end

それとも、あなたはdslness O / W URLMapを使用することができます。それは次のようになります:

main_app = MainApp.new
Rack::URLMap.new '/'=>main_app, /^(foo|bar)/ => MyMiddleWare.new(main_app)

URLMapはを完全に理解するために、実際に非常に単純です。

他のヒント

@appは、右スコープに存在しないので、これは動作しません。

# in my_app.ru or any Rack::Builder context:
@app = self
map '/foo' do
  use MyMiddleware
  run lambda { |env| @app.call(env) }
end

しかし、この意志ます:

# in my_app.ru or any Rack::Builder context:
::MAIN_RACK_APP = self
map '/foo' do
  use MyMiddleware
  run lambda { |env| ::MAIN_RACK_APP.call(env) }
end

Rack::Builderは、それが無限に再帰しないように、パスの前部をオフmapする最初の引数を取り除き。残念ながら、これはそのパス接頭辞が取り除かれた後、それはパスの残りの部分は適切に他のマッピングが一致する可能性は低いということを意味します。

ここでは一例です。

::MAIN_APP = self
use Rack::ShowExceptions
use Rack::Lint
use Rack::Reloader, 0
use Rack::ContentLength

map '/html' do
  use MyContentTypeSettingMiddleware, 'text/html'
  run lambda { |env| puts 'HTML!'; ::MAIN_APP.call(env) }
end

map '/xml' do
  use MyContentTypeSettingMiddleware, 'application/xml'
  run lambda { |env| puts 'XML!'; ::MAIN_APP.call(env) }
end

map '/' do
  use ContentType, 'text/plain'
  run lambda { |env| [ 200, {}, "<p>Hello!</p>" ] }
end

/html/xmlに行くに行くログインするには、次のようになります:

HTML!
XML!
127.0.0.1 - - [28/May/2009 17:41:42] "GET /html/xml HTTP/1.1" 200 13 0.3626

これは、'/html'プレフィックスとなりましたコールのストリップを'/html'にマップアプリですが'/xml'にマップアプリにマッチします。

scroll top