Rack URL Mapping - PullRequest
       15

Rack URL Mapping

4 голосов
/ 29 марта 2010

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

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

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

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

Итак, я пытался это:

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

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

Спасибо

1 Ответ

3 голосов
/ 18 июня 2010

Вы правы, что 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
...