actionpack 5.1.7 → 5.2.0.beta1

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 (144) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +132 -490
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller.rb +2 -0
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +10 -2
  7. data/lib/abstract_controller/caching.rb +3 -2
  8. data/lib/abstract_controller/caching/fragments.rb +30 -7
  9. data/lib/abstract_controller/callbacks.rb +25 -3
  10. data/lib/abstract_controller/collector.rb +2 -0
  11. data/lib/abstract_controller/error.rb +2 -0
  12. data/lib/abstract_controller/helpers.rb +4 -5
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  15. data/lib/abstract_controller/rendering.rb +9 -16
  16. data/lib/abstract_controller/translation.rb +2 -0
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/action_controller.rb +3 -0
  19. data/lib/action_controller/api.rb +2 -0
  20. data/lib/action_controller/api/api_rendering.rb +2 -0
  21. data/lib/action_controller/base.rb +3 -0
  22. data/lib/action_controller/caching.rb +2 -0
  23. data/lib/action_controller/form_builder.rb +2 -0
  24. data/lib/action_controller/log_subscriber.rb +5 -3
  25. data/lib/action_controller/metal.rb +3 -2
  26. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  27. data/lib/action_controller/metal/conditional_get.rb +4 -3
  28. data/lib/action_controller/metal/content_security_policy.rb +26 -0
  29. data/lib/action_controller/metal/cookies.rb +2 -0
  30. data/lib/action_controller/metal/data_streaming.rb +7 -5
  31. data/lib/action_controller/metal/etag_with_flash.rb +2 -0
  32. data/lib/action_controller/metal/etag_with_template_digest.rb +3 -2
  33. data/lib/action_controller/metal/exceptions.rb +2 -3
  34. data/lib/action_controller/metal/flash.rb +3 -2
  35. data/lib/action_controller/metal/force_ssl.rb +2 -0
  36. data/lib/action_controller/metal/head.rb +2 -0
  37. data/lib/action_controller/metal/helpers.rb +4 -3
  38. data/lib/action_controller/metal/http_authentication.rb +8 -9
  39. data/lib/action_controller/metal/implicit_render.rb +2 -0
  40. data/lib/action_controller/metal/instrumentation.rb +4 -6
  41. data/lib/action_controller/metal/live.rb +3 -1
  42. data/lib/action_controller/metal/mime_responds.rb +3 -1
  43. data/lib/action_controller/metal/parameter_encoding.rb +2 -0
  44. data/lib/action_controller/metal/params_wrapper.rb +13 -9
  45. data/lib/action_controller/metal/redirecting.rb +21 -10
  46. data/lib/action_controller/metal/renderers.rb +4 -3
  47. data/lib/action_controller/metal/rendering.rb +2 -2
  48. data/lib/action_controller/metal/request_forgery_protection.rb +22 -6
  49. data/lib/action_controller/metal/rescue.rb +5 -3
  50. data/lib/action_controller/metal/streaming.rb +2 -0
  51. data/lib/action_controller/metal/strong_parameters.rb +19 -11
  52. data/lib/action_controller/metal/testing.rb +2 -6
  53. data/lib/action_controller/metal/url_for.rb +2 -0
  54. data/lib/action_controller/railtie.rb +16 -4
  55. data/lib/action_controller/railties/helpers.rb +2 -0
  56. data/lib/action_controller/renderer.rb +2 -0
  57. data/lib/action_controller/template_assertions.rb +2 -0
  58. data/lib/action_controller/test_case.rb +4 -1
  59. data/lib/action_dispatch.rb +3 -0
  60. data/lib/action_dispatch/http/cache.rb +15 -9
  61. data/lib/action_dispatch/http/content_security_policy.rb +233 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +4 -2
  63. data/lib/action_dispatch/http/filter_redirect.rb +2 -0
  64. data/lib/action_dispatch/http/headers.rb +2 -0
  65. data/lib/action_dispatch/http/mime_negotiation.rb +4 -13
  66. data/lib/action_dispatch/http/mime_type.rb +15 -13
  67. data/lib/action_dispatch/http/mime_types.rb +4 -2
  68. data/lib/action_dispatch/http/parameter_filter.rb +2 -0
  69. data/lib/action_dispatch/http/parameters.rb +6 -9
  70. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  71. data/lib/action_dispatch/http/request.rb +36 -16
  72. data/lib/action_dispatch/http/response.rb +11 -9
  73. data/lib/action_dispatch/http/upload.rb +2 -0
  74. data/lib/action_dispatch/http/url.rb +4 -5
  75. data/lib/action_dispatch/journey.rb +2 -0
  76. data/lib/action_dispatch/journey/formatter.rb +4 -2
  77. data/lib/action_dispatch/journey/gtg/builder.rb +2 -0
  78. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -8
  79. data/lib/action_dispatch/journey/gtg/transition_table.rb +3 -2
  80. data/lib/action_dispatch/journey/nfa/builder.rb +2 -0
  81. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  82. data/lib/action_dispatch/journey/nfa/simulator.rb +2 -0
  83. data/lib/action_dispatch/journey/nfa/transition_table.rb +2 -0
  84. data/lib/action_dispatch/journey/nodes/node.rb +2 -0
  85. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  86. data/lib/action_dispatch/journey/path/pattern.rb +2 -0
  87. data/lib/action_dispatch/journey/route.rb +15 -6
  88. data/lib/action_dispatch/journey/router.rb +3 -1
  89. data/lib/action_dispatch/journey/router/utils.rb +14 -7
  90. data/lib/action_dispatch/journey/routes.rb +2 -1
  91. data/lib/action_dispatch/journey/scanner.rb +1 -0
  92. data/lib/action_dispatch/journey/visitors.rb +5 -3
  93. data/lib/action_dispatch/middleware/callbacks.rb +2 -0
  94. data/lib/action_dispatch/middleware/cookies.rb +141 -91
  95. data/lib/action_dispatch/middleware/debug_exceptions.rb +4 -2
  96. data/lib/action_dispatch/middleware/debug_locks.rb +9 -7
  97. data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -6
  98. data/lib/action_dispatch/middleware/executor.rb +2 -0
  99. data/lib/action_dispatch/middleware/flash.rb +3 -1
  100. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -4
  101. data/lib/action_dispatch/middleware/reloader.rb +2 -0
  102. data/lib/action_dispatch/middleware/remote_ip.rb +7 -5
  103. data/lib/action_dispatch/middleware/request_id.rb +2 -0
  104. data/lib/action_dispatch/middleware/session/abstract_store.rb +3 -1
  105. data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
  106. data/lib/action_dispatch/middleware/session/cookie_store.rb +13 -25
  107. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -0
  108. data/lib/action_dispatch/middleware/show_exceptions.rb +3 -1
  109. data/lib/action_dispatch/middleware/ssl.rb +42 -37
  110. data/lib/action_dispatch/middleware/stack.rb +2 -0
  111. data/lib/action_dispatch/middleware/static.rb +10 -8
  112. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
  113. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +6 -2
  114. data/lib/action_dispatch/railtie.rb +7 -0
  115. data/lib/action_dispatch/request/session.rb +8 -4
  116. data/lib/action_dispatch/request/utils.rb +4 -4
  117. data/lib/action_dispatch/routing.rb +3 -1
  118. data/lib/action_dispatch/routing/endpoint.rb +8 -4
  119. data/lib/action_dispatch/routing/inspector.rb +5 -3
  120. data/lib/action_dispatch/routing/mapper.rb +62 -51
  121. data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
  122. data/lib/action_dispatch/routing/redirection.rb +7 -5
  123. data/lib/action_dispatch/routing/route_set.rb +26 -33
  124. data/lib/action_dispatch/routing/routes_proxy.rb +5 -2
  125. data/lib/action_dispatch/routing/url_for.rb +6 -4
  126. data/lib/action_dispatch/system_test_case.rb +14 -6
  127. data/lib/action_dispatch/system_testing/driver.rb +20 -2
  128. data/lib/action_dispatch/system_testing/server.rb +2 -16
  129. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -4
  130. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  131. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  132. data/lib/action_dispatch/testing/assertion_response.rb +2 -0
  133. data/lib/action_dispatch/testing/assertions.rb +2 -0
  134. data/lib/action_dispatch/testing/assertions/response.rb +4 -2
  135. data/lib/action_dispatch/testing/assertions/routing.rb +5 -5
  136. data/lib/action_dispatch/testing/integration.rb +24 -21
  137. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  138. data/lib/action_dispatch/testing/test_process.rb +2 -0
  139. data/lib/action_dispatch/testing/test_request.rb +3 -1
  140. data/lib/action_dispatch/testing/test_response.rb +23 -3
  141. data/lib/action_pack.rb +2 -0
  142. data/lib/action_pack/gem_version.rb +5 -3
  143. data/lib/action_pack/version.rb +2 -0
  144. metadata +17 -13
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  module BasicImplicitRender # :nodoc:
3
5
  def send_action(method, *args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/keys"
2
4
 
3
5
  module ActionController
@@ -7,8 +9,7 @@ module ActionController
7
9
  include Head
8
10
 
9
11
  included do
10
- class_attribute :etaggers
11
- self.etaggers = []
12
+ class_attribute :etaggers, default: []
12
13
  end
13
14
 
14
15
  module ClassMethods
@@ -227,7 +228,7 @@ module ActionController
227
228
  # expires_in 3.hours, public: true, must_revalidate: true
228
229
  #
229
230
  # This method will overwrite an existing Cache-Control header.
230
- # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
231
+ # See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
231
232
  #
232
233
  # The method will also ensure an HTTP Date header for client compatibility.
233
234
  def expires_in(seconds, options = {})
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController #:nodoc:
4
+ module ContentSecurityPolicy
5
+ # TODO: Documentation
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ def content_security_policy(**options, &block)
10
+ before_action(options) do
11
+ if block_given?
12
+ policy = request.content_security_policy.clone
13
+ yield policy
14
+ request.content_security_policy = policy
15
+ end
16
+ end
17
+ end
18
+
19
+ def content_security_policy_report_only(report_only = true, **options)
20
+ before_action(options) do
21
+ request.content_security_policy_report_only = report_only
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController #:nodoc:
2
4
  module Cookies
3
5
  extend ActiveSupport::Concern
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_controller/metal/exceptions"
2
4
 
3
5
  module ActionController #:nodoc:
@@ -54,14 +56,14 @@ module ActionController #:nodoc:
54
56
  #
55
57
  # Read about the other Content-* HTTP headers if you'd like to
56
58
  # provide the user with more information (such as Content-Description) in
57
- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
59
+ # https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
58
60
  #
59
61
  # Also be aware that the document may be cached by proxies and browsers.
60
62
  # The Pragma and Cache-Control headers declare how the file may be cached
61
63
  # by intermediaries. They default to require clients to validate with
62
64
  # the server before releasing cached responses. See
63
- # http://www.mnot.net/cache_docs/ for an overview of web caching and
64
- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
65
+ # https://www.mnot.net/cache_docs/ for an overview of web caching and
66
+ # https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
65
67
  # for the Cache-Control header spec.
66
68
  def send_file(path, options = {}) #:doc:
67
69
  raise MissingFile, "Cannot read file #{path}" unless File.file?(path) && File.readable?(path)
@@ -111,10 +113,10 @@ module ActionController #:nodoc:
111
113
  def send_file_headers!(options)
112
114
  type_provided = options.has_key?(:type)
113
115
 
114
- self.content_type = DEFAULT_SEND_FILE_TYPE
116
+ content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
117
+ self.content_type = content_type
115
118
  response.sending_file = true
116
119
 
117
- content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
118
120
  raise ArgumentError, ":type option required" if content_type.nil?
119
121
 
120
122
  if content_type.is_a?(Symbol)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  # When you're using the flash, it's generally used as a conditional on the view.
3
5
  # This means the content of the view depends on the flash. Which in turn means
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  # When our views change, they should bubble up into HTTP cache freshness
3
5
  # and bust browser caches. So the template digest for the current action
@@ -22,8 +24,7 @@ module ActionController
22
24
  include ActionController::ConditionalGet
23
25
 
24
26
  included do
25
- class_attribute :etag_with_template_digest
26
- self.etag_with_template_digest = true
27
+ class_attribute :etag_with_template_digest, default: true
27
28
 
28
29
  ActiveSupport.on_load :action_view, yield: true do
29
30
  etag do |options|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  class ActionControllerError < StandardError #:nodoc:
3
5
  end
@@ -32,9 +34,6 @@ module ActionController
32
34
  class NotImplemented < MethodNotAllowed #:nodoc:
33
35
  end
34
36
 
35
- class UnknownController < ActionControllerError #:nodoc:
36
- end
37
-
38
37
  class MissingFile < ActionControllerError #:nodoc:
39
38
  end
40
39
 
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController #:nodoc:
2
4
  module Flash
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  included do
6
- class_attribute :_flash_types, instance_accessor: false
7
- self._flash_types = []
8
+ class_attribute :_flash_types, instance_accessor: false, default: []
8
9
 
9
10
  delegate :flash, to: :request
10
11
  add_flash_types(:alert, :notice)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/except"
2
4
  require "active_support/core_ext/hash/slice"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  module Head
3
5
  # Returns a response that has no content (merely headers). The options
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  # The \Rails framework provides a large number of helpers for working with assets, dates, forms,
3
5
  # numbers and model objects, to name a few. These helpers are available to all templates
@@ -53,9 +55,8 @@ module ActionController
53
55
  include AbstractController::Helpers
54
56
 
55
57
  included do
56
- class_attribute :helpers_path, :include_all_helpers
57
- self.helpers_path ||= []
58
- self.include_all_helpers = true
58
+ class_attribute :helpers_path, default: []
59
+ class_attribute :include_all_helpers, default: true
59
60
  end
60
61
 
61
62
  module ClassMethods
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "base64"
2
4
  require "active_support/security_utils"
3
5
 
@@ -70,10 +72,10 @@ module ActionController
70
72
  before_action(options.except(:name, :password, :realm)) do
71
73
  authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
72
74
  # This comparison uses & so that it doesn't short circuit and
73
- # uses `variable_size_secure_compare` so that length information
75
+ # uses `secure_compare` so that length information
74
76
  # isn't leaked.
75
- ActiveSupport::SecurityUtils.variable_size_secure_compare(name, options[:name]) &
76
- ActiveSupport::SecurityUtils.variable_size_secure_compare(password, options[:password])
77
+ ActiveSupport::SecurityUtils.secure_compare(name, options[:name]) &
78
+ ActiveSupport::SecurityUtils.secure_compare(password, options[:password])
77
79
  end
78
80
  end
79
81
  end
@@ -246,7 +248,7 @@ module ActionController
246
248
  def decode_credentials(header)
247
249
  ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/, "").split(",").map do |pair|
