actionpack 7.0.8.1 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -500
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +119 -106
  7. data/lib/abstract_controller/caching/fragments.rb +51 -52
  8. data/lib/abstract_controller/caching.rb +2 -0
  9. data/lib/abstract_controller/callbacks.rb +94 -67
  10. data/lib/abstract_controller/collector.rb +6 -6
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +2 -0
  13. data/lib/abstract_controller/helpers.rb +121 -91
  14. data/lib/abstract_controller/logger.rb +2 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
  16. data/lib/abstract_controller/rendering.rb +14 -13
  17. data/lib/abstract_controller/translation.rb +12 -30
  18. data/lib/abstract_controller/url_for.rb +9 -5
  19. data/lib/abstract_controller.rb +8 -0
  20. data/lib/action_controller/api/api_rendering.rb +2 -0
  21. data/lib/action_controller/api.rb +78 -73
  22. data/lib/action_controller/base.rb +199 -141
  23. data/lib/action_controller/caching.rb +16 -11
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +21 -16
  26. data/lib/action_controller/log_subscriber.rb +19 -5
  27. data/lib/action_controller/metal/allow_browser.rb +123 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  29. data/lib/action_controller/metal/conditional_get.rb +187 -174
  30. data/lib/action_controller/metal/content_security_policy.rb +26 -25
  31. data/lib/action_controller/metal/cookies.rb +4 -2
  32. data/lib/action_controller/metal/data_streaming.rb +65 -54
  33. data/lib/action_controller/metal/default_headers.rb +6 -2
  34. data/lib/action_controller/metal/etag_with_flash.rb +4 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +18 -14
  36. data/lib/action_controller/metal/exceptions.rb +19 -9
  37. data/lib/action_controller/metal/flash.rb +12 -10
  38. data/lib/action_controller/metal/head.rb +20 -16
  39. data/lib/action_controller/metal/helpers.rb +64 -67
  40. data/lib/action_controller/metal/http_authentication.rb +214 -200
  41. data/lib/action_controller/metal/implicit_render.rb +21 -17
  42. data/lib/action_controller/metal/instrumentation.rb +22 -12
  43. data/lib/action_controller/metal/live.rb +125 -92
  44. data/lib/action_controller/metal/logging.rb +6 -4
  45. data/lib/action_controller/metal/mime_responds.rb +151 -142
  46. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  47. data/lib/action_controller/metal/params_wrapper.rb +58 -58
  48. data/lib/action_controller/metal/permissions_policy.rb +14 -13
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +110 -84
  51. data/lib/action_controller/metal/renderers.rb +50 -49
  52. data/lib/action_controller/metal/rendering.rb +103 -82
  53. data/lib/action_controller/metal/request_forgery_protection.rb +279 -161
  54. data/lib/action_controller/metal/rescue.rb +12 -8
  55. data/lib/action_controller/metal/streaming.rb +174 -132
  56. data/lib/action_controller/metal/strong_parameters.rb +598 -473
  57. data/lib/action_controller/metal/testing.rb +2 -0
  58. data/lib/action_controller/metal/url_for.rb +23 -14
  59. data/lib/action_controller/metal.rb +145 -61
  60. data/lib/action_controller/railtie.rb +25 -9
  61. data/lib/action_controller/railties/helpers.rb +2 -0
  62. data/lib/action_controller/renderer.rb +105 -66
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +157 -128
  65. data/lib/action_controller.rb +17 -3
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +28 -29
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +69 -49
  71. data/lib/action_dispatch/http/filter_parameters.rb +27 -12
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +23 -21
  74. data/lib/action_dispatch/http/mime_negotiation.rb +37 -48
  75. data/lib/action_dispatch/http/mime_type.rb +60 -30
  76. data/lib/action_dispatch/http/mime_types.rb +5 -1
  77. data/lib/action_dispatch/http/parameters.rb +12 -10
  78. data/lib/action_dispatch/http/permissions_policy.rb +32 -34
  79. data/lib/action_dispatch/http/rack_cache.rb +4 -0
  80. data/lib/action_dispatch/http/request.rb +132 -79
  81. data/lib/action_dispatch/http/response.rb +136 -103
  82. data/lib/action_dispatch/http/upload.rb +19 -15
  83. data/lib/action_dispatch/http/url.rb +75 -73
  84. data/lib/action_dispatch/journey/formatter.rb +19 -6
  85. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  88. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  89. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  90. data/lib/action_dispatch/journey/parser.rb +4 -3
  91. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  92. data/lib/action_dispatch/journey/path/pattern.rb +18 -15
  93. data/lib/action_dispatch/journey/route.rb +12 -9
  94. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  95. data/lib/action_dispatch/journey/router.rb +13 -10
  96. data/lib/action_dispatch/journey/routes.rb +6 -4
  97. data/lib/action_dispatch/journey/scanner.rb +4 -2
  98. data/lib/action_dispatch/journey/visitors.rb +2 -0
  99. data/lib/action_dispatch/journey.rb +2 -0
  100. data/lib/action_dispatch/log_subscriber.rb +25 -0
  101. data/lib/action_dispatch/middleware/actionable_exceptions.rb +7 -6
  102. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  103. data/lib/action_dispatch/middleware/callbacks.rb +4 -0
  104. data/lib/action_dispatch/middleware/cookies.rb +192 -194
  105. data/lib/action_dispatch/middleware/debug_exceptions.rb +36 -27
  106. data/lib/action_dispatch/middleware/debug_locks.rb +18 -13
  107. data/lib/action_dispatch/middleware/debug_view.rb +9 -2
  108. data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -27
  109. data/lib/action_dispatch/middleware/executor.rb +9 -1
  110. data/lib/action_dispatch/middleware/flash.rb +65 -46
  111. data/lib/action_dispatch/middleware/host_authorization.rb +22 -17
  112. data/lib/action_dispatch/middleware/public_exceptions.rb +12 -8
  113. data/lib/action_dispatch/middleware/reloader.rb +9 -5
  114. data/lib/action_dispatch/middleware/remote_ip.rb +88 -83
  115. data/lib/action_dispatch/middleware/request_id.rb +15 -8
  116. data/lib/action_dispatch/middleware/server_timing.rb +8 -6
  117. data/lib/action_dispatch/middleware/session/abstract_store.rb +7 -0
  118. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -7
  119. data/lib/action_dispatch/middleware/session/cookie_store.rb +32 -25
  120. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -3
  121. data/lib/action_dispatch/middleware/show_exceptions.rb +42 -28
  122. data/lib/action_dispatch/middleware/ssl.rb +60 -45
  123. data/lib/action_dispatch/middleware/stack.rb +15 -9
  124. data/lib/action_dispatch/middleware/static.rb +40 -34
  125. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
  126. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
  127. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
  129. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
  130. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
  133. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
  134. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  137. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
  138. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +47 -38
  139. data/lib/action_dispatch/railtie.rb +12 -4
  140. data/lib/action_dispatch/request/session.rb +39 -27
  141. data/lib/action_dispatch/request/utils.rb +10 -3
  142. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  143. data/lib/action_dispatch/routing/inspector.rb +59 -9
  144. data/lib/action_dispatch/routing/mapper.rb +686 -639
  145. data/lib/action_dispatch/routing/polymorphic_routes.rb +70 -61
  146. data/lib/action_dispatch/routing/redirection.rb +52 -38
  147. data/lib/action_dispatch/routing/route_set.rb +106 -62
  148. data/lib/action_dispatch/routing/routes_proxy.rb +16 -19
  149. data/lib/action_dispatch/routing/url_for.rb +131 -122
  150. data/lib/action_dispatch/routing.rb +152 -150
  151. data/lib/action_dispatch/system_test_case.rb +91 -81
  152. data/lib/action_dispatch/system_testing/browser.rb +27 -19
  153. data/lib/action_dispatch/system_testing/driver.rb +16 -22
  154. data/lib/action_dispatch/system_testing/server.rb +2 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +53 -31
  156. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  158. data/lib/action_dispatch/testing/assertions/response.rb +36 -26
  159. data/lib/action_dispatch/testing/assertions/routing.rb +203 -95
  160. data/lib/action_dispatch/testing/assertions.rb +5 -1
  161. data/lib/action_dispatch/testing/integration.rb +240 -229
  162. data/lib/action_dispatch/testing/request_encoder.rb +6 -1
  163. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  164. data/lib/action_dispatch/testing/test_process.rb +14 -9
  165. data/lib/action_dispatch/testing/test_request.rb +4 -2
  166. data/lib/action_dispatch/testing/test_response.rb +34 -19
  167. data/lib/action_dispatch.rb +52 -21
  168. data/lib/action_pack/gem_version.rb +5 -3
  169. data/lib/action_pack/version.rb +3 -1
  170. data/lib/action_pack.rb +18 -17
  171. metadata +91 -32
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_dispatch/journey"
4
6
  require "active_support/core_ext/object/to_query"
