From d212de6abfdb244ac9174416e824eaeaf3c5949f Mon Sep 17 00:00:00 2001 From: Ryan Tomayko Date: Tue, 17 Feb 2009 08:07:37 -0800 Subject: [PATCH] Fix routes don't match with certain forms of URL encoding [#147] We no longer store routes in URL encoded form and unescape the PATH_INFO before attempting to match routes. This allows matching all variations of encoded characters but does not allow matching encoded "/" characters in the PATH_INFO. See also: http://sinatra.lighthouseapp.com/projects/9779/tickets/147 http://groups.google.com/group/sinatrarb/browse_thread/thread/baab6ea877d7c2e4 --- lib/sinatra/base.rb | 6 +++--- test/routing_test.rb | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index a3c2f403..0b6df940 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -372,11 +372,11 @@ module Sinatra # routes if routes = self.class.routes[@request.request_method] original_params = @params - path = @request.path_info + path = unescape(@request.path_info) routes.each do |pattern, keys, conditions, block| if match = pattern.match(path) - values = match.captures.map{|val| val && unescape(val) } + values = match.captures.to_a params = if keys.any? keys.zip(values).inject({}) do |hash,(k,v)| @@ -673,7 +673,7 @@ module Sinatra if path.respond_to? :to_str special_chars = %w{. + ( )} pattern = - URI.encode(path).gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match| + path.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match| case match when "*" keys << 'splat' diff --git a/test/routing_test.rb b/test/routing_test.rb index 3f84bb6e..8657a1c2 100644 --- a/test/routing_test.rb +++ b/test/routing_test.rb @@ -158,7 +158,7 @@ describe "Routing" do it "literally matches + in paths" do route_def '/te+st/' - get '/te+st/' + get '/te%2Bst/' assert ok? get '/teeeeeeest/' assert not_found? @@ -243,7 +243,7 @@ describe "Routing" do assert_equal 'looks good', body end - it "supports paths that include spaces" do + it "matches paths that include spaces encoded with %20" do mock_app { get '/path with spaces' do 'looks good' @@ -255,6 +255,18 @@ describe "Routing" do assert_equal 'looks good', body end + it "matches paths that include spaces encoded with +" do + mock_app { + get '/path with spaces' do + 'looks good' + end + } + + get '/path+with+spaces' + assert ok? + assert_equal 'looks good', body + end + it "URL decodes named parameters and splats" do mock_app { get '/:foo/*' do