1
0
Fork 0
mirror of https://github.com/sinatra/sinatra synced 2023-03-27 23:18:01 -04:00

Merge pull request #271 from sinatra/slash

Change how URI escaping is handled
This commit is contained in:
Konstantin Haase 2011-05-18 22:17:17 -07:00
commit 62cd299580
2 changed files with 25 additions and 24 deletions

View file

@ -35,15 +35,6 @@ module Sinatra
@env.include? "HTTP_X_FORWARDED_HOST"
end
def route
@route ||= Rack::Utils.unescape(path_info)
end
def path_info=(value)
@route = nil
super
end
private
def accept_entry(entry)
@ -636,7 +627,6 @@ module Sinatra
@response = Response.new
@params = indifferent_params(@request.params)
template_cache.clear if settings.reload_templates
force_encoding(@request.route)
force_encoding(@params)
@response['Content-Type'] = nil
@ -732,10 +722,10 @@ module Sinatra
# Returns pass block.
def process_route(pattern, keys, conditions)
@original_params ||= @params
route = @request.route
route = @request.path_info
route = '/' if route.empty? and not settings.empty_path_info?
if match = pattern.match(route)
values = match.captures.to_a
values = match.captures.to_a.map { |v| force_encoding URI.decode(v) if v }
params =
if keys.any?
keys.zip(values).inject({}) do |hash,(k,v)|
@ -1158,19 +1148,16 @@ module Sinatra
keys = []
if path.respond_to? :to_str
special_chars = %w{. + ( ) $}
pattern =
path.to_str.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
case match
when "*"
keys << 'splat'
"(.*?)"
when *special_chars
Regexp.escape(match)
else
keys << $2[1..-1]
"([^/?#]+)"
end
pattern = path.to_str.gsub(/[^\?\%\\\/\:\*\w]/) { |c| encoded(c) }
pattern.gsub! /((:\w+)|\*)/ do |match|
if match == "*"
keys << 'splat'
"(.*?)"
else
keys << $2[1..-1]
"([^/?#]+)"
end
end
[/^#{pattern}$/, keys]
elsif path.respond_to?(:keys) && path.respond_to?(:match)
[path, path.keys]
@ -1183,6 +1170,13 @@ module Sinatra
end
end
def encoded(char)
enc = URI.encode(char)
enc = "(?:#{Regexp.escape enc}|#{URI.encode char, /./})" if enc == char
enc = "(?:#{enc}|#{encoded('+')})" if char == " "
enc
end
public
# Makes the methods defined in the block and in the Modules given
# in `extensions` available to the handlers and templates

View file

@ -78,6 +78,13 @@ class RoutingTest < Test::Unit::TestCase
assert_equal 200, status
end
it "it handles encoded slashes correctly" do
mock_app { get("/:a") { |a| a } }
get '/foo%2Fbar'
assert_equal 200, status
assert_body "foo/bar"
end
it "overrides the content-type in error handlers" do
mock_app {
before { content_type 'text/plain' }