5
7
  require "active_support/core_ext/module/redefine_method"
@@ -10,12 +12,28 @@ require "action_dispatch/routing/endpoint"
10
12
 
11
13
  module ActionDispatch
12
14
  module Routing
13
- # :stopdoc:
15
+ # The RouteSet contains a collection of Route instances, representing the routes
16
+ # typically defined in `config/routes.rb`.
14
17
  class RouteSet
15
- # Since the router holds references to many parts of the system
16
- # like engines, controllers and the application itself, inspecting
17
- # the route set can actually be really slow, therefore we default
18
- # alias inspect to to_s.
18
+ # Returns a Route matching the given requirements, or `nil` if none are found.
19
+ #
20
+ # This is intended for use by tools such as Language Servers.
21
+ #
22
+ # Given the routes are defined as:
23
+ #
24
+ # resources :posts
25
+ #
26
+ # Then the following will return the Route for the `show` action:
27
+ #
28
+ # Rails.application.routes.from_requirements(controller: "posts", action: "show")
29
+ def from_requirements(requirements)
30
+ routes.find { |route| route.requirements == requirements }
31
+ end
32
+ # :stopdoc:
33
+
34
+ # Since the router holds references to many parts of the system like engines,
35
+ # controllers and the application itself, inspecting the route set can actually
36
+ # be really slow, therefore we default alias inspect to to_s.
19
37
  alias inspect to_s
