actionpack 5.2.8.1 → 6.0.6

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 +270 -347
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/abstract_controller/base.rb +4 -3
  6. data/lib/abstract_controller/caching/fragments.rb +6 -22
  7. data/lib/abstract_controller/caching.rb +1 -1
  8. data/lib/abstract_controller/callbacks.rb +12 -0
  9. data/lib/abstract_controller/collector.rb +1 -2
  10. data/lib/abstract_controller/helpers.rb +7 -6
  11. data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
  12. data/lib/abstract_controller/translation.rb +4 -4
  13. data/lib/action_controller/api.rb +2 -1
  14. data/lib/action_controller/base.rb +2 -7
  15. data/lib/action_controller/caching.rb +1 -2
  16. data/lib/action_controller/log_subscriber.rb +8 -5
  17. data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
  18. data/lib/action_controller/metal/conditional_get.rb +9 -3
  19. data/lib/action_controller/metal/content_security_policy.rb +0 -1
  20. data/lib/action_controller/metal/data_streaming.rb +5 -6
  21. data/lib/action_controller/metal/default_headers.rb +17 -0
  22. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  23. data/lib/action_controller/metal/exceptions.rb +23 -2
  24. data/lib/action_controller/metal/flash.rb +5 -5
  25. data/lib/action_controller/metal/force_ssl.rb +15 -56
  26. data/lib/action_controller/metal/head.rb +1 -1
  27. data/lib/action_controller/metal/helpers.rb +3 -4
  28. data/lib/action_controller/metal/http_authentication.rb +20 -21
  29. data/lib/action_controller/metal/implicit_render.rb +4 -14
  30. data/lib/action_controller/metal/instrumentation.rb +3 -6
  31. data/lib/action_controller/metal/live.rb +29 -31
  32. data/lib/action_controller/metal/mime_responds.rb +13 -2
  33. data/lib/action_controller/metal/params_wrapper.rb +18 -14
  34. data/lib/action_controller/metal/redirecting.rb +5 -5
  35. data/lib/action_controller/metal/renderers.rb +4 -4
  36. data/lib/action_controller/metal/rendering.rb +2 -3
  37. data/lib/action_controller/metal/request_forgery_protection.rb +25 -48
  38. data/lib/action_controller/metal/streaming.rb +0 -1
  39. data/lib/action_controller/metal/strong_parameters.rb +65 -44
  40. data/lib/action_controller/metal/url_for.rb +1 -1
  41. data/lib/action_controller/metal.rb +8 -6
  42. data/lib/action_controller/railties/helpers.rb +1 -1
  43. data/lib/action_controller/renderer.rb +17 -3
  44. data/lib/action_controller/template_assertions.rb +1 -1
  45. data/lib/action_controller/test_case.rb +7 -8
  46. data/lib/action_controller.rb +5 -1
  47. data/lib/action_dispatch/http/cache.rb +14 -11
  48. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  49. data/lib/action_dispatch/http/content_security_policy.rb +28 -17
  50. data/lib/action_dispatch/http/filter_parameters.rb +8 -7
  51. data/lib/action_dispatch/http/filter_redirect.rb +1 -2
  52. data/lib/action_dispatch/http/headers.rb +1 -2
  53. data/lib/action_dispatch/http/mime_negotiation.rb +13 -6
  54. data/lib/action_dispatch/http/mime_type.rb +14 -8
  55. data/lib/action_dispatch/http/parameter_filter.rb +5 -79
  56. data/lib/action_dispatch/http/parameters.rb +15 -6
  57. data/lib/action_dispatch/http/request.rb +21 -14
  58. data/lib/action_dispatch/http/response.rb +40 -21
  59. data/lib/action_dispatch/http/upload.rb +9 -1
  60. data/lib/action_dispatch/http/url.rb +81 -82
  61. data/lib/action_dispatch/journey/formatter.rb +2 -3
  62. data/lib/action_dispatch/journey/gtg/builder.rb +0 -1
  63. data/lib/action_dispatch/journey/gtg/transition_table.rb +0 -1
  64. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -2
  65. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -1
  66. data/lib/action_dispatch/journey/nodes/node.rb +9 -8
  67. data/lib/action_dispatch/journey/path/pattern.rb +6 -3
  68. data/lib/action_dispatch/journey/route.rb +5 -4
  69. data/lib/action_dispatch/journey/router/utils.rb +10 -10
  70. data/lib/action_dispatch/journey/router.rb +0 -4
  71. data/lib/action_dispatch/journey/routes.rb +0 -2
  72. data/lib/action_dispatch/journey/scanner.rb +10 -4
  73. data/lib/action_dispatch/journey/visitors.rb +1 -4
  74. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  75. data/lib/action_dispatch/middleware/callbacks.rb +2 -4
  76. data/lib/action_dispatch/middleware/cookies.rb +62 -78
  77. data/lib/action_dispatch/middleware/debug_exceptions.rb +45 -61
  78. data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
  79. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  80. data/lib/action_dispatch/middleware/exception_wrapper.rb +49 -16
  81. data/lib/action_dispatch/middleware/flash.rb +1 -1
  82. data/lib/action_dispatch/middleware/host_authorization.rb +121 -0
  83. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -3
  84. data/lib/action_dispatch/middleware/remote_ip.rb +9 -12
  85. data/lib/action_dispatch/middleware/request_id.rb +2 -2
  86. data/lib/action_dispatch/middleware/session/abstract_store.rb +0 -1
  87. data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -7
  88. data/lib/action_dispatch/middleware/show_exceptions.rb +1 -2
  89. data/lib/action_dispatch/middleware/ssl.rb +8 -8
  90. data/lib/action_dispatch/middleware/stack.rb +38 -2
  91. data/lib/action_dispatch/middleware/static.rb +6 -7
  92. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +3 -1
  95. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  96. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
  97. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  98. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  99. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  100. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -4
  101. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  102. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +7 -4
  103. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +5 -2
  104. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -0
  105. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  106. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  107. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  108. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  109. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
  110. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +3 -0
  111. data/lib/action_dispatch/railtie.rb +7 -2
  112. data/lib/action_dispatch/request/session.rb +9 -2
  113. data/lib/action_dispatch/routing/inspector.rb +97 -50
  114. data/lib/action_dispatch/routing/mapper.rb +63 -42
  115. data/lib/action_dispatch/routing/polymorphic_routes.rb +3 -6
  116. data/lib/action_dispatch/routing/route_set.rb +25 -31
  117. data/lib/action_dispatch/routing/url_for.rb +2 -2
  118. data/lib/action_dispatch/routing.rb +21 -20
  119. data/lib/action_dispatch/system_test_case.rb +44 -6
  120. data/lib/action_dispatch/system_testing/browser.rb +38 -7
  121. data/lib/action_dispatch/system_testing/driver.rb +11 -2
  122. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -5
  123. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +7 -6
  124. data/lib/action_dispatch/testing/assertion_response.rb +0 -1
  125. data/lib/action_dispatch/testing/assertions/response.rb +2 -3
  126. data/lib/action_dispatch/testing/assertions/routing.rb +15 -3
  127. data/lib/action_dispatch/testing/assertions.rb +1 -1
  128. data/lib/action_dispatch/testing/integration.rb +33 -12
  129. data/lib/action_dispatch/testing/request_encoder.rb +2 -2
  130. data/lib/action_dispatch/testing/test_process.rb +2 -2
  131. data/lib/action_dispatch/testing/test_response.rb +4 -32
  132. data/lib/action_dispatch.rb +7 -2
  133. data/lib/action_pack/gem_version.rb +4 -4
  134. data/lib/action_pack.rb +1 -1
  135. metadata +29 -15
  136. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2018 David Heinemeier Hansson
