Rack::URLMap takes a hash mapping urls or paths to apps, and dispatches accordingly. Support for HTTP/1.1 host names exists if the URLs start with http:// or https://.

Rack::URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part relevant for dispatch is in the SCRIPT_NAME, and the rest in the PATH_INFO. This should be taken care of when you need to reconstruct the URL in order to create links.

Rack::URLMap dispatches in such a way that the longest paths are tried first, since they are most specific.

[~/local/src/ruby/sinatra/rack/rack-urlmap(master)]$ cat config.ru 
app1 = lambda { |e| [200, {}, ["one\n"]]}
app2 = lambda { |e| [200, {}, ["two\n"]]}
app3 = lambda { |e| [200, {}, ["one + two = three\n"]]}

app = Rack::URLMap.new "/one" => app1, "/two" => app2, "/one/two" => app3

run app

[~/local/src/ruby/sinatra/rack/rack-urlmap(master)]$ cat Rakefile 
desc "run the server"
task :default do
  sh "rackup"

desc "run the client with one"
task :one do
  sh %q{curl -v 'http://localhost:9292/one'}

desc "run the client with two"
task :two do
  sh %q{curl -v 'http://localhost:9292/two'}

desc "run the client with one/two"
task :onetwo do
  sh %q{curl -v 'http://localhost:9292/one/two'}

[~/local/src/ruby/sinatra/rack/rack-urlmap]$ rake
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on, CTRL+C to stop - - [17/Oct/2013 21:24:48] "GET /two HTTP/1.1" 200 - 0.0006

[~/local/src/ruby/sinatra/rack/rack-urlmap(master)]$ rake onetwo
curl -v 'http://localhost:9292/one/two'
* About to connect() to localhost port 9292 (#0)
*   Trying ::1... Connection refused
*   Trying connected
* Connected to localhost ( port 9292 (#0)
> GET /one/two HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5
> Host: localhost:9292
> Accept: */*
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Connection: close
< Server: thin 1.5.1 codename Straight Razor
one + two = three
* Closing connection #0

Casiano Rodriguez León 2015-06-18