20
38
 
21
39
  class Dispatcher < Routing::Endpoint
@@ -34,20 +52,20 @@ module ActionDispatch
34
52
  if @raise_on_name_error
35
53
  raise
36
54
  else
37
- [404, { "X-Cascade" => "pass" }, []]
55
+ [404, { Constants::X_CASCADE => "pass" }, []]
38
56
  end
39
57
  end
40
58
 
41
- private
42
- def controller(req)
43
- req.controller_class
44
- rescue NameError => e
45
- raise ActionController::RoutingError, e.message, e.backtrace
46
- end
59
+ private
60
+ def controller(req)
61
+ req.controller_class
62
+ rescue NameError => e
63
+ raise ActionController::RoutingError, e.message, e.backtrace
64
+ end
47
65
 
48
- def dispatch(controller, action, req, res)
49
- controller.dispatch(action, req, res)
50
- end
66
+ def dispatch(controller, action, req, res)
67
+ controller.dispatch(action, req, res)
68
+ end
51
69
  end
52
70
 
53
71
  class StaticDispatcher < Dispatcher
@@ -144,8 +162,8 @@ module ActionDispatch
144
162
  routes.length
145
163
  end
146
164
 
147
- # Given a +name+, defines name_path and name_url helpers.
148
- # Used by 'direct', 'resolve', and 'polymorphic' route helpers.
165
+ # Given a `name`, defines name_path and name_url helpers. Used by 'direct',
166
+ # 'resolve', and 'polymorphic' route helpers.
149
167
  def add_url_helper(name, defaults, &block)
150
168
  helper = CustomUrlHelper.new(name, defaults, &block)
151
169
  path_name = :"#{name}_path"
@@ -282,7 +300,7 @@ module ActionDispatch
282
300
 
283
301
  if args.size < path_params_size
284
302
  path_params -= controller_options.keys
285
- path_params -= result.keys
303
+ path_params -= (result[:path_params] || {}).merge(result).keys
286
304
  else
287
305
  path_params = path_params.dup
288
306
  end
@@ -301,18 +319,18 @@ module ActionDispatch
301
319
  end
302
320
 
303
321
  private
304
- # Create a URL helper allowing ordered parameters to be associated
305
- # with corresponding dynamic segments, so you can do:
322
+ # Create a URL helper allowing ordered parameters to be associated with
323
+ # corresponding dynamic segments, so you can do:
306
324
  #
