diff options
author | Joshua Peek <josh@joshpeek.com> | 2009-12-26 11:17:52 -0600 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2009-12-26 11:17:52 -0600 |
commit | 8e6bc663d1a72f717dc913faf72cc84097da8f8a (patch) | |
tree | 168412e42481d9859118ff9d0baf4fc95f03f68e | |
parent | 99acee31104cb2cc0e3adb1c25a9a29dfc510619 (diff) | |
parent | 065ba85cc49a15d952c46410aad4ef78a98f7717 (diff) | |
download | rack-8e6bc663d1a72f717dc913faf72cc84097da8f8a.tar.gz |
Merge remote branch 'origin/nosqueeze'
-rw-r--r-- | lib/rack/urlmap.rb | 15 | ||||
-rw-r--r-- | test/spec_rack_urlmap.rb | 30 |
2 files changed, 38 insertions, 7 deletions
diff --git a/lib/rack/urlmap.rb b/lib/rack/urlmap.rb index 262dec8d..b699d35b 100644 --- a/lib/rack/urlmap.rb +++ b/lib/rack/urlmap.rb @@ -28,25 +28,26 @@ module Rack raise ArgumentError, "paths need to start with /" end location = location.chomp('/') + match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n') - [host, location, app] - }.sort_by { |(h, l, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first + [host, location, match, app] + }.sort_by { |(h, l, m, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first end def call(env) - path = env["PATH_INFO"].to_s.squeeze("/") + path = env["PATH_INFO"].to_s script_name = env['SCRIPT_NAME'] hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT') - @mapping.each { |host, location, app| + @mapping.each { |host, location, match, app| next unless (hHost == host || sName == host \ || (host.nil? && (hHost == sName || hHost == sName+':'+sPort))) - next unless location == path[0, location.size] - next unless path[location.size] == nil || path[location.size] == ?/ + next unless path =~ match && rest = $1 + next unless rest.empty? || rest[0] == ?/ return app.call( env.merge( 'SCRIPT_NAME' => (script_name + location), - 'PATH_INFO' => path[location.size..-1])) + 'PATH_INFO' => rest)) } [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]] end diff --git a/test/spec_rack_urlmap.rb b/test/spec_rack_urlmap.rb index 6c4d72ac..3d8fe605 100644 --- a/test/spec_rack_urlmap.rb +++ b/test/spec_rack_urlmap.rb @@ -44,6 +44,12 @@ context "Rack::URLMap" do res["X-ScriptName"].should.equal "/foo/bar" res["X-PathInfo"].should.equal "/" + res = Rack::MockRequest.new(map).get("/foo///bar//quux") + res.status.should.equal 200 + res.should.be.ok + res["X-ScriptName"].should.equal "/foo/bar" + res["X-PathInfo"].should.equal "//quux" + res = Rack::MockRequest.new(map).get("/foo/quux", "SCRIPT_NAME" => "/bleh") res.should.be.ok res["X-ScriptName"].should.equal "/bleh/foo" @@ -182,4 +188,28 @@ context "Rack::URLMap" do res["X-PathInfo"].should.equal "/" res["X-ScriptName"].should.equal "" end + + specify "should not squeeze slashes" do + map = Rack::URLMap.new("/" => lambda { |env| + [200, + { "Content-Type" => "text/plain", + "X-Position" => "root", + "X-PathInfo" => env["PATH_INFO"], + "X-ScriptName" => env["SCRIPT_NAME"] + }, [""]]}, + "/foo" => lambda { |env| + [200, + { "Content-Type" => "text/plain", + "X-Position" => "foo", + "X-PathInfo" => env["PATH_INFO"], + "X-ScriptName" => env["SCRIPT_NAME"] + }, [""]]} + ) + + res = Rack::MockRequest.new(map).get("/http://example.org/bar") + res.should.be.ok + res["X-Position"].should.equal "root" + res["X-PathInfo"].should.equal "/http://example.org/bar" + res["X-ScriptName"].should.equal "" + end end |