Сопоставление URL-адресов стоек

Я пытаюсь написать два вида Rack-маршрутов. Rack позволяет нам писать такие маршруты так:

app = Rack::URLMap.new('/test'  => SimpleAdapter.new,
                       '/files' => Rack::File.new('.'))

В моем случае я хотел бы обработать эти маршруты:

  • "/" или "индекс"
  • "/*" для соответствия любым другим маршрутам

Итак, я пробовал это:

app = Rack::URLMap.new('/index' => SimpleAdapter.new,
                       '/'      => Rack::File.new('./public'))

Это работает хорошо, но... я не знаю, как добавить путь '/' (в качестве альтернативы пути '/index'). Согласно моим тестам, путь '/*' не интерпретируется как подстановочный знак. Вы знаете, как я мог бы сделать?

Спасибо


person Puru puru rin..    schedule 28.03.2010    source источник


Ответы (1)


Вы правы, что Rack::URLMap не рассматривает '*' в пути как подстановочный знак. Фактический перевод из пути в регулярное выражение выглядит так:

Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n')

То есть он обрабатывает любые символы в пути как литералы, но также сопоставляет путь с любым суффиксом. Я считаю, что единственный способ выполнить то, что вы пытаетесь, - это использовать промежуточное программное обеспечение вместо конечной точки. В вашем config.ru у вас может быть что-то вроде этого:

use SimpleAdapter
run Rack::File

И ваш lib/simple_adapter.rb может выглядеть примерно так:

class SimpleAdapter
  SLASH_OR_INDEX = %r{/(?:index)?}
  def initialize(app)
    @app = app
  end
  def call(env)
    request = Rack::Request.new(env)
    if request.path =~ SLASH_OR_INDEX
      # return some Rack response triple...
    else
      # pass the request on down the stack:
      @app.call(env)
    end
  end
end
person James A. Rosen    schedule 18.06.2010