Pregunta

Me gustaría tener MyMiddleware carrera en mi aplicación Rack, pero sólo para ciertos caminos. Tenía la esperanza de utilizar Rack::Builder o al menos Rack::URLMap, pero no puedo encontrar la manera.

Esto es lo que pensé que trabajar, pero no:

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

O, mejor aún, con una expresión regular:

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

Pero map parece exigir una aplicación en el extremo; no va a caer de nuevo simplemente pasar el control de nuevo a su padre. (El error real es "undefined method 'each' for nil:NilClass" de cuando estante intenta convertir el final de ese bloque do...end en un app.)

¿Hay un middleware por ahí que toma una matriz de middleware y un camino y sólo se ejecuta si ellos coincide con la ruta?

¿Fue útil?

Solución

Usted podría tener MyMiddleware comprobar el camino y no pasar el control a la siguiente pieza de cerámica de media si coincide.

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

O, usted podría utilizar URLMap w / o la dslness. Se vería algo como esto:

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

a asimilar .

Otros consejos

Esto no funciona porque @app no existe en el ámbito derecha:

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

Pero esta voluntad:

# 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 tiras el primer argumento de map de la parte frontal de la ruta, por lo que no hace cesar Recurse. Desafortunadamente, esto significa que después de ese prefijo de ruta se elimina, es poco probable que el resto de la ruta coincidirá correctamente otras asignaciones.

Este es un ejemplo:

::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

El ir a /html/xml hace que el siguiente ir al registro:

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

Es decir, la aplicación asignada a '/html' tiras de '/html' el prefijo y la llamada ahora coincide con la aplicación asignada a '/xml'.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top