diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/routing')
4 files changed, 55 insertions, 31 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 7a22b65c44..e43e897783 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -495,8 +495,6 @@ module ActionDispatch # Define a route that only recognizes HTTP GET. # For supported arguments, see <tt>Base#match</tt>. # - # Example: - # # get 'bacon', :to => 'food#bacon' def get(*args, &block) map_method(:get, args, &block) @@ -505,8 +503,6 @@ module ActionDispatch # Define a route that only recognizes HTTP POST. # For supported arguments, see <tt>Base#match</tt>. # - # Example: - # # post 'bacon', :to => 'food#bacon' def post(*args, &block) map_method(:post, args, &block) @@ -515,8 +511,6 @@ module ActionDispatch # Define a route that only recognizes HTTP PATCH. # For supported arguments, see <tt>Base#match</tt>. # - # Example: - # # patch 'bacon', :to => 'food#bacon' def patch(*args, &block) map_method(:patch, args, &block) @@ -525,8 +519,6 @@ module ActionDispatch # Define a route that only recognizes HTTP PUT. # For supported arguments, see <tt>Base#match</tt>. # - # Example: - # # put 'bacon', :to => 'food#bacon' def put(*args, &block) map_method(:put, args, &block) @@ -535,8 +527,6 @@ module ActionDispatch # Define a route that only recognizes HTTP DELETE. # For supported arguments, see <tt>Base#match</tt>. # - # Example: - # # delete 'broccoli', :to => 'food#broccoli' def delete(*args, &block) map_method(:delete, args, &block) @@ -681,7 +671,6 @@ module ActionDispatch # Scopes routes to a specific controller # - # Example: # controller "food" do # match "bacon", :action => "bacon" # end @@ -1329,17 +1318,18 @@ module ActionDispatch def draw(name) path = @draw_paths.find do |_path| - _path.join("#{name}.rb").file? + File.exists? "#{_path}/#{name}.rb" end unless path msg = "Your router tried to #draw the external file #{name}.rb,\n" \ "but the file was not found in:\n\n" msg += @draw_paths.map { |_path| " * #{_path}" }.join("\n") - raise msg + raise ArgumentError, msg end - - instance_eval(path.join("#{name}.rb").read) + + route_path = "#{path}/#{name}.rb" + instance_eval(File.read(route_path), route_path.to_s) end # match 'path' => 'controller#action' diff --git a/actionpack/lib/action_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index 95c588c00a..205ff44b1c 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -2,6 +2,7 @@ require 'action_dispatch/http/request' require 'active_support/core_ext/uri' require 'active_support/core_ext/array/extract_options' require 'rack/utils' +require 'action_controller/metal/exceptions' module ActionDispatch module Routing @@ -16,6 +17,14 @@ module ActionDispatch def call(env) req = Request.new(env) + # If any of the path parameters has a invalid encoding then + # raise since it's likely to trigger errors further on. + req.symbolized_path_parameters.each do |key, value| + unless value.valid_encoding? + raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}" + end + end + uri = URI.parse(path(req.symbolized_path_parameters, req)) uri.scheme ||= req.scheme uri.host ||= req.host @@ -35,6 +44,25 @@ module ActionDispatch def path(params, request) block.call params, request end + + def inspect + "redirect(#{status})" + end + end + + class PathRedirect < Redirect + def path(params, request) + (params.empty? || !block.match(/%\{\w*\}/)) ? block : (block % escape(params)) + end + + def inspect + "redirect(#{status}, #{block})" + end + + private + def escape(params) + Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }] + end end class OptionRedirect < Redirect # :nodoc: @@ -56,6 +84,10 @@ module ActionDispatch ActionDispatch::Http::URL.url_for url_options end + def inspect + "redirect(#{status}, #{options.map{ |k,v| "#{k}: #{v}" }.join(', ')})" + end + private def escape_path(params) Hash[params.map{ |k,v| [k, URI.parser.escape(v)] }] @@ -102,24 +134,15 @@ module ActionDispatch def redirect(*args, &block) options = args.extract_options! status = options.delete(:status) || 301 + path = args.shift return OptionRedirect.new(status, options) if options.any? - - path = args.shift - - block = lambda { |params, request| - (params.empty? || !path.match(/%\{\w*\}/)) ? path : (path % escape(params)) - } if String === path + return PathRedirect.new(status, path) if String === path block = path if path.respond_to? :call raise ArgumentError, "redirection argument not supported" unless block Redirect.new status, block end - - private - def escape(params) - Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }] - end end end end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 0ae668d42a..7872f4007e 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -26,6 +26,15 @@ module ActionDispatch def call(env) params = env[PARAMETERS_KEY] + + # If any of the path parameters has a invalid encoding then + # raise since it's likely to trigger errors further on. + params.each do |key, value| + unless value.valid_encoding? + raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}" + end + end + prepare_params!(params) # Just raise undefined constant errors if a controller was specified as default. @@ -654,9 +663,13 @@ module ActionDispatch dispatcher = dispatcher.app end - if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params, false) - dispatcher.prepare_params!(params) - return params + if dispatcher.is_a?(Dispatcher) + if dispatcher.controller(params, false) + dispatcher.prepare_params!(params) + return params + else + raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller" + end end end diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index ee02f4b531..fd3bed7e8f 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -132,8 +132,6 @@ module ActionDispatch # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to # +url_for+ is forwarded to the Routes module. # - # Examples: - # # url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :port => '8080' # # => 'http://somehost.org:8080/tasks/testing' # url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :anchor => 'ok', :only_path => true |
