actionpack 4.2.11.3 → 5.0.7.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +890 -384
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/abstract_controller/base.rb +28 -38
  6. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
  7. data/lib/abstract_controller/caching.rb +62 -0
  8. data/lib/abstract_controller/callbacks.rb +54 -19
  9. data/lib/abstract_controller/collector.rb +4 -9
  10. data/lib/abstract_controller/error.rb +4 -0
  11. data/lib/abstract_controller/helpers.rb +4 -3
  12. data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
  13. data/lib/abstract_controller/rendering.rb +28 -18
  14. data/lib/abstract_controller/translation.rb +8 -7
  15. data/lib/abstract_controller.rb +6 -2
  16. data/lib/action_controller/api/api_rendering.rb +14 -0
  17. data/lib/action_controller/api.rb +147 -0
  18. data/lib/action_controller/base.rb +14 -11
  19. data/lib/action_controller/caching.rb +13 -58
  20. data/lib/action_controller/form_builder.rb +48 -0
  21. data/lib/action_controller/log_subscriber.rb +3 -10
  22. data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
  23. data/lib/action_controller/metal/conditional_get.rb +106 -34
  24. data/lib/action_controller/metal/cookies.rb +1 -3
  25. data/lib/action_controller/metal/data_streaming.rb +14 -34
  26. data/lib/action_controller/metal/etag_with_template_digest.rb +8 -2
  27. data/lib/action_controller/metal/exceptions.rb +11 -6
  28. data/lib/action_controller/metal/force_ssl.rb +11 -11
  29. data/lib/action_controller/metal/head.rb +14 -8
  30. data/lib/action_controller/metal/helpers.rb +15 -6
  31. data/lib/action_controller/metal/http_authentication.rb +44 -35
  32. data/lib/action_controller/metal/implicit_render.rb +61 -6
  33. data/lib/action_controller/metal/instrumentation.rb +5 -5
  34. data/lib/action_controller/metal/live.rb +71 -88
  35. data/lib/action_controller/metal/mime_responds.rb +27 -42
  36. data/lib/action_controller/metal/params_wrapper.rb +9 -9
  37. data/lib/action_controller/metal/redirecting.rb +32 -9
  38. data/lib/action_controller/metal/renderers.rb +83 -40
  39. data/lib/action_controller/metal/rendering.rb +38 -6
  40. data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
  41. data/lib/action_controller/metal/rescue.rb +3 -12
  42. data/lib/action_controller/metal/streaming.rb +4 -4
  43. data/lib/action_controller/metal/strong_parameters.rb +527 -134
  44. data/lib/action_controller/metal/testing.rb +1 -12
  45. data/lib/action_controller/metal/url_for.rb +12 -5
  46. data/lib/action_controller/metal.rb +88 -63
  47. data/lib/action_controller/railtie.rb +11 -7
  48. data/lib/action_controller/renderer.rb +113 -0
  49. data/lib/action_controller/template_assertions.rb +9 -0
  50. data/lib/action_controller/test_case.rb +311 -374
  51. data/lib/action_controller.rb +12 -9
  52. data/lib/action_dispatch/http/cache.rb +73 -34
  53. data/lib/action_dispatch/http/filter_parameters.rb +16 -12
  54. data/lib/action_dispatch/http/filter_redirect.rb +7 -8
  55. data/lib/action_dispatch/http/headers.rb +45 -14
  56. data/lib/action_dispatch/http/mime_negotiation.rb +42 -23
  57. data/lib/action_dispatch/http/mime_type.rb +126 -90
  58. data/lib/action_dispatch/http/mime_types.rb +3 -4
  59. data/lib/action_dispatch/http/parameter_filter.rb +19 -9
  60. data/lib/action_dispatch/http/parameters.rb +70 -40
  61. data/lib/action_dispatch/http/request.rb +144 -89
  62. data/lib/action_dispatch/http/response.rb +215 -102
  63. data/lib/action_dispatch/http/upload.rb +6 -2
  64. data/lib/action_dispatch/http/url.rb +117 -8
  65. data/lib/action_dispatch/journey/formatter.rb +47 -30
  66. data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
  67. data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
  68. data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
  69. data/lib/action_dispatch/journey/nodes/node.rb +14 -4
  70. data/lib/action_dispatch/journey/parser.rb +2 -0
  71. data/lib/action_dispatch/journey/parser_extras.rb +8 -2
  72. data/lib/action_dispatch/journey/path/pattern.rb +38 -42
  73. data/lib/action_dispatch/journey/route.rb +88 -26
  74. data/lib/action_dispatch/journey/router/utils.rb +5 -5
  75. data/lib/action_dispatch/journey/router.rb +8 -10
  76. data/lib/action_dispatch/journey/routes.rb +14 -15
  77. data/lib/action_dispatch/journey/visitors.rb +89 -44
  78. data/lib/action_dispatch/middleware/callbacks.rb +10 -1
  79. data/lib/action_dispatch/middleware/cookies.rb +188 -134
  80. data/lib/action_dispatch/middleware/debug_exceptions.rb +128 -49
  81. data/lib/action_dispatch/middleware/debug_locks.rb +122 -0
  82. data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
  83. data/lib/action_dispatch/middleware/executor.rb +19 -0
  84. data/lib/action_dispatch/middleware/flash.rb +66 -45
  85. data/lib/action_dispatch/middleware/params_parser.rb +32 -46
  86. data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
  87. data/lib/action_dispatch/middleware/reloader.rb +14 -58
  88. data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
  89. data/lib/action_dispatch/middleware/request_id.rb +11 -6
  90. data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
  91. data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
  92. data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
  93. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
  94. data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
  95. data/lib/action_dispatch/middleware/ssl.rb +124 -36
  96. data/lib/action_dispatch/middleware/stack.rb +44 -40
  97. data/lib/action_dispatch/middleware/static.rb +51 -35
  98. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
  99. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  100. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
  101. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  102. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  103. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
  104. data/lib/action_dispatch/railtie.rb +2 -2
  105. data/lib/action_dispatch/request/session.rb +69 -33
  106. data/lib/action_dispatch/request/utils.rb +51 -19
  107. data/lib/action_dispatch/routing/inspector.rb +32 -43
  108. data/lib/action_dispatch/routing/mapper.rb +515 -348
  109. data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
  110. data/lib/action_dispatch/routing/redirection.rb +5 -4
  111. data/lib/action_dispatch/routing/route_set.rb +148 -240
  112. data/lib/action_dispatch/routing/url_for.rb +27 -10
  113. data/lib/action_dispatch/routing.rb +17 -13
  114. data/lib/action_dispatch/testing/assertion_response.rb +45 -0
  115. data/lib/action_dispatch/testing/assertions/response.rb +38 -20
  116. data/lib/action_dispatch/testing/assertions/routing.rb +16 -12
  117. data/lib/action_dispatch/testing/assertions.rb +1 -1
  118. data/lib/action_dispatch/testing/integration.rb +377 -149
  119. data/lib/action_dispatch/testing/request_encoder.rb +53 -0
  120. data/lib/action_dispatch/testing/test_process.rb +24 -20
  121. data/lib/action_dispatch/testing/test_request.rb +22 -31
  122. data/lib/action_dispatch/testing/test_response.rb +12 -4
  123. data/lib/action_dispatch.rb +4 -1
  124. data/lib/action_pack/gem_version.rb +4 -4
  125. data/lib/action_pack.rb +1 -1
  126. metadata +32 -34
  127. data/lib/action_controller/metal/hide_actions.rb +0 -40
  128. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  129. data/lib/action_controller/middleware.rb +0 -39
  130. data/lib/action_controller/model_naming.rb +0 -12
  131. data/lib/action_dispatch/journey/backwards.rb +0 -5
  132. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  133. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  134. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  135. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
  136. /data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