1
+ Copyright (c) 2004-2019 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -23,6 +23,7 @@ by default and Action View rendering is implicitly triggered by Action
23
23
  Controller. However, these modules are designed to function on their own and
24
24
  can be used outside of Rails.
25
25
 
26
+ You can read more about Action Pack in the {Action Controller Overview}[https://guides.rubyonrails.org/action_controller_overview.html] guide.
26
27
 
27
28
  == Download and installation
28
29
 
@@ -32,7 +33,7 @@ The latest version of Action Pack can be installed with RubyGems:
32
33
 
33
34
  Source code can be downloaded as part of the Rails project on GitHub:
34
35
 
35
- * https://github.com/rails/rails/tree/5-2-stable/actionpack
36
+ * https://github.com/rails/rails/tree/main/actionpack
36
37
 
37
38
 
38
39
  == License
@@ -46,7 +47,7 @@ Action Pack is released under the MIT license:
46
47
 
47
48
  API documentation is at:
48
49
 
49
- * http://api.rubyonrails.org
50
+ * https://api.rubyonrails.org
50
51
 
51
52
  Bug reports for the Ruby on Rails project can be filed here:
52
53
 
@@ -54,4 +55,4 @@ Bug reports for the Ruby on Rails project can be filed here:
54
55
 
55
56
  Feature requests should be discussed on the rails-core mailing list here:
56
57
 
57
- * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
58
+ * https://discuss.rubyonrails.org/c/rubyonrails-core
@@ -78,7 +78,9 @@ module AbstractController
78
78
  # Except for public instance methods of Base and its ancestors
79
79
  internal_methods +
80
80
  # Be sure to include shadowed public instance methods of this class
81
- public_instance_methods(false)).uniq.map(&:to_s)
81
+ public_instance_methods(false))
82
+
83
+ methods.map!(&:to_s)
82
84
 