307
- # foo_url(bar, baz, bang)
325
+ # foo_url(bar, baz, bang)
308
326
  #
309
327
  # Instead of:
310
328
  #
311
- # foo_url(bar: bar, baz: baz, bang: bang)
329
+ # foo_url(bar: bar, baz: baz, bang: bang)
312
330
  #
313
331
  # Also allow options hash, so you can do:
314
332
  #
315
- # foo_url(bar, baz, bang, sort_by: 'baz')
333
+ # foo_url(bar, baz, bang, sort_by: 'baz')
316
334
  #
317
335
  def define_url_helper(mod, name, helper, url_strategy)
318
336
  mod.define_method(name) do |*args|
@@ -375,6 +393,7 @@ module ActionDispatch
375
393
  @disable_clear_and_finalize = false
376
394
  @finalized = false
377
395
  @env_key = "ROUTES_#{object_id}_SCRIPT_NAME"
396
+ @default_env = nil
378
397
 
379
398
  @set = Journey::Routes.new
380
399
  @router = Journey::Router.new @set
@@ -385,6 +404,7 @@ module ActionDispatch
385
404
  def eager_load!
386
405
  router.eager_load!
387
406
  routes.each(&:eager_load!)
407
+ formatter.eager_load!
388
408
  nil
389
409
  end
390
410
 
@@ -405,6 +425,25 @@ module ActionDispatch
405
425
  end
406
426
  private :make_request
407
427
 
428
+ def default_env
429
+ if default_url_options != @default_env&.[]("action_dispatch.routes.default_url_options")
430
+ url_options = default_url_options.dup.freeze
431
+ uri = URI(ActionDispatch::Http::URL.full_url_for(host: "example.org", **url_options))
432
+
433
+ @default_env = {
434
+ "action_dispatch.routes" => self,
435
+ "action_dispatch.routes.default_url_options" => url_options,
436
+ "HTTPS" => uri.scheme == "https" ? "on" : "off",
437
+ "rack.url_scheme" => uri.scheme,
438
+ "HTTP_HOST" => uri.port == uri.default_port ? uri.host : "#{uri.host}:#{uri.port}",
439
+ "SCRIPT_NAME" => uri.path.chomp("/"),
440
+ "rack.input" => "",
441
+ }.freeze
442
+ end
443
+
444
+ @default_env
445
+ end
446
+
408
447
  def draw(&block)
409
448
  clear! unless @disable_clear_and_finalize
410
449
  eval_block(block)
@@ -450,10 +489,9 @@ module ActionDispatch
450
489
  include UrlFor
451
490
  end
452
491
 
453
- # Contains all the mounted helpers across different
454
- # engines and the `main_app` helper for the application.
455
- # You can include this in your classes if you want to
456
- # access routes for other engines.
492
+ # Contains all the mounted helpers across different engines and the `main_app`
493
+ # helper for the application. You can include this in your classes if you want
494
+ # to access routes for other engines.
457
495
  def mounted_helpers
458
496
  MountedHelpers
459
497
  end
@@ -543,13 +581,11 @@ module ActionDispatch
543
581
 
544
582
  url_helpers = routes.named_routes.url_helpers_module
545
583
 
546
- # Make named_routes available in the module singleton
547
- # as well, so one can do:
584
+ # Make named_routes available in the module singleton as well, so one can do:
548
585
  # Rails.application.routes.url_helpers.posts_path
549
586
  extend url_helpers
550
587
 
551
- # Any class that includes this module will get all
552
- # named routes...
588
+ # Any class that includes this module will get all named routes...
553
589
  include url_helpers
554
590
 
555
591
  if supports_path
@@ -564,9 +600,8 @@ module ActionDispatch
564
600
  redefine_singleton_method(:_routes) { routes }
565
601
  end
566
602
 
567
- # And an instance method _routes. Note that
568
- # UrlFor (included in this module) add extra
569
- # conveniences for working with @_routes.
603
+ # And an instance method _routes. Note that UrlFor (included in this module) add
604
+ # extra conveniences for working with @_routes.
570
605
  define_method(:_routes) { @_routes || routes }
571
606
 
572
607
  define_method(:_generate_paths_by_default) do
@@ -574,6 +609,20 @@ module ActionDispatch
574
609
  end