248
250
  key, value = pair.split("=", 2)
249
- [key.strip, value.to_s.gsub(/^"|"$/, "").delete('\'')]
251
+ [key.strip, value.to_s.gsub(/^"|"$/, "").delete("'")]
250
252
  end]
251
253
  end
252
254
 
@@ -348,10 +350,7 @@ module ActionController
348
350
  # authenticate_or_request_with_http_token do |token, options|
349
351
  # # Compare the tokens in a time-constant manner, to mitigate
350
352
  # # timing attacks.
351
- # ActiveSupport::SecurityUtils.secure_compare(
352
- # ::Digest::SHA256.hexdigest(token),
353
- # ::Digest::SHA256.hexdigest(TOKEN)
354
- # )
353
+ # ActiveSupport::SecurityUtils.secure_compare(token, TOKEN)
355
354
  # end
356
355
  # end
357
356
  # end
@@ -475,7 +474,7 @@ module ActionController
475
474
 
476
475
  # This removes the <tt>"</tt> characters wrapping the value.
477
476
  def rewrite_param_values(array_params)
478
- array_params.each { |param| (param[1] || "").gsub! %r/^"|"$/, "" }
477
+ array_params.each { |param| (param[1] || "".dup).gsub! %r/^"|"$/, "" }
479
478
  end
