Index: actionpack/test/controller/routing_test.rb =================================================================== --- actionpack/test/controller/routing_test.rb (revision 9250) +++ actionpack/test/controller/routing_test.rb (working copy) @@ -25,7 +25,7 @@ ActionController::Routing.use_controllers! ['controller'] @set = ActionController::Routing::RouteSet.new @set.draw do |map| - map.connect ':controller/:action/:variable' + map.connect ':controller/:action/:variable/*additional' end safe, unsafe = %w(: @ & = + $ , ;), %w(^ / ? # [ ]) @@ -36,17 +36,19 @@ end def test_route_generation_escapes_unsafe_path_characters - assert_equal "/contr#{@segment}oller/act#{@escaped}ion/var#{@escaped}iable", + assert_equal "/contr#{@segment}oller/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2", @set.generate(:controller => "contr#{@segment}oller", :action => "act#{@segment}ion", - :variable => "var#{@segment}iable") + :variable => "var#{@segment}iable", + :additional => ["add#{@segment}itional-1", "add#{@segment}itional-2"]) end def test_route_recognition_unescapes_path_components options = { :controller => "controller", :action => "act#{@segment}ion", - :variable => "var#{@segment}iable" } - assert_equal options, @set.recognize_path("/controller/act#{@escaped}ion/var#{@escaped}iable") + :variable => "var#{@segment}iable", + :additional => ["add#{@segment}itional-1", "add#{@segment}itional-2"] } + assert_equal options, @set.recognize_path("/controller/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2") end end Index: actionpack/lib/action_controller/routing/segments.rb =================================================================== --- actionpack/lib/action_controller/routing/segments.rb (revision 9250) +++ actionpack/lib/action_controller/routing/segments.rb (working copy) @@ -244,13 +244,14 @@ end class PathSegment < DynamicSegment #:nodoc: - RESERVED_PCHAR = "#{Segment::RESERVED_PCHAR}/" - UNSAFE_PCHAR = Regexp.new("[^#{URI::REGEXP::PATTERN::UNRESERVED}#{RESERVED_PCHAR}]", false, 'N').freeze - def interpolation_chunk(value_code = "#{local_name}") - "\#{URI.escape(#{value_code}.to_s, ActionController::Routing::PathSegment::UNSAFE_PCHAR)}" + "\#{#{value_code}}" end + def extract_value + "#{local_name} = hash[:#{key}] && hash[:#{key}].collect { |path_component| URI.escape(path_component, ActionController::Routing::Segment::UNSAFE_PCHAR) }.to_param #{"|| #{default.inspect}" if default}" + end + def default '' end