575
610
 
576
611
  private :_generate_paths_by_default
612
+
613
+ # If the module is included more than once (for example, in a subclass of an
614
+ # ancestor that includes the module), ensure that the `_routes` singleton and
615
+ # instance methods return the desired route set by including a new copy of the
616
+ # module (recursively if necessary). Note that this method is called for each
617
+ # inclusion, whereas the above `included` block is run only for the initial
618
+ # inclusion of each copy.
619
+ def self.included(base)
620
+ super
621
+ if base.respond_to?(:_routes) && !base._routes.equal?(@_proxy._routes)
622
+ @dup_for_reinclude ||= self.dup
623
+ base.include @dup_for_reinclude
624
+ end
625
+ end
577
626
  end
578
627
  end
579
628
 
@@ -596,16 +645,16 @@ module ActionDispatch
596
645
  named_routes[name] = route if name
597
646
 
598
647
  if route.segment_keys.include?(:controller)
599
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
648
+ ActionDispatch.deprecator.warn(<<-MSG.squish)
600
649
  Using a dynamic :controller segment in a route is deprecated and
601
- will be removed in Rails 7.1.
650
+ will be removed in Rails 7.2.
602
651
  MSG
603
652
  end
604
653
 
605
654
  if route.segment_keys.include?(:action)
606
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
655
+ ActionDispatch.deprecator.warn(<<-MSG.squish)
607
656
  Using a dynamic :action segment in a route is deprecated and
608
- will be removed in Rails 7.1.
657
+ will be removed in Rails 7.2.
609
658
  MSG
610
659
  end
611
660
 
@@ -682,14 +731,14 @@ module ActionDispatch
682
731
  end
683
732
 
684
733
  def normalize_options!
685
- # If an explicit :controller was given, always make :action explicit
686
- # too, so that action expiry works as expected for things like
734
+ # If an explicit :controller was given, always make :action explicit too, so
735
+ # that action expiry works as expected for things like
687
736
  #
688
- # generate({controller: 'content'}, {controller: 'content', action: 'show'})
737
+ # generate({controller: 'content'}, {controller: 'content', action: 'show'})
689
738
  #
690
- # (the above is from the unit tests). In the above case, because the
691
- # controller was explicitly given, but no action, the action is implied to
692
- # be "index", not the recalled action of "show".
739
+ # (the above is from the unit tests). In the above case, because the controller
740
+ # was explicitly given, but no action, the action is implied to be "index", not
741
+ # the recalled action of "show".
693
742
 
694
743
  if options[:controller]
695
744
  options[:action] ||= "index"
@@ -701,10 +750,9 @@ module ActionDispatch
701
750
  end
702
751
  end
703
752
 
704
- # This pulls :controller, :action, and :id out of the recall.
705
- # The recall key is only used if there is no key in the options
706
- # or if the key in the options is identical. If any of
707
- # :controller, :action or :id is not found, don't pull any
753
+ # This pulls :controller, :action, and :id out of the recall. The recall key is
754
+ # only used if there is no key in the options or if the key in the options is
755
+ # identical. If any of :controller, :action or :id is not found, don't pull any
708
756
  # more keys from the recall.
709
757
  def normalize_controller_action_id!
710
758
  use_recall_for(:controller) || return
@@ -712,8 +760,8 @@ module ActionDispatch
712
760
  use_recall_for(:id)
713
761
  end
714
762
 
715
- # if the current controller is "foo/bar/baz" and controller: "baz/bat"
716
- # is specified, the controller becomes "foo/baz/bat"
763
+ # if the current controller is "foo/bar/baz" and controller: "baz/bat" is
764
+ # specified, the controller becomes "foo/baz/bat"
717
765
  def use_relative_controller!
718
766
  if !named_route && different_controller? && !controller.start_with?("/")
719
767
  old_parts = current_controller.split("/")
@@ -755,8 +803,8 @@ module ActionDispatch
755
803
  end
756
804
  end
757
805
 
758
- # Generate the path indicated by the arguments, and return an array of
759
- # the keys that were not used to generate it.
806
+ # Generate the path indicated by the arguments, and return an array of the keys
807
+ # that were not used to generate it.
760
808
  def extra_keys(options, recall = {})
761
809
  generate_extras(options, recall).last
762
810
  end
