Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 6185

Show
Ignore:
Timestamp:
02/21/07 10:05:07 (1 year ago)
Author:
bitsweat
Message:

Routing: better support for escaped values in route segments. Closes #7544.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/CHANGELOG

    r6184 r6185  
    11*SVN* 
     2 
     3* Routing: better support for escaped values in route segments.  #7544 [Chris 
     4Roos] 
    25 
    36* Introduce a cookie-based session store as the Rails default. Sessions typically contain at most a user_id and flash message; both fit within the 4K cookie size limit. A secure hash is included with the cookie to ensure data integrity (a user cannot alter his user_id without knowing the secret key included in the hash). If you have more than 4K of session data or don't want your data to be visible to the user, pick another session store. Cookie-based sessions are dramatically faster than the alternatives.  [Jeremy Kemper] 
  • trunk/actionpack/lib/action_controller/routing.rb

    r6113 r6185  
    413413        next_capture = 1 
    414414        extraction = segments.collect do |segment| 
    415           x = segment.match_extraction next_capture 
     415          x = segment.match_extraction(next_capture) 
    416416          next_capture += Regexp.new(segment.regexp_chunk).number_of_captures 
    417417          x 
     
    695695   
    696696      def interpolation_chunk 
    697         "\#{URI.escape(#{local_name}.to_s)}" 
     697        "\#{CGI.escape(#{local_name}.to_s)}" 
    698698      end 
    699699   
     
    726726      end 
    727727      def match_extraction(next_capture) 
    728         hangon = (default ? "|| #{default.inspect}" : "if match[#{next_capture}]") 
    729          
    730728        # All non code-related keys (such as :id, :slug) have to be unescaped as other CGI params 
    731         "params[:#{key}] = match[#{next_capture}] #{hangon}" 
     729        default_value = default ? default.inspect : nil 
     730        %[ 
     731          value = if (m = match[#{next_capture}]) 
     732            m = m.gsub('+', '%2B') 
     733            CGI.unescape(m) 
     734          else 
     735            #{default_value} 
     736          end 
     737          params[:#{key}] = value if value 
     738        ] 
    732739      end 
    733740   
     
    12931300   
    12941301      def recognize_path(path, environment={}) 
    1295         path = URI.unescape(path) 
    12961302        routes.each do |route| 
    12971303          result = route.recognize(path, environment) and return result 
  • trunk/actionpack/test/controller/routing_test.rb

    r6113 r6185  
    1212    (@warn_output ||= []) << msg 
    1313  end 
     14end 
     15 
     16class UriReservedCharactersRoutingTest < Test::Unit::TestCase 
     17  # See RFC 3986, section 2.2 Reserved Characters 
     18   
     19  def setup 
     20    ActionController::Routing.use_controllers! ['controller'] 
     21    @set = ActionController::Routing::RouteSet.new 
     22    @set.draw do |map| 
     23      map.connect ':controller/:action/:var' 
     24    end 
     25  end 
     26   
     27  def test_should_escape_reserved_uri_characters_within_individual_path_components 
     28    assert_equal '/controller/action/p1%3Ap2', @set.generate(:controller => 'controller', :action => 'action', :var => 'p1:p2') 
     29    assert_equal '/controller/action/p1%2Fp2', @set.generate(:controller => 'controller', :action => 'action', :var => 'p1/p2') 
     30    assert_equal '/controller/action/p1%3Fp2', @set.generate(:controller => 'controller', :action => 'action', :var => 'p1?p2') 
     31    assert_equal '/controller/action/p1%23p2', @set.generate(:controller => 'controller', :action => 'action', :var => 'p1#p2') 
     32    assert_equal '/controller/action/p1%5Bp2', @set.generate(:controller => 'controller', :action => 'action', :var => 'p1[p2') 
     33    assert_equal '/controller/action/p1%5Dp2', @set.generate(:controller => 'controller', :action => 'action', :var => 'p1]p2') 
     34    assert_equal '/controller/action/p1%40p2', @set.generate(:controller => 'controller', :action => 'action', :var => 'p1@p2') 
     35  end 
     36   
     37  def test_should_recognize_escaped_path_component_and_unescape 
     38    expected_options = {:var => "p1:p2", :controller => "controller", :action => "action"} 
     39    assert_equal expected_options, @set.recognize_path('/controller/action/p1%3Ap2') 
     40    expected_options = {:var => "p1/p2", :controller => "controller", :action => "action"} 
     41    assert_equal expected_options, @set.recognize_path('/controller/action/p1%2Fp2') 
     42    expected_options = {:var => "p1?p2", :controller => "controller", :action => "action"} 
     43    assert_equal expected_options, @set.recognize_path('/controller/action/p1%3Fp2') 
     44    expected_options = {:var => "p1#p2", :controller => "controller", :action => "action"} 
     45    assert_equal expected_options, @set.recognize_path('/controller/action/p1%23p2') 
     46    expected_options = {:var => "p1[p2", :controller => "controller", :action => "action"} 
     47    assert_equal expected_options, @set.recognize_path('/controller/action/p1%5Bp2') 
     48    expected_options = {:var => "p1]p2", :controller => "controller", :action => "action"} 
     49    assert_equal expected_options, @set.recognize_path('/controller/action/p1%5Dp2') 
     50    expected_options = {:var => "p1@p2", :controller => "controller", :action => "action"} 
     51    assert_equal expected_options, @set.recognize_path('/controller/action/p1%40p2') 
     52  end 
     53   
    1454end 
    1555