aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/journey/router.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/journey/router.rb')
-rw-r--r--actionpack/lib/action_dispatch/journey/router.rb47
1 files changed, 30 insertions, 17 deletions
diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb
index 06cdce1724..89a164f968 100644
--- a/actionpack/lib/action_dispatch/journey/router.rb
+++ b/actionpack/lib/action_dispatch/journey/router.rb
@@ -1,27 +1,33 @@
-require 'action_dispatch/journey/router/utils'
-require 'action_dispatch/journey/routes'
-require 'action_dispatch/journey/formatter'
+# frozen_string_literal: true
+
+require "action_dispatch/journey/router/utils"
+require "action_dispatch/journey/routes"
+require "action_dispatch/journey/formatter"
before = $-w
$-w = false
-require 'action_dispatch/journey/parser'
+require "action_dispatch/journey/parser"
$-w = before
-require 'action_dispatch/journey/route'
-require 'action_dispatch/journey/path/pattern'
+require "action_dispatch/journey/route"
+require "action_dispatch/journey/path/pattern"
module ActionDispatch
module Journey # :nodoc:
class Router # :nodoc:
- class RoutingError < ::StandardError # :nodoc:
- end
-
attr_accessor :routes
def initialize(routes)
@routes = routes
end
+ def eager_load!
+ # Eagerly trigger the simulator's initialization so
+ # it doesn't happen during a request cycle.
+ simulator
+ nil
+ end
+
def serve(req)
find_routes(req).each do |match, parameters, route|
set_params = req.path_parameters
@@ -29,16 +35,20 @@ module ActionDispatch
script_name = req.script_name
unless route.path.anchored
- req.script_name = (script_name.to_s + match.to_s).chomp('/')
+ req.script_name = (script_name.to_s + match.to_s).chomp("/")
req.path_info = match.post_match
req.path_info = "/" + req.path_info unless req.path_info.start_with? "/"
end
+ parameters = route.defaults.merge parameters.transform_values { |val|
+ val.dup.force_encoding(::Encoding::UTF_8)
+ }
+
req.path_parameters = set_params.merge parameters
status, headers, body = route.app.serve(req)
- if 'pass' == headers['X-Cascade']
+ if "pass" == headers["X-Cascade"]
req.script_name = script_name
req.path_info = path_info
req.path_parameters = set_params
@@ -48,7 +58,7 @@ module ActionDispatch
return [status, headers, body]
end
- return [404, {'X-Cascade' => 'pass'}, ['Not Found']]
+ [404, { "X-Cascade" => "pass" }, ["Not Found"]]
end
def recognize(rails_req)
@@ -58,6 +68,7 @@ module ActionDispatch
rails_req.path_info = match.post_match.sub(/^([^\/])/, '/\1')
end
+ parameters = route.defaults.merge parameters
yield(route, parameters)
end
end
@@ -72,7 +83,9 @@ module ActionDispatch
private
def partitioned_routes
- routes.partitioned_routes
+ routes.partition { |r|
+ r.path.anchored && r.ast.grep(Nodes::Symbol).all? { |n| n.default_regexp? }
+ }
end
def ast
@@ -92,7 +105,7 @@ module ActionDispatch
simulator.memos(path) { [] }
end
- def find_routes req
+ def find_routes(req)
routes = filter_routes(req.path_info).concat custom_routes.find_all { |r|
r.path.match(req.path_info)
}
@@ -107,9 +120,9 @@ module ActionDispatch
routes.sort_by!(&:precedence)
routes.map! { |r|
- match_data = r.path.match(req.path_info)
- path_parameters = r.defaults.dup
- match_data.names.zip(match_data.captures) { |name,val|
+ match_data = r.path.match(req.path_info)
+ path_parameters = {}
+ match_data.names.zip(match_data.captures) { |name, val|
path_parameters[name.to_sym] = Utils.unescape_uri(val) if val
}
[match_data, path_parameters, r]