480
479
 
481
480
  # This method takes an authorization body and splits up the key-value
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  # Handles implicit rendering for a controller action that does not
3
5
  # explicitly respond with +render+, +respond_to+, +redirect+, or +head+.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "benchmark"
2
4
  require "abstract_controller/logger"
3
5
 
@@ -81,16 +83,13 @@ module ActionController
81
83
  # def cleanup_view_runtime
82
84
  # super - time_taken_in_something_expensive
83
85
  # end
84
- #
85
- # :api: plugin
86
- def cleanup_view_runtime
86
+ def cleanup_view_runtime # :doc:
87
87
  yield
88
88
  end
89
89
 
90
90
  # Every time after an action is processed, this method is invoked
91
91
  # with the payload, so you can add more information.
92
- # :api: plugin
93
- def append_info_to_payload(payload)
92
+ def append_info_to_payload(payload) # :doc:
94
93
  payload[:view_runtime] = view_runtime
95
94
  end
96
95
 
@@ -98,7 +97,6 @@ module ActionController
98
97
  # A hook which allows other frameworks to log what happened during
99
98
  # controller process action. This method should return an array
100
99
  # with the messages to be added.
101
- # :api: plugin
102
100
  def log_process_action(payload) #:nodoc:
103
101
  messages, view_runtime = [], payload[:view_runtime]