83
85
  methods.to_set
84
86
  end
@@ -102,7 +104,7 @@ module AbstractController
102
104
  # ==== Returns
103
105
  # * <tt>String</tt>
104
106
  def controller_path
105
- @controller_path ||= name.sub(/Controller$/, "".freeze).underscore unless anonymous?
107
+ @controller_path ||= name.sub(/Controller$/, "").underscore unless anonymous?
106
108
  end
107
109
 
108
110
  # Refresh the cached action_methods when a new action_method is added.
@@ -174,7 +176,6 @@ module AbstractController
174
176
  end
175
177
 
176
178
  private
177
-
178
179
  # Returns true if the name can be considered an action because
179
180
  # it has a method defined in the controller.
180
181
  #
@@ -28,7 +28,6 @@ module AbstractController
28
28
  self.fragment_cache_keys = []
29
29
 
30
30
  if respond_to?(:helper_method)
31
- helper_method :fragment_cache_key
32
31
  helper_method :combined_fragment_cache_key
33
32
  end
34
33
  end
@@ -60,35 +59,20 @@ module AbstractController
60
59
  end
61
60
  end
62
61
 
63
- # Given a key (as described in +expire_fragment+), returns
64
- # a key suitable for use in reading, writing, or expiring a
65
- # cached fragment. All keys begin with <tt>views/</tt>,
66
- # followed by any controller-wide key prefix values, ending
67
- # with the specified +key+ value. The key is expanded using
68
- # ActiveSupport::Cache.expand_cache_key.
69
- def fragment_cache_key(key)
70
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
71
- Calling fragment_cache_key directly is deprecated and will be removed in Rails 6.0.
72
- All fragment accessors now use the combined_fragment_cache_key method that retains the key as an array,
73
- such that the caching stores can interrogate the parts for cache versions used in
74
- recyclable cache keys.
75
- MSG
76
-
77
- head = self.class.fragment_cache_keys.map { |k| instance_exec(&k) }
78
- tail = key.is_a?(Hash) ? url_for(key).split("://").last : key
79
- ActiveSupport::Cache.expand_cache_key([*head, *tail], :views)
80
- end
81
-
82
62
  # Given a key (as described in +expire_fragment+), returns
83
63
  # a key array suitable for use in reading, writing, or expiring a
84
64
  # cached fragment. All keys begin with <tt>:views</tt>,
85
- # followed by ENV["RAILS_CACHE_ID"] or ENV["RAILS_APP_VERSION"] if set,
65
+ # followed by <tt>ENV["RAILS_CACHE_ID"]</tt> or <tt>ENV["RAILS_APP_VERSION"]</tt> if set,
86
66
  # followed by any controller-wide key prefix values, ending
87
67
  # with the specified +key+ value.
88
68
  def combined_fragment_cache_key(key)
89
69
  head = self.class.fragment_cache_keys.map { |k| instance_exec(&k) }
90
70
  tail = key.is_a?(Hash) ? url_for(key).split("://").last : key