@@ -1,11 +1,9 @@
1
1
  require 'action_dispatch/journey'
2
- require 'forwardable'
3
2
  require 'active_support/concern'
4
3
  require 'active_support/core_ext/object/to_query'
5
4
  require 'active_support/core_ext/hash/slice'
6
5
  require 'active_support/core_ext/module/remove_method'
7
6
  require 'active_support/core_ext/array/extract_options'
8
- require 'active_support/core_ext/string/filters'
9
7
  require 'action_controller/metal/exceptions'
10
8
  require 'action_dispatch/http/request'
11
9
  require 'action_dispatch/routing/endpoint'
@@ -20,67 +18,48 @@ module ActionDispatch
20
18
  # alias inspect to to_s.
21
19
  alias inspect to_s
22
20
 
23
- mattr_accessor :relative_url_root
24
-
25
21
  class Dispatcher < Routing::Endpoint
26
- def initialize(defaults)
27
- @defaults = defaults
22
+ def initialize(raise_on_name_error)
23
+ @raise_on_name_error = raise_on_name_error
28
24
  end
29
25
 
30
26
  def dispatcher?; true; end
31
27
 
32
28
  def serve(req)
33
- req.check_path_parameters!
34
- params = req.path_parameters
35
-
36
- prepare_params!(params)
37
-
38
- # Just raise undefined constant errors if a controller was specified as default.
39
- unless controller = controller(params, @defaults.key?(:controller))
29
+ params = req.path_parameters
30
+ controller = controller req
31
+ res = controller.make_response! req
32
+ dispatch(controller, params[:action], req, res)
33
+ rescue ActionController::RoutingError
34
+ if @raise_on_name_error
35
+ raise
36
+ else
40
37
  return [404, {'X-Cascade' => 'pass'}, []]