104
102
  messages << ("Views: %.1fms" % view_runtime.to_f) if view_runtime
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_dispatch/http/response"
2
4
  require "delegate"
3
5
  require "active_support/json"
@@ -295,7 +297,7 @@ module ActionController
295
297
  return unless logger
296
298
 
297
299
  logger.fatal do
298
- message = "\n#{exception.class} (#{exception.message}):\n"
300
+ message = "\n#{exception.class} (#{exception.message}):\n".dup
299
301
  message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
300
302
  message << " " << exception.backtrace.join("\n ")
301
303
  "#{message}\n\n"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "abstract_controller/collector"
2
4
 
3
5
  module ActionController #:nodoc:
@@ -182,7 +184,7 @@ module ActionController #:nodoc:
182
184
  # request.variant = [:tablet, :phone]
183
185
  #
184
186
  # This will work similarly to formats and MIME types negotiation. If there
185
- # is no +:tablet+ variant declared, +:phone+ variant will be picked:
187
+ # is no +:tablet+ variant declared, the +:phone+ variant will be used:
186
188
  #
187
189
  # respond_to do |format|
188
190
  # format.html.none
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  # Specify binary encoding for parameters for a given action.
3
5
  module ParameterEncoding
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/slice"
2
4
  require "active_support/core_ext/hash/except"