91
- [ :views, (ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]), *head, *tail ].compact
71
+
72
+ cache_key = [:views, ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"], head, tail]
73
+ cache_key.flatten!(1)
74
+ cache_key.compact!
75
+ cache_key
92
76
  end
93
77
 
94
78
  # Writes +content+ to the location signified by
@@ -15,7 +15,7 @@ module AbstractController
15
15
  end
16
16
 
17
17
  def cache_store=(store)
18
- config.cache_store = ActiveSupport::Cache.lookup_store(store)
18
+ config.cache_store = ActiveSupport::Cache.lookup_store(*store)
19
19
  end
20
20
 
21
21
  private
@@ -103,6 +103,10 @@ module AbstractController
103
103
  # :call-seq: before_action(names, block)
104
104
  #
105
105
  # Append a callback before actions. See _insert_callbacks for parameter details.
106
+ #
107
+ # If the callback renders or redirects, the action will not run. If there
108
+ # are additional callbacks scheduled to run after that callback, they are
109
+ # also cancelled.
106
110
 
107
111
  ##
108
112
  # :method: prepend_before_action
@@ -110,6 +114,10 @@ module AbstractController
110
114
  # :call-seq: prepend_before_action(names, block)
111
115
  #
112
116
  # Prepend a callback before actions. See _insert_callbacks for parameter details.
117
+ #
118
+ # If the callback renders or redirects, the action will not run. If there
119
+ # are additional callbacks scheduled to run after that callback, they are
120
+ # also cancelled.
113
121
 
114
122
  ##
115
123
  # :method: skip_before_action
@@ -124,6 +132,10 @@ module AbstractController
124
132
  # :call-seq: append_before_action(names, block)
125
133
  #
126
134
  # Append a callback before actions. See _insert_callbacks for parameter details.
135
+ #
136
+ # If the callback renders or redirects, the action will not run. If there
137
+ # are additional callbacks scheduled to run after that callback, they are
138
+ # also cancelled.
127
139
 
128
140
  ##
129
141
  # :method: after_action
@@ -22,11 +22,10 @@ module AbstractController
22
22
  end
23
23
 
24
24
  private
25
-
26
25
  def method_missing(symbol, &block)
27
26
  unless mime_constant = Mime[symbol]
28
27
  raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \
29
- "http://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
28
+ "https://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
30
29
  "If you meant to respond to a variant like :tablet or :phone, not a custom format, " \
31
30
  "be sure to nest your variant response within a format response: " \
32
31
  "format.html { |html| html.tablet { ... } }"
@@ -17,7 +17,7 @@ module AbstractController
17
17
  @path = "helpers/#{path}.rb"
18
18
  set_backtrace error.backtrace
19
19
 
20
- if error.path =~ /^#{path}(\.rb)?$/
20
+ if /^#{path}(\.rb)?$/.match?(error.path)
21
21
  super("Missing helper file helpers/%s.rb" % path)
22
22
  else
23
23
  raise error
@@ -61,11 +61,12 @@ module AbstractController
61
61
  meths.flatten!
62
62
  self._helper_methods += meths
63
63
 
64
- meths.each do |meth|
64
+ meths.each do |method|
65
65
  _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
66
- def #{meth}(*args, &blk) # def current_user(*args, &blk)
67
- controller.send(%(#{meth}), *args, &blk) # controller.send(:current_user, *args, &blk)
68
- end # end
66
+ def #{method}(*args, &blk) # def current_user(*args, &blk)
67
+ controller.send(%(#{method}), *args, &blk) # controller.send(:current_user, *args, &blk)
68
+ end # end
69
+ ruby2_keywords(%(#{method})) if respond_to?(:ruby2_keywords, true)
69
70
  ruby_eval
70
71
  end
71
72
  end
@@ -181,7 +182,7 @@ module AbstractController
181
182
  end
182
183
 
183
184
  def default_helper_module!
184
- module_name = name.sub(/Controller$/, "".freeze)
185
+ module_name = name.sub(/Controller$/, "")
185
186
  module_path = module_name.underscore
186
187
  helper module_path
187
188
  rescue LoadError => e
@@ -7,7 +7,7 @@ module AbstractController
7
7
  Module.new do
8
8
  define_method(:inherited) do |klass|
9
9
  super(klass)
10
- if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
10
+ if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
11
11
  klass.include(namespace.railtie_routes_url_helpers(include_path_helpers))
12
12
  else
13
13
  klass.include(routes.url_helpers(include_path_helpers))
@@ -10,7 +10,7 @@ module AbstractController
10
10
  # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
11
11
  # to translate many keys within the same controller / action and gives you a
12
12
  # simple framework for scoping them consistently.
13
- def translate(key, options = {})
13
+ def translate(key, **options)
14
14
  if key.to_s.first == "."
15
15
  path = controller_path.tr("/", ".")
16
16
  defaults = [:"#{path}#{key}"]
@@ -18,13 +18,13 @@ module AbstractController
18
18
  options[:default] = defaults.flatten
19
19
  key = "#{path}.#{action_name}#{key}"
20
20
  end
21
- I18n.translate(key, options)
21
+ I18n.translate(key, **options)
22
22
  end
23
23
  alias :t :translate
24
24
 
25
25
  # Delegates to <tt>I18n.localize</tt>. Also aliased as <tt>l</tt>.
26
- def localize(*args)
27
- I18n.localize(*args)
26
+ def localize(object, **options)
27
+ I18n.localize(object, **options)
28
28
  end
29
29
  alias :l :localize
30
30
  end
@@ -12,7 +12,7 @@ module ActionController
12
12
  #
13
13
  # An API Controller is different from a normal controller in the sense that
14
14
  # by default it doesn't include a number of features that are usually required
15
- # by browser access only: layouts and templates rendering, cookies, sessions,
15
+ # by browser access only: layouts and templates rendering,
16
16
  # flash, assets, and so on. This makes the entire controller stack thinner,
17
17
  # suitable for API applications. It doesn't mean you won't have such
18
18
  # features if you need them: they're all available for you to include in
@@ -122,6 +122,7 @@ module ActionController
122
122
 
123
123
  ForceSSL,
124
124
  DataStreaming,
125
+ DefaultHeaders,
125
126
 
126
127
  # Before callbacks should also be executed as early as possible, so
127
128
  # also include them at the bottom.
@@ -78,7 +78,7 @@ module ActionController
78
78
  #
79
79
  # You can retrieve it again through the same hash:
80
80
  #
81
- # Hello #{session[:person]}
81
+ # "Hello #{session[:person]}"
82
82
  #
83
83
  # For removing objects from the session, you can either assign a single key to +nil+:
84
84
  #
@@ -232,6 +232,7 @@ module ActionController
232
232
  HttpAuthentication::Basic::ControllerMethods,
233
233
  HttpAuthentication::Digest::ControllerMethods,
234
234
  HttpAuthentication::Token::ControllerMethods,
235
+ DefaultHeaders,
235
236
 
236
237
  # Before callbacks should also be executed as early as possible, so
237
238
  # also include them at the bottom.
@@ -264,12 +265,6 @@ module ActionController
264
265
  PROTECTED_IVARS
265
266
  end
266
267
 
267
- def self.make_response!(request)
268
- ActionDispatch::Response.create.tap do |res|
269
- res.request = request
270
- end
271
- end
272
-
273
268
  ActiveSupport.run_load_hooks(:action_controller_base, self)
274
269
  ActiveSupport.run_load_hooks(:action_controller, self)
275
270
  end
@@ -30,7 +30,6 @@ module ActionController
30
30
  end
31
31
 
32
32
  private
33
-
34
33
  def instrument_payload(key)
35
34
  {
36
35
  controller: controller_name,
@@ -40,7 +39,7 @@ module ActionController
40
39
  end
41
40
 
42
41
  def instrument_name
43
- "action_controller".freeze
42
+ "action_controller"
44
43
  end
45
44
  end
46
45
  end
@@ -18,16 +18,19 @@ module ActionController
18
18
 
19
19
  def process_action(event)
20
20
  info do
21
- payload = event.payload
21
+ payload = event.payload
22
22
  additions = ActionController::Base.log_process_action(payload)
23
-
24
23
  status = payload[:status]
24
+
25
25
  if status.nil? && payload[:exception].present?
26
26
  exception_class_name = payload[:exception].first
27
27
  status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
28
28
  end
29
- message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms".dup
30
- message << " (#{additions.join(" | ".freeze)})" unless additions.empty?
29
+
30
+ additions << "Allocations: #{event.allocations}"
31
+
32
+ message = +"Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
33
+ message << " (#{additions.join(" | ")})" unless additions.empty?
31
34
  message << "\n\n" if defined?(Rails.env) && Rails.env.development?
32
35
 
33
36
  message
@@ -53,7 +56,7 @@ module ActionController
53
56
  def unpermitted_parameters(event)
54
57
  debug do
55
58
  unpermitted_keys = event.payload[:keys]
56
- "Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{unpermitted_keys.map { |e| ":#{e}" }.join(", ")}"
59
+ color("Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{unpermitted_keys.map { |e| ":#{e}" }.join(", ")}", RED)
57
60
  end
58
61
  end
59
62
 
@@ -6,7 +6,7 @@ module ActionController
6
6
  super.tap { default_render unless performed? }
7
7
  end
8
8
 
9
- def default_render(*args)
9
+ def default_render
10
10
  head :no_content
11
11
  end
12
12
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/hash/keys"
4
-
5
3
  module ActionController
6
4
  module ConditionalGet
7
5
  extend ActiveSupport::Concern
@@ -230,12 +228,20 @@ module ActionController
230
228
  # This method will overwrite an existing Cache-Control header.
231
229
  # See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
232
230
  #
231
+ # HTTP Cache-Control Extensions for Stale Content. See https://tools.ietf.org/html/rfc5861
232
+ # It helps to cache an asset and serve it while is being revalidated and/or returning with an error.
233
+ #
234
+ # expires_in 3.hours, public: true, stale_while_revalidate: 60.seconds
235
+ # expires_in 3.hours, public: true, stale_while_revalidate: 60.seconds, stale_if_error: 5.minutes
236
+ #
233
237
  # The method will also ensure an HTTP Date header for client compatibility.
234
238
  def expires_in(seconds, options = {})
235
239
  response.cache_control.merge!(
236
240
  max_age: seconds,
237
241
  public: options.delete(:public),
238
- must_revalidate: options.delete(:must_revalidate)
242
+ must_revalidate: options.delete(:must_revalidate),
243
+ stale_while_revalidate: options.delete(:stale_while_revalidate),
244
+ stale_if_error: options.delete(:stale_if_error),
239
245
  )
240
246
  options.delete(:private)
241
247
 
@@ -36,7 +36,6 @@ module ActionController #:nodoc:
36
36
  end
37
37
 
38
38
  private
39
-
40
39
  def content_security_policy?
41
40
  request.content_security_policy
42
41
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "action_controller/metal/exceptions"
4
+ require "action_dispatch/http/content_disposition"
4
5
 
5
6
  module ActionController #:nodoc:
6
7
  # Methods for sending arbitrary data and for streaming files to the browser,
@@ -10,8 +11,8 @@ module ActionController #:nodoc:
10
11
 
11
12
  include ActionController::Rendering
12
13
 
13
- DEFAULT_SEND_FILE_TYPE = "application/octet-stream".freeze #:nodoc:
14
- DEFAULT_SEND_FILE_DISPOSITION = "attachment".freeze #:nodoc:
14
+ DEFAULT_SEND_FILE_TYPE = "application/octet-stream" #:nodoc:
15
+ DEFAULT_SEND_FILE_DISPOSITION = "attachment" #:nodoc:
15
16
 
16
17
  private
17
18
  # Sends the file. This uses a server-appropriate method (such as X-Sendfile)
@@ -132,10 +133,8 @@ module ActionController #:nodoc:
132
133
  end
133
134
 
134
135
  disposition = options.fetch(:disposition, DEFAULT_SEND_FILE_DISPOSITION)
135
- unless disposition.nil?
136
- disposition = disposition.to_s
137
- disposition += %(; filename="#{options[:filename]}") if options[:filename]
138
- headers["Content-Disposition"] = disposition
136
+ if disposition
137
+ headers["Content-Disposition"] = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: options[:filename])
139
138
  end
140
139
 
141
140
  headers["Content-Transfer-Encoding"] = "binary"
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ # Allows configuring default headers that will be automatically merged into
5
+ # each response.
6
+ module DefaultHeaders
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def make_response!(request)
11
+ ActionDispatch::Response.create.tap do |res|
12
+ res.request = request
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -51,7 +51,7 @@ module ActionController
51
51
  end
52
52
 
53
53
  def lookup_and_digest_template(template)
54
- ActionView::Digestor.digest name: template, finder: lookup_context
54
+ ActionView::Digestor.digest name: template, format: nil, finder: lookup_context
55
55
  end
56
56
  end
57
57
  end
@@ -22,12 +22,12 @@ module ActionController
22
22
  end
23
23
  end
24
24
 
25
- class ActionController::UrlGenerationError < ActionControllerError #:nodoc:
25
+ class UrlGenerationError < ActionControllerError #:nodoc:
26
26
  end
27
27
 
28
28
  class MethodNotAllowed < ActionControllerError #:nodoc:
29
29
  def initialize(*allowed_methods)
30
- super("Only #{allowed_methods.to_sentence(locale: :en)} requests are allowed.")
30
+ super("Only #{allowed_methods.to_sentence} requests are allowed.")
31
31
  end
32
32
  end
33
33
 
@@ -50,4 +50,25 @@ module ActionController
50
50
 
51
51
  class UnknownFormat < ActionControllerError #:nodoc:
52
52
  end
53
+
54
+ # Raised when a nested respond_to is triggered and the content types of each
55
+ # are incompatible. For example:
56
+ #
57
+ # respond_to do |outer_type|
58
+ # outer_type.js do
59
+ # respond_to do |inner_type|
60
+ # inner_type.html { render body: "HTML" }
61
+ # end
62
+ # end
63
+ # end
64
+ class RespondToMismatchError < ActionControllerError
65
+ DEFAULT_MESSAGE = "respond_to was called multiple times and matched with conflicting formats in this action. Please note that you may only call respond_to and match on a single format per action."
66
+
67
+ def initialize(message = nil)
68
+ super(message || DEFAULT_MESSAGE)
69
+ end
70
+ end
71
+
72
+ class MissingExactTemplate < UnknownFormat #:nodoc:
73
+ end
53
74
  end
@@ -36,7 +36,7 @@ module ActionController #:nodoc:
36
36
  define_method(type) do
37
37
  request.flash[type]
38
38
  end
39
- helper_method type
39
+ helper_method(type) if respond_to?(:helper_method)
40
40
 
41
41
  self._flash_types += [type]
42
42
  end
@@ -44,18 +44,18 @@ module ActionController #:nodoc:
44
44
  end
45
45
 
46
46
  private
47
- def redirect_to(options = {}, response_status_and_flash = {}) #:doc:
47
+ def redirect_to(options = {}, response_options_and_flash = {}) #:doc:
48
48
  self.class._flash_types.each do |flash_type|
49
- if type = response_status_and_flash.delete(flash_type)
49
+ if type = response_options_and_flash.delete(flash_type)
50
50
  flash[flash_type] = type
51
51
  end
52
52
  end
53
53
 
54
- if other_flashes = response_status_and_flash.delete(:flash)
54
+ if other_flashes = response_options_and_flash.delete(:flash)
55
55
  flash.update(other_flashes)
56
56
  end
57
57
 
58
- super(options, response_status_and_flash)
58
+ super(options, response_options_and_flash)
59
59
  end
60
60
  end
61
61
  end
@@ -4,18 +4,10 @@ require "active_support/core_ext/hash/except"
4
4
  require "active_support/core_ext/hash/slice"
5
5
 
6
6
  module ActionController
7
- # This module provides a method which will redirect the browser to use the secured HTTPS
8
- # protocol. This will ensure that users' sensitive information will be
9
- # transferred safely over the internet. You _should_ always force the browser
10
- # to use HTTPS when you're transferring sensitive information such as
11
- # user authentication, account information, or credit card information.
12
- #
13
- # Note that if you are really concerned about your application security,
14
- # you might consider using +config.force_ssl+ in your config file instead.
15
- # That will ensure all the data is transferred via HTTPS, and will
16
- # prevent the user from getting their session hijacked when accessing the
17
- # site over unsecured HTTP protocol.
18
- module ForceSSL
7
+ # This module is deprecated in favor of +config.force_ssl+ in your environment
8
+ # config file. This will ensure all endpoints not explicitly marked otherwise
9
+ # will have all communication served over HTTPS.
10
+ module ForceSSL # :nodoc:
19
11
  extend ActiveSupport::Concern
20
12
  include AbstractController::Callbacks
21
13
 
@@ -23,45 +15,17 @@ module ActionController
23
15
  URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
24
16
  REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
25
17
 
26
- module ClassMethods
27
- # Force the request to this particular controller or specified actions to be
28
- # through the HTTPS protocol.
29
- #
30
- # If you need to disable this for any reason (e.g. development) then you can use
31
- # an +:if+ or +:unless+ condition.
32
- #
33
- # class AccountsController < ApplicationController
34
- # force_ssl if: :ssl_configured?
35
- #
36
- # def ssl_configured?
37
- # !Rails.env.development?
38
- # end
39
- # end
40
- #
41
- # ==== URL Options
42
- # You can pass any of the following options to affect the redirect URL
43
- # * <tt>host</tt> - Redirect to a different host name
44
- # * <tt>subdomain</tt> - Redirect to a different subdomain
45
- # * <tt>domain</tt> - Redirect to a different domain
46
- # * <tt>port</tt> - Redirect to a non-standard port
47
- # * <tt>path</tt> - Redirect to a different path
48
- #
49
- # ==== Redirect Options
50
- # You can pass any of the following options to affect the redirect status and response
51
- # * <tt>status</tt> - Redirect with a custom status (default is 301 Moved Permanently)
52
- # * <tt>flash</tt> - Set a flash message when redirecting
53
- # * <tt>alert</tt> - Set an alert message when redirecting
54
- # * <tt>notice</tt> - Set a notice message when redirecting
55
- #
56
- # ==== Action Options
57
- # You can pass any of the following options to affect the before_action callback
58
- # * <tt>only</tt> - The callback should be run only for this action
59
- # * <tt>except</tt> - The callback should be run for all actions except this action
60
- # * <tt>if</tt> - A symbol naming an instance method or a proc; the
61
- # callback will be called only when it returns a true value.
62
- # * <tt>unless</tt> - A symbol naming an instance method or a proc; the
63
- # callback will be called only when it returns a false value.
18
+ module ClassMethods # :nodoc:
64
19
  def force_ssl(options = {})
20
+ ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
21
+ Controller-level `force_ssl` is deprecated and will be removed from
22
+ Rails 6.1. Please enable `config.force_ssl` in your environment
23
+ configuration to enable the ActionDispatch::SSL middleware to more
24
+ fully enforce that your application communicate over HTTPS. If needed,
25
+ you can use `config.ssl_options` to exempt matching endpoints from
26
+ being redirected to HTTPS.
27
+ MESSAGE
28
+
65
29
  action_options = options.slice(*ACTION_OPTIONS)
66
30
  redirect_options = options.except(*ACTION_OPTIONS)
67
31
  before_action(action_options) do
@@ -70,18 +34,13 @@ module ActionController
70
34
  end
71
35
  end
72
36
 
73
- # Redirect the existing request to use the HTTPS protocol.
74
- #
75
- # ==== Parameters
76
- # * <tt>host_or_options</tt> - Either a host name or any of the URL and
77
- # redirect options available to the <tt>force_ssl</tt> method.
78
37
  def force_ssl_redirect(host_or_options = nil)
79
38
  unless request.ssl?
80
39
  options = {
81
40
  protocol: "https://",
82
41
  host: request.host,
83
42
  path: request.fullpath,
84
- status: :moved_permanently
43
+ status: :moved_permanently,
85
44
  }
86
45
 
87
46
  if host_or_options.is_a?(Hash)
@@ -38,7 +38,7 @@ module ActionController
38
38
  self.response_body = ""
39
39
 
40
40
  if include_content?(response_code)
41
- self.content_type = content_type || (Mime[formats.first] if formats)
41
+ self.content_type = content_type || (Mime[formats.first] if formats) || Mime[:html]
42
42
  response.charset = false
43
43
  end
44
44