41
38
  end
42
-
43
- dispatch(controller, params[:action], req.env)
44
39
  end
45
40
 
46
- def prepare_params!(params)
47
- normalize_controller!(params)
48
- merge_default_action!(params)
49
- end
41
+ private
50
42
 
51
- # If this is a default_controller (i.e. a controller specified by the user)
52
- # we should raise an error in case it's not found, because it usually means
53
- # a user error. However, if the controller was retrieved through a dynamic
54
- # segment, as in :controller(/:action), we should simply return nil and
55
- # delegate the control back to Rack cascade. Besides, if this is not a default
56
- # controller, it means we should respect the @scope[:module] parameter.
57
- def controller(params, default_controller=true)
58
- if params && params.key?(:controller)
59
- controller_param = params[:controller]
60
- controller_reference(controller_param)
61
- end
43
+ def controller(req)
44
+ req.controller_class
62
45
  rescue NameError => e
63
- raise ActionController::RoutingError, e.message, e.backtrace if default_controller
46
+ raise ActionController::RoutingError, e.message, e.backtrace
64
47
  end
65
48
 
66
- private
67
-
68
- def controller_reference(controller_param)
69
- const_name = "#{controller_param.camelize}Controller"
70
- ActiveSupport::Dependencies.constantize(const_name)
49
+ def dispatch(controller, action, req, res)
50
+ controller.dispatch(action, req, res)
71
51
  end
52
+ end
72
53
 
73
- def dispatch(controller, action, env)
74
- controller.action(action).call(env)
54
+ class StaticDispatcher < Dispatcher
55
+ def initialize(controller_class)
56
+ super(false)
57
+ @controller_class = controller_class
75
58
  end
76
59
 
77
- def normalize_controller!(params)
78
- params[:controller] = params[:controller].underscore if params.key?(:controller)
79
- end
60
+ private
80
61
 
81
- def merge_default_action!(params)
82
- params[:action] ||= 'index'
83
- end
62
+ def controller(_); @controller_class; end
84
63
  end
85
64
 
86
65
  # A NamedRouteCollection instance is a collection of named routes, and also
@@ -88,7 +67,8 @@ module ActionDispatch
88
67
  # named routes.
89
68
  class NamedRouteCollection
90
69
  include Enumerable
91
- attr_reader :routes, :url_helpers_module
70
+ attr_reader :routes, :url_helpers_module, :path_helpers_module
71
+ private :routes
92
72
 
93
73
  def initialize
94
74
  @routes = {}
@@ -103,14 +83,6 @@ module ActionDispatch
103
83
  @path_helpers.include?(key) || @url_helpers.include?(key)
104
84
  end
105
85
 
106
- def helpers
107
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
108
- `named_routes.helpers` is deprecated, please use `route_defined?(route_name)`
109
- to see if a named route was defined.
110
- MSG
111
- @path_helpers + @url_helpers
112
- end
113
-
114
86
  def helper_names
115
87
  @path_helpers.map(&:to_s) + @url_helpers.map(&:to_s)
116
88
  end
@@ -139,7 +111,7 @@ module ActionDispatch
139
111
  @url_helpers_module.send :undef_method, url_name
140
112
  end
141
113
  routes[key] = route
142
- define_url_helper @path_helpers_module, route, path_name, route.defaults, name, LEGACY
114
+ define_url_helper @path_helpers_module, route, path_name, route.defaults, name, PATH
143
115
  define_url_helper @url_helpers_module, route, url_name, route.defaults, name, UNKNOWN
