I am trying to write two kind of Rack routes. Rack allow us to write such routes like so:
app = Rack::URLMap.new('/test' => SimpleAdapter.new,
'/files' => Rack::File.new('.'))
In my case, I would like to handle those routes:
- "/" or "index"
- "/*" in order to match any other routes
So I had trying this:
app = Rack::URLMap.new('/index' => SimpleAdapter.new,
'/' => Rack::File.new('./public'))
This works well, but... I don't know how to add '/' path (as alternative of '/index' path). The path '/*' is not interpreted as a wildcard, according to my tests. Do you know how I could do?
Thanks
You are correct that Rack::URLMap
doesn't treat '*'
in a path as a wildcard. The actual translation from path to regular expression looks like this:
Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n')
That is, it treats any characters in the path as literals, but also matches a path with any suffix. I believe the only way for you to accomplish what you're attempting is to use a middleware instead of an endpoint. In your config.ru
you might have something like this:
use SimpleAdapter
run Rack::File
And your lib/simple_adapter.rb
might look something like this:
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