diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/journey/router.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/journey/router.rb | 47 |
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] |