144
116
 
145
117
  @path_helpers << path_name
@@ -151,6 +123,7 @@ module ActionDispatch
151
123
  end
152
124
 
153
125
  def key?(name)
126
+ return unless name
154
127
  routes.key? name.to_sym
155
128
  end
156
129
 
@@ -171,25 +144,6 @@ module ActionDispatch
171
144
  routes.length
172
145
  end
173
146
 
174
- def path_helpers_module(warn = false)
175
- if warn
176
- mod = @path_helpers_module
177
- helpers = @path_helpers
178
- Module.new do
179
- include mod
180
-
181
- helpers.each do |meth|
182
- define_method(meth) do |*args, &block|
183
- ActiveSupport::Deprecation.warn("The method `#{meth}` cannot be used here as a full URL is required. Use `#{meth.to_s.sub(/_path$/, '_url')}` instead")
184
- super(*args, &block)
185
- end
186
- end
187
- end
188
- else
189
- @path_helpers_module
190
- end
191
- end
192
-
193
147
  class UrlHelper
194
148
  def self.create(route, options, route_name, url_strategy)
195
149
  if optimize_helper?(route)
@@ -227,11 +181,8 @@ module ActionDispatch
227
181
  private
228
182
 
229
183
  def optimized_helper(args)
230
- params = parameterize_args(args)
231
- missing_keys = missing_keys(params)
232
-
233
- unless missing_keys.empty?
234
- raise_generation_error(params, missing_keys)
184
+ params = parameterize_args(args) do
185
+ raise_generation_error(args)
235
186
  end
236
187
 
237
188
  @route.format params
@@ -243,16 +194,21 @@ module ActionDispatch
243
194
 
244
195
  def parameterize_args(args)
245
196
  params = {}
246
- @required_parts.zip(args.map(&:to_param)) { |k,v| params[k] = v }
197
+ @arg_size.times { |i|
198
+ key = @required_parts[i]
199
+ value = args[i].to_param
200
+ yield key if value.nil? || value.empty?
201
+ params[key] = value
202
+ }
247
203
  params
248
204
  end
249
205
 
250
- def missing_keys(args)
251
- args.select{ |part, arg| arg.nil? || arg.empty? }.keys
252
- end
253
-
254
- def raise_generation_error(args, missing_keys)
255
- constraints = Hash[@route.requirements.merge(args).sort_by{|k,v| k.to_s}]
206
+ def raise_generation_error(args)
207
+ missing_keys = []
208
+ params = parameterize_args(args) { |missing_key|
209
+ missing_keys << missing_key
210
+ }
211
+ constraints = Hash[@route.requirements.merge(params).sort_by{|k,v| k.to_s}]
256
212
  message = "No route matches #{constraints.inspect}"
257
213
  message << " missing required keys: #{missing_keys.sort.inspect}"
258
214
 
@@ -272,7 +228,7 @@ module ActionDispatch
272
228
  controller_options = t.url_options
273
229
  options = controller_options.merge @options
274
230
  hash = handle_positional_args(controller_options,
275
- deprecate_string_options(inner_options) || {},
231
+ inner_options || {},
276
232
  args,
277
233
  options,
278
234
  @segment_keys)
@@ -292,34 +248,21 @@ module ActionDispatch
292
248
  if args.size < path_params_size
293
249
  path_params -= controller_options.keys
294
250
  path_params -= result.keys
251
+ else
252
+ path_params = path_params.dup
253
+ end
254
+ inner_options.each_key do |key|
255
+ path_params.delete(key)
295
256
  end
296
- path_params.each { |param|
297
- value = inner_options.fetch(param) { args.shift }
298
257
 
299
- unless param == :format && value.nil?
300
- result[param] = value
301
- end
302
- }
258
+ args.each_with_index do |arg, index|
259
+ param = path_params[index]
260
+ result[param] = arg if param
261
+ end
303
262
  end
304
263
 
305
264
  result.merge!(inner_options)
306
265
  end
307
-
308
- DEPRECATED_STRING_OPTIONS = %w[controller action]
309
-
310
- def deprecate_string_options(options)
311
- options ||= {}
312
- deprecated_string_options = options.keys & DEPRECATED_STRING_OPTIONS
313
- if deprecated_string_options.any?
314
- msg = "Calling URL helpers with string keys #{deprecated_string_options.join(", ")} is deprecated. Use symbols instead."
315
- ActiveSupport::Deprecation.warn(msg)
316
- deprecated_string_options.each do |option|
317
- value = options.delete(option)
318
- options[option.to_sym] = value
319
- end
320
- end
321
- options
322
- end
323
266
  end
