aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorJoshua Peek <josh@joshpeek.com>2009-12-01 22:48:42 -0600
committerJoshua Peek <josh@joshpeek.com>2009-12-01 22:48:42 -0600
commit2fbd6f46fd00a334119f1a25394046963831ce3e (patch)
tree1328ee8ade328a129df47ddae815bd5a0c6dab5b /actionpack
parent7fe19d415ab80727d685c163d7a0413ca6bfe585 (diff)
downloadrails-2fbd6f46fd00a334119f1a25394046963831ce3e.tar.gz
rails-2fbd6f46fd00a334119f1a25394046963831ce3e.tar.bz2
rails-2fbd6f46fd00a334119f1a25394046963831ce3e.zip
Simply track controller namespaces instead of a complete list of
possible controllers to route to
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_dispatch/routing.rb59
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb10
2 files changed, 22 insertions, 47 deletions
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index 9b977800b4..9159bb6395 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -265,6 +265,7 @@ module ActionDispatch
SEPARATORS = %w( / . ? )
HTTP_METHODS = [:get, :head, :post, :put, :delete, :options]
+ CONTROLLER_REGEXP = /[_a-zA-Z0-9]+/
# The root paths which may contain controller files
mattr_accessor :controller_paths
@@ -277,7 +278,11 @@ module ActionDispatch
class << self
def controller_constraints
- @controller_constraints ||= Regexp.union(*possible_controllers.collect { |n| Regexp.escape(n) })
+ @controller_constraints ||= begin
+ source = controller_namespaces.map { |ns| "#{Regexp.escape(ns)}/#{CONTROLLER_REGEXP.source}" }
+ source << CONTROLLER_REGEXP.source
+ Regexp.compile(source.sort.reverse.join('|'))
+ end
end
def clear_controller_cache!
@@ -285,57 +290,25 @@ module ActionDispatch
end
private
- # Returns the array of controller names currently available to ActionController::Routing.
- def possible_controllers
- possible_controllers = []
+ def controller_namespaces
+ namespaces = Set.new
- # Find any controller classes already in memory
+ # Find any nested controllers already in memory
ActionController::Base.subclasses.each do |klass|
controller_name = klass.underscore
- controller_name.gsub!(/_controller\Z/, '')
- possible_controllers << controller_name
+ namespaces << controller_name.split('/')[0...-1].join('/')
end
- # Find controllers in controllers/ directory
- paths = controller_paths.select { |path| File.directory?(path) && path != "." }
- seen_paths = Hash.new {|h, k| h[k] = true; false}
- normalize_paths(paths).each do |load_path|
+ # Find namespaces in controllers/ directory
+ controller_paths.each do |load_path|
+ load_path = File.expand_path(load_path)
Dir["#{load_path}/**/*_controller.rb"].collect do |path|
- next if seen_paths[path.gsub(%r{^\.[/\\]}, "")]
-
- controller_name = path[(load_path.length + 1)..-1]
-
- controller_name.gsub!(/_controller\.rb\Z/, '')
- possible_controllers << controller_name
+ namespaces << File.dirname(path).sub(/#{load_path}\/?/, '')
end
end
- # remove duplicates
- possible_controllers.uniq!
-
- possible_controllers
- end
-
- # Returns an array of paths, cleaned of double-slashes and relative path references.
- # * "\\\" and "//" become "\\" or "/".
- # * "/foo/bar/../config" becomes "/foo/config".
- # The returned array is sorted by length, descending.
- def normalize_paths(paths)
- # do the hokey-pokey of path normalization...
- paths = paths.collect do |path|
- path = path.
- gsub("//", "/"). # replace double / chars with a single
- gsub("\\\\", "\\"). # replace double \ chars with a single
- gsub(%r{(.)[\\/]$}, '\1') # drop final / or \ if path ends with it
-
- # eliminate .. paths where possible
- re = %r{[^/\\]+[/\\]\.\.[/\\]}
- path.gsub!(re, "") while path.match(re)
- path
- end
-
- # start with longest path, first
- paths = paths.uniq.sort_by { |path| - path.length }
+ namespaces.delete('')
+ namespaces
end
end
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 18e18c5820..c2f6531a74 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -27,11 +27,13 @@ module ActionDispatch
end
end
+ unless controller = controller(params)
+ return [417, {}, []]
+ end
+
if env['action_controller.recognize']
- controller(params)
[200, {}, params]
else
- controller = controller(params)
controller.action(params[:action]).call(env)
end
end
@@ -42,8 +44,8 @@ module ActionDispatch
controller = "#{params[:controller].camelize}Controller"
ActiveSupport::Inflector.constantize(controller)
end
- rescue NameError => e
- raise ActionController::RoutingError, e.message
+ rescue NameError
+ nil
end
def merge_default_action!(params)