3
5
  require "active_support/core_ext/module/anonymous"
@@ -110,6 +112,14 @@ module ActionController
110
112
  else
111
113
  self.include = m.attribute_names
112
114
  end
115
+
116
+ if m.respond_to?(:nested_attributes_options) && m.nested_attributes_options.keys.any?
117
+ self.include += m.nested_attributes_options.keys.map do |key|
118
+ key.to_s.concat("_attributes")
119
+ end
120
+ end
121
+
122
+ self.include
113
123
  end
114
124
  end
115
125
  end
@@ -159,8 +169,7 @@ module ActionController
159
169
  end
160
170
 
161
171
  included do
162
- class_attribute :_wrapper_options
163
- self._wrapper_options = Options.from_hash(format: [])
172
+ class_attribute :_wrapper_options, default: Options.from_hash(format: [])
164
173
  end
165
174
 
166
175
  module ClassMethods
@@ -233,12 +242,7 @@ module ActionController
233
242
  # by the metal call stack.
234
243
  def process_action(*args)
235
244
  if _wrapper_enabled?
236
- if request.parameters[_wrapper_key].present?
237
- wrapped_hash = _extract_parameters(request.parameters)
238
- else
239
- wrapped_hash = _wrap_parameters request.request_parameters
240
- end
241
-
245
+ wrapped_hash = _wrap_parameters request.request_parameters
242
246
  wrapped_keys = request.request_parameters.keys
243
247
  wrapped_filtered_hash = _wrap_parameters request.filtered_parameters.slice(*wrapped_keys)
244
248
 
@@ -283,7 +287,7 @@ module ActionController
283
287
  return false unless request.has_content_type?
284
288
 
285
289
  ref = request.content_mime_type.ref
286
- _wrapper_formats.include?(ref) && _wrapper_key && !request.request_parameters.key?(_wrapper_key)
290
+ _wrapper_formats.include?(ref) && _wrapper_key && !request.parameters.key?(_wrapper_key)
287
291
  end