324
267
 
325
268
  private
@@ -340,8 +283,17 @@ module ActionDispatch
340
283
  helper = UrlHelper.create(route, opts, route_key, url_strategy)
341
284
  mod.module_eval do
342
285
  define_method(name) do |*args|
343
- options = nil
344
- options = args.pop if args.last.is_a? Hash
286
+ last = args.last
287
+ options = case last
288
+ when Hash
289
+ args.pop
290
+ when ActionController::Parameters
291
+ if last.permitted?
292
+ args.pop.to_h
293
+ else
294
+ raise ArgumentError, ActionDispatch::Routing::INSECURE_URL_PARAMETERS_MESSAGE
295
+ end
296
+ end
345
297
  helper.call self, args, options
346
298
  end
347
299
  end
@@ -350,38 +302,12 @@ module ActionDispatch
350
302
 
351
303
  # strategy for building urls to send to the client
352
304
  PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) }
353
- FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) }
354
305
  UNKNOWN = ->(options) { ActionDispatch::Http::URL.url_for(options) }
355
- LEGACY = ->(options) {
356
- if options.key?(:only_path)
357
- if options[:only_path]
358
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
359
- You are calling a `*_path` helper with the `only_path` option
360
- explicitly set to `true`. This option will stop working on
361
- path helpers in Rails 5. Simply remove the `only_path: true`
362
- argument from your call as it is redundant when applied to a
363
- path helper.
364
- MSG
365
-
366
- PATH.call(options)
367
- else
368
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
369
- You are calling a `*_path` helper with the `only_path` option
370
- explicitly set to `false`. This option will stop working on
371
- path helpers in Rails 5. Use the corresponding `*_url` helper
372
- instead.
373
- MSG
374
-
375
- FULL.call(options)
376
- end
377
- else
378
- PATH.call(options)
379
- end
380
- }
381
306
 
382
307
  attr_accessor :formatter, :set, :named_routes, :default_scope, :router
383
308
  attr_accessor :disable_clear_and_finalize, :resources_path_names
384
- attr_accessor :default_url_options, :request_class
309
+ attr_accessor :default_url_options
310
+ attr_reader :env_key
385
311
 
386
312
  alias :routes :set
387
313
 
@@ -389,22 +315,59 @@ module ActionDispatch
389
315
  { :new => 'new', :edit => 'edit' }
390
316
  end
391
317
 
392
- def initialize(request_class = ActionDispatch::Request)
318
+ def self.new_with_config(config)
319
+ route_set_config = DEFAULT_CONFIG
320
+
321
+ # engines apparently don't have this set
322
+ if config.respond_to? :relative_url_root
323
+ route_set_config.relative_url_root = config.relative_url_root
324
+ end
325
+
326
+ if config.respond_to? :api_only
327
+ route_set_config.api_only = config.api_only
328
+ end
329
+
330
+ new route_set_config
331
+ end
332
+
333
+ Config = Struct.new :relative_url_root, :api_only
334
+
335
+ DEFAULT_CONFIG = Config.new(nil, false)
336
+
337
+ def initialize(config = DEFAULT_CONFIG)
393
338
  self.named_routes = NamedRouteCollection.new
394
339
  self.resources_path_names = self.class.default_resources_path_names
395
340
  self.default_url_options = {}
396
- self.request_class = request_class
397
341
 
342
+ @config = config
398
343
  @append = []
399
344
  @prepend = []
400
345
  @disable_clear_and_finalize = false
401
346
  @finalized = false
347
+ @env_key = "ROUTES_#{object_id}_SCRIPT_NAME".freeze
402
348
 
403
349
  @set = Journey::Routes.new
404
350
  @router = Journey::Router.new @set
405
- @formatter = Journey::Formatter.new @set
351
+ @formatter = Journey::Formatter.new self
352
+ end
353
+
354
+ def relative_url_root
355
+ @config.relative_url_root
406
356
  end
407
357
 
358
+ def api_only?
359
+ @config.api_only
360
+ end
361
+
362
+ def request_class
363
+ ActionDispatch::Request
364
+ end
365
+
366
+ def make_request(env)
367
+ request_class.new env
368
+ end
369
+ private :make_request
370
+
408
371
  def draw(&block)
