2010-03-28 9 views
4

J'essaye d'écrire deux types de routes en rack. Rack nous permettent d'écrire ces lignes comme ceci:Rack URL Mapping

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

Dans mon cas, je voudrais gérer ces itinéraires:

  • "/" ou "index"
  • "/ *" dans afin de faire correspondre toutes les autres routes

J'avait essayer ceci:

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

Cela fonctionne bien, mais ... Je ne sais pas comment ajouter le chemin '/' (comme alternative au chemin '/ index'). Le chemin '/ *' n'est pas interprété comme un caractère générique, selon mes tests. Sais-tu comment je pourrais faire?

Merci

Répondre

3

Vous avez raison Rack::URLMap ne traite pas '*' dans un chemin comme joker. La traduction réelle de chemin à l'expression régulière ressemble à ceci:

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

C'est, il traite tous les caractères dans le chemin comme littéraux, mais correspond aussi un chemin avec un suffixe. Je crois que la seule façon pour vous d'accomplir ce que vous essayez est d'utiliser un middleware au lieu d'un point de terminaison. Dans votre config.ru vous pourriez avoir quelque chose comme ceci:

use SimpleAdapter 
run Rack::File 

Et votre lib/simple_adapter.rb pourrait ressembler à ceci:

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