288
292
  end
289
293
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  module Redirecting
3
5
  extend ActiveSupport::Concern
@@ -29,7 +31,7 @@ module ActionController
29
31
  # redirect_to post_url(@post), status: 301
30
32
  # redirect_to action: 'atom', status: 302
31
33
  #
32
- # The status code can either be a standard {HTTP Status code}[http://www.iana.org/assignments/http-status-codes] as an
34
+ # The status code can either be a standard {HTTP Status code}[https://www.iana.org/assignments/http-status-codes] as an
33
35
  # integer, or a symbol representing the downcased, underscored and symbolized description.
34
36
  # Note that the status code must be a 3xx HTTP code, or redirection will not occur.
35
37
  #
@@ -66,7 +68,7 @@ module ActionController
66
68
  # if possible, otherwise redirects to the provided default fallback
67
69
  # location.
68
70
  #
69
- # The referrer information is pulled from the HTTP `Referer` (sic) header on
71
+ # The referrer information is pulled from the HTTP +Referer+ (sic) header on
70
72
  # the request. This is an optional header and its presence on the request is
71
73
  # subject to browser security settings and user preferences. If the request
72
74
  # is missing this header, the <tt>fallback_location</tt> will be used.
@@ -77,15 +79,18 @@ module ActionController
77
79
  # redirect_back fallback_location: "/images/screenshot.jpg"
78
80
  # redirect_back fallback_location: posts_url
79
81
  # redirect_back fallback_location: proc { edit_post_url(@post) }
82
+ # redirect_back fallback_location: '/', allow_other_host: false
83
+ #
84
+ # ==== Options
85
+ # * <tt>:fallback_location</tt> - The default fallback location that will be used on missing +Referer+ header.
86
+ # * <tt>:allow_other_host</tt> - Allows or disallow redirection to the host that is different to the current host
80
87
  #
81
- # All options that can be passed to <tt>redirect_to</tt> are accepted as
88
+ # All other options that can be passed to <tt>redirect_to</tt> are accepted as
82
89
  # options and the behavior is identical.
83
- def redirect_back(fallback_location:, **args)
84
- if referer = request.headers["Referer"]
85
- redirect_to referer, **args
86
- else
87
- redirect_to fallback_location, **args
88
- end
90
+ def redirect_back(fallback_location:, allow_other_host: true, **args)
91
+ referer = request.headers["Referer"]
92
+ redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
93
+ redirect_to redirect_to_referer ? referer : fallback_location, **args
89
94
  end
90
95
 
91
96
  def _compute_redirect_to_location(request, options) #:nodoc:
@@ -93,7 +98,7 @@ module ActionController
93
98
  # The scheme name consist of a letter followed by any combination of
94
99
  # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
95
100
  # characters; and is terminated by a colon (":").
96
- # See http://tools.ietf.org/html/rfc3986#section-3.1
101
+ # See https://tools.ietf.org/html/rfc3986#section-3.1
97
102
  # The protocol relative scheme starts with a double slash "//".
98
103
  when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i
99
104
  options
@@ -118,5 +123,11 @@ module ActionController
118
123
  302
119
124
  end
120
125
  end
126
+
127
+ def _url_host_allowed?(url)
128
+ URI(url.to_s).host == request.host
129
+ rescue ArgumentError, URI::Error
130
+ false
131
+ end
121
132
  end
122
133
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
 
3
5
  module ActionController
@@ -26,8 +28,7 @@ module ActionController
26
28
  RENDERERS = Set.new
27
29
 
28
30
  included do
29
- class_attribute :_renderers
30
- self._renderers = Set.new.freeze
31
+ class_attribute :_renderers, default: Set.new.freeze
31
32
  end
32
33
 
33
34
  # Used in <tt>ActionController::Base</tt>
@@ -84,7 +85,7 @@ module ActionController
84
85
  def self.remove(key)
85
86
  RENDERERS.delete(key.to_sym)
86
87
  method_name = _render_with_renderer_method_name(key)
87
- remove_method(method_name) if method_defined?(method_name)
88
+ remove_possible_method(method_name)
88
89
  end
89
90
 
90
91
  def self._render_with_renderer_method_name(key)