409
372
  clear! unless @disable_clear_and_finalize
410
373
  eval_block(block)
@@ -421,10 +384,6 @@ module ActionDispatch
421
384
  end
422
385
 
423
386
  def eval_block(block)
424
- if block.arity == 1
425
- raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
426
- "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
427
- end
428
387
  mapper = Mapper.new(self)
429
388
  if default_scope
430
389
  mapper.with_default_scope(default_scope, &block)
@@ -448,10 +407,6 @@ module ActionDispatch
448
407
  @prepend.each { |blk| eval_block(blk) }
449
408
  end
450
409
 
451
- def dispatcher(defaults)
452
- Routing::RouteSet::Dispatcher.new(defaults)
453
- end
454
-
455
410
  module MountedHelpers
456
411
  extend ActiveSupport::Concern
457
412
  include UrlFor
@@ -495,7 +450,14 @@ module ActionDispatch
495
450
  # Rails.application.routes.url_helpers.url_for(args)
496
451
  @_routes = routes
497
452
  class << self
498
- delegate :url_for, :optimize_routes_generation?, to: '@_routes'
453
+ def url_for(options)
454
+ @_routes.url_for(options)
455
+ end
456
+
457
+ def optimize_routes_generation?
458
+ @_routes.optimize_routes_generation?
459
+ end
460
+
499
461
  attr_reader :_routes
500
462
  def url_options; {}; end
501
463
  end
@@ -513,12 +475,10 @@ module ActionDispatch
513
475
 
514
476
  if supports_path
515
477
  path_helpers = routes.named_routes.path_helpers_module
516
- else
517
- path_helpers = routes.named_routes.path_helpers_module(true)
518
- end
519
478
 
520
- include path_helpers
521
- extend path_helpers
479
+ include path_helpers
480
+ extend path_helpers
481
+ end
522
482
 
523
483
  # plus a singleton class method called _routes ...
524
484
  included do
@@ -542,7 +502,7 @@ module ActionDispatch
542
502
  routes.empty?
543
503
  end
544
504
 
545
- def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
505
+ def add_route(mapping, path_ast, name, anchor)
546
506
  raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i)
547
507
 
548
508
  if name && named_routes[name]
@@ -553,74 +513,32 @@ module ActionDispatch
553
513
  "http://guides.rubyonrails.org/routing.html#restricting-the-routes-created"
554
514
  end
555
515
 
556
- path = conditions.delete :path_info
557
- ast = conditions.delete :parsed_path_info
558
- path = build_path(path, ast, requirements, anchor)
559
- conditions = build_conditions(conditions, path.names.map { |x| x.to_sym })
560
-
561
- route = @set.add_route(app, path, conditions, defaults, name)
516
+ route = @set.add_route(name, mapping)
562
517
  named_routes[name] = route if name
563
- route
564
- end
565
-
566
- def build_path(path, ast, requirements, anchor)
567
- strexp = Journey::Router::Strexp.new(
568
- ast,
569
- path,
570
- requirements,
571
- SEPARATORS,
572
- anchor)
573
-
574
- pattern = Journey::Path::Pattern.new(strexp)
575
518
 