@@ -779,25 +827,21 @@ module ActionDispatch
779
827
 
780
828
  RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length,
781
829
  :trailing_slash, :anchor, :params, :only_path, :script_name,
782
- :original_script_name, :relative_url_root]
830
+ :original_script_name]
783
831
 
784
832
  def optimize_routes_generation?
785
833
  default_url_options.empty?
786
834
  end
787
835
 
788
836
  def find_script_name(options)
789
- options.delete(:script_name) || find_relative_url_root(options) || ""
790
- end
791
-
792
- def find_relative_url_root(options)
793
- options.delete(:relative_url_root) || relative_url_root
837
+ options.delete(:script_name) || relative_url_root || ""
794
838
  end
795
839
 
796
840
  def path_for(options, route_name = nil, reserved = RESERVED_OPTIONS)
797
841
  url_for(options, route_name, PATH, nil, reserved)
798
842
  end
799
843
 
800
- # The +options+ argument must be a hash whose keys are *symbols*.
844
+ # The `options` argument must be a hash whose keys are **symbols**.
801
845
  def url_for(options, route_name = nil, url_strategy = UNKNOWN, method_name = nil, reserved = RESERVED_OPTIONS)
802
846
  options = default_url_options.merge options
803
847
 
@@ -830,7 +874,7 @@ module ActionDispatch
830
874
  params = route_with_params.params
831
875
 
832
876
  if options.key? :params
833
- if options[:params]&.respond_to?(:to_hash)
877
+ if options[:params].respond_to?(:to_hash)
834
878
  params.merge! options[:params]
835
879
  else
836
880
  params[:params] = options[:params]
@@ -854,7 +898,7 @@ module ActionDispatch
854
898
 
855
899
  def recognize_path(path, environment = {})
856
900
  method = (environment[:method] || "GET").to_s.upcase
857
- path = Journey::Router::Utils.normalize_path(path) unless %r{://}.match?(path)
901
+ path = Journey::Router::Utils.normalize_path(path) unless path&.include?("://")
858
902
  extras = environment[:extras] || {}
859
903
 
860
904
  begin
@@ -873,7 +917,7 @@ module ActionDispatch
873
917
  params.each do |key, value|
874
918
  if value.is_a?(String)
875
919
  value = value.dup.force_encoding(Encoding::BINARY)
876
- params[key] = URI::DEFAULT_PARSER.unescape(value)
920
+ params[key] = RFC2396_PARSER.unescape(value)
877
921
  end
878
922
  end
879
923
  req.path_parameters = params
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/core_ext/array/extract_options"
4
6
 
5
7
  module ActionDispatch
@@ -29,32 +31,27 @@ module ActionDispatch
29
31
 
30
32
  def method_missing(method, *args)
31
33
  if @helpers.respond_to?(method)
32
- self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
33
- def #{method}(*args)
34
- options = args.extract_options!
35
- options = url_options.merge((options || {}).symbolize_keys)
34
+ options = args.extract_options!
35
+ options = url_options.merge((options || {}).symbolize_keys)
36
36
 
37
- if @script_namer
38
- options[:script_name] = merge_script_names(
39
- options[:script_name],
40
- @script_namer.call(options)
41
- )
42
- end
37
+ if @script_namer
38
+ options[:script_name] = merge_script_names(
39
+ options[:script_name],
40
+ @script_namer.call(options)
41
+ )
42
+ end
43
43
 
44
- args << options
45
- @helpers.#{method}(*args)
46
- end
47
- RUBY
48
- public_send(method, *args)
44
+ args << options
45
+ @helpers.public_send(method, *args)
49
46
  else
50
47
  super
51
48
  end
52
49
  end
53
50
 
54
- # Keeps the part of the script name provided by the global
55
- # context via ENV["SCRIPT_NAME"], which `mount` doesn't know
56
- # about since it depends on the specific request, but use our
57
- # script name resolver for the mount point dependent part.
51
+ # Keeps the part of the script name provided by the global context via
52
+ # [ENV]("SCRIPT_NAME"), which `mount` doesn't know about since it depends on the
53
+ # specific request, but use our script name resolver for the mount point
54
+ # dependent part.
58
55
  def merge_script_names(previous_script_name, new_script_name)
59
56
  return new_script_name unless previous_script_name
60
57