576
- builder = Journey::GTG::Builder.new pattern.spec
577
-
578
- # Get all the symbol nodes followed by literals that are not the
579
- # dummy node.
580
- symbols = pattern.spec.grep(Journey::Nodes::Symbol).find_all { |n|
581
- builder.followpos(n).first.literal?
582
- }
583
-
584
- # Get all the symbol nodes preceded by literals.
585
- symbols.concat pattern.spec.find_all(&:literal?).map { |n|
586
- builder.followpos(n).first
587
- }.find_all(&:symbol?)
588
-
589
- symbols.each { |x|
590
- x.regexp = /(?:#{Regexp.union(x.regexp, '-')})+/
591
- }
592
-
593
- pattern
594
- end
595
- private :build_path
596
-
597
- def build_conditions(current_conditions, path_values)
598
- conditions = current_conditions.dup
599
-
600
- # Rack-Mount requires that :request_method be a regular expression.
601
- # :request_method represents the HTTP verb that matches this route.
602
- #
603
- # Here we munge values before they get sent on to rack-mount.
604
- verbs = conditions[:request_method] || []
605
- unless verbs.empty?
606
- conditions[:request_method] = %r[^#{verbs.join('|')}$]
519
+ if route.segment_keys.include?(:controller)
520
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
521
+ Using a dynamic :controller segment in a route is deprecated and
522
+ will be removed in Rails 5.2.
523
+ MSG
607
524
  end
608
525
 
609
- conditions.keep_if do |k, _|
610
- k == :action || k == :controller || k == :required_defaults ||
611
- @request_class.public_method_defined?(k) || path_values.include?(k)
526
+ if route.segment_keys.include?(:action)
527
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
528
+ Using a dynamic :action segment in a route is deprecated and
529
+ will be removed in Rails 5.2.
530
+ MSG
612
531
  end
532
+
533
+ route
613
534
  end
614
- private :build_conditions
615
535
 
616
536
  class Generator
617
537
  PARAMETERIZE = lambda do |name, value|
618
538
  if name == :controller
619
539
  value
620
- elsif value.is_a?(Array)
621
- value.map { |v| v.to_param }.join('/')
622
- elsif param = value.to_param
623
- param
540
+ else
541
+ value.to_param
624
542
  end
625
543
  end
626
544
 
@@ -628,16 +546,14 @@ module ActionDispatch
628
546
 
629
547
  def initialize(named_route, options, recall, set)
630
548
  @named_route = named_route
631
- @options = options.dup
632
- @recall = recall.dup
549
+ @options = options
550
+ @recall = recall
633
551
  @set = set
634
552
 
635
- normalize_recall!
636
553
  normalize_options!
637
554
  normalize_controller_action_id!
638
555
  use_relative_controller!
639
556
  normalize_controller!
640
- normalize_action!
641
557
  end
642
558
 
643
559
  def controller
@@ -651,16 +567,11 @@ module ActionDispatch
651
567
  def use_recall_for(key)
652
568
  if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key])
653
569
  if !named_route_exists? || segment_keys.include?(key)
654
- @options[key] = @recall.delete(key)
570
+ @options[key] = @recall[key]
655
571
  end
656
572
  end
657
573
  end
658
574
 
659
- # Set 'index' as default action for recall
660
- def normalize_recall!
661
- @recall[:action] ||= 'index'
662
- end
663
-
664
575
  def normalize_options!
665
576
  # If an explicit :controller was given, always make :action explicit
666
577
  # too, so that action expiry works as expected for things like
@@ -705,13 +616,12 @@ module ActionDispatch
705
616
 
706
617
  # Remove leading slashes from controllers
707
618
  def normalize_controller!
708
- @options[:controller] = controller.sub(%r{^/}, '') if controller
709
- end
710
-
711
- # Move 'index' action from options to recall
712
- def normalize_action!
713
- if @options[:action] == 'index'
714
- @recall[:action] = @options.delete(:action)
619
+ if controller
620
+ if controller.start_with?("/".freeze)
621
+ @options[:controller] = controller[1..-1]
622
+ else
623
+ @options[:controller] = controller
624
+ end
715
625
  end
716
626
  end
717
627
 
@@ -812,7 +722,7 @@ module ActionDispatch
812
722
  end
813
723
 
814
724
  def call(env)
815
- req = request_class.new(env)
725
+ req = make_request(env)
816
726
  req.path_info = Journey::Router::Utils.normalize_path(req.path_info)
817
727
  @router.serve(req)
818
728
  end
@@ -828,7 +738,7 @@ module ActionDispatch
828
738
  raise ActionController::RoutingError, e.message
829
739
  end
830
740
 
831
- req = request_class.new(env)
741
+ req = make_request(env)
832
742
  @router.recognize(req) do |route, params|
833
743
  params.merge!(extras)
834
744
  params.each do |key, value|
@@ -837,18 +747,16 @@ module ActionDispatch
837
747
  params[key] = URI.parser.unescape(value)
838
748
  end
839
749
  end
840
- old_params = req.path_parameters
841
- req.path_parameters = old_params.merge params
750
+ req.path_parameters = params
842
751
  app = route.app
843
752
  if app.matches?(req) && app.dispatcher?
844
- dispatcher = app.app
845
-
846
- if dispatcher.controller(params, false)
847
- dispatcher.prepare_params!(params)
848
- return params
849
- else
753
+ begin
754
+ req.controller_class
755
+ rescue NameError
850
756
  raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller"
851
757
  end
758
+
759
+ return req.path_parameters
852
760
  end
853
761
  end
854
762