actionpack 7.0.8.7 → 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 +90 -537
  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 +212 -199
  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 +48 -45
  71. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  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 -27
  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 +6 -4
  169. data/lib/action_pack/version.rb +3 -1
  170. data/lib/action_pack.rb +18 -17
  171. metadata +86 -27
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  module Http
5
7
  class ContentDisposition # :nodoc:
@@ -1,49 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/core_ext/object/deep_dup"
4
6
  require "active_support/core_ext/array/wrap"
5
7
 
6
8
  module ActionDispatch # :nodoc:
7
- # Configures the HTTP
8
- # {Content-Security-Policy}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy]
9
- # response header to help protect against XSS and injection attacks.
9
+ # # Action Dispatch Content Security Policy
10
+ #
11
+ # Configures the HTTP [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
12
+ # response header to help protect against XSS and
13
+ # injection attacks.
10
14
  #
11
15
  # Example global policy:
12
16
  #
13
- # Rails.application.config.content_security_policy do |policy|
14
- # policy.default_src :self, :https
15
- # policy.font_src :self, :https, :data
16
- # policy.img_src :self, :https, :data
17
- # policy.object_src :none
18
- # policy.script_src :self, :https
19
- # policy.style_src :self, :https
17
+ # Rails.application.config.content_security_policy do |policy|
18
+ # policy.default_src :self, :https
19
+ # policy.font_src :self, :https, :data
20
+ # policy.img_src :self, :https, :data
21
+ # policy.object_src :none
22
+ # policy.script_src :self, :https
23
+ # policy.style_src :self, :https
20
24
  #
21
- # # Specify URI for violation reports
22
- # policy.report_uri "/csp-violation-report-endpoint"
23
- # end
25
+ # # Specify URI for violation reports
26
+ # policy.report_uri "/csp-violation-report-endpoint"
27
+ # end
24
28
  class ContentSecurityPolicy
25
29
  class InvalidDirectiveError < StandardError
26
30
  end
27
31
 
28
32
  class Middleware
29
- CONTENT_TYPE = "Content-Type"
30
- POLICY = "Content-Security-Policy"
31
- POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only"
32
-
33
33
  def initialize(app)
34
34
  @app = app
35
35
  end
36
36
 
37
37
  def call(env)
38
- request = ActionDispatch::Request.new env
39
38
  status, headers, _ = response = @app.call(env)
40
39
 
41
- # Returning CSP headers with a 304 Not Modified is harmful, since nonces in the new
42
- # CSP headers might not match nonces in the cached HTML.
40
+ # Returning CSP headers with a 304 Not Modified is harmful, since nonces in the
41
+ # new CSP headers might not match nonces in the cached HTML.
43
42
  return response if status == 304
44
43
 
45
44
  return response if policy_present?(headers)
46
45
 
46
+ request = ActionDispatch::Request.new env
47
+
47
48
  if policy = request.content_security_policy
48
49
  nonce = request.content_security_policy_nonce
49
50
  nonce_directives = request.content_security_policy_nonce_directives
@@ -57,14 +58,15 @@ module ActionDispatch # :nodoc:
57
58
  private
58
59
  def header_name(request)
59
60
  if request.content_security_policy_report_only
60
- POLICY_REPORT_ONLY
61
+ ActionDispatch::Constants::CONTENT_SECURITY_POLICY_REPORT_ONLY
61
62
  else
62
- POLICY
63
+ ActionDispatch::Constants::CONTENT_SECURITY_POLICY
63
64
  end
64
65
  end
65
66
 
66
67
  def policy_present?(headers)
67
- headers[POLICY] || headers[POLICY_REPORT_ONLY]
68
+ headers[ActionDispatch::Constants::CONTENT_SECURITY_POLICY] ||
69
+ headers[ActionDispatch::Constants::CONTENT_SECURITY_POLICY_REPORT_ONLY]
68
70
  end
69
71
  end
70
72
 
@@ -126,6 +128,7 @@ module ActionDispatch # :nodoc:
126
128
  MAPPINGS = {
127
129
  self: "'self'",
128
130
  unsafe_eval: "'unsafe-eval'",
131
+ unsafe_hashes: "'unsafe-hashes'",
129
132
  unsafe_inline: "'unsafe-inline'",
130
133
  none: "'none'",
131
134
  http: "http:",
@@ -192,14 +195,14 @@ module ActionDispatch # :nodoc:
192
195
  end
193
196
  end
194
197
 
195
- # Specify whether to prevent the user agent from loading any assets over
196
- # HTTP when the page uses HTTPS:
198
+ # Specify whether to prevent the user agent from loading any assets over HTTP
199
+ # when the page uses HTTPS:
197
200
  #
198
- # policy.block_all_mixed_content
201
+ # policy.block_all_mixed_content
199
202
  #
200
- # Pass +false+ to allow it again:
203
+ # Pass `false` to allow it again:
201
204
  #
202
- # policy.block_all_mixed_content false
205
+ # policy.block_all_mixed_content false
203
206
  #
204
207
  def block_all_mixed_content(enabled = true)
205
208
  if enabled
@@ -211,11 +214,11 @@ module ActionDispatch # :nodoc:
211
214
 
212
215
  # Restricts the set of plugins that can be embedded:
213
216
  #
214
- # policy.plugin_types "application/x-shockwave-flash"
217
+ # policy.plugin_types "application/x-shockwave-flash"
215
218
  #
216
219
  # Leave empty to allow all plugins:
217
220
  #
218
- # policy.plugin_types
221
+ # policy.plugin_types
219
222
  #
220
223
  def plugin_types(*types)
221
224
  if types.first
@@ -225,23 +228,23 @@ module ActionDispatch # :nodoc:
225
228
  end
226
229
  end
227
230
 
228
- # Enable the {report-uri}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri]
229
- # directive. Violation reports will be sent to the specified URI:
231
+ # Enable the [report-uri](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri)
232
+ # directive. Violation reports will be sent to the
233
+ # specified URI:
230
234
  #
231
- # policy.report_uri "/csp-violation-report-endpoint"
235
+ # policy.report_uri "/csp-violation-report-endpoint"
232
236
  #
233
237
  def report_uri(uri)
234
238
  @directives["report-uri"] = [uri]
235
239
  end
236
240
 
237
- # Specify asset types for which {Subresource Integrity}[https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity]
238
- # is required:
241
+ # Specify asset types for which [Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) is required:
239
242
  #
240
- # policy.require_sri_for :script, :style
243
+ # policy.require_sri_for :script, :style
241
244
  #
242
245
  # Leave empty to not require Subresource Integrity:
243
246
  #
244
- # policy.require_sri_for
247
+ # policy.require_sri_for
245
248
  #
246
249
  def require_sri_for(*types)
247
250
  if types.first
@@ -251,18 +254,18 @@ module ActionDispatch # :nodoc:
251
254
  end
252
255
  end
253
256
 
254
- # Specify whether a {sandbox}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox]
257
+ # Specify whether a [sandbox](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox)
255
258
  # should be enabled for the requested resource:
256
259
  #
257
- # policy.sandbox
260
+ # policy.sandbox
258
261
  #
259
262
  # Values can be passed as arguments:
260
263
  #
261
- # policy.sandbox "allow-scripts", "allow-modals"
264
+ # policy.sandbox "allow-scripts", "allow-modals"
262
265
  #
263
- # Pass +false+ to disable the sandbox:
266
+ # Pass `false` to disable the sandbox:
264
267
  #
265
- # policy.sandbox false
268
+ # policy.sandbox false
266
269
  #
267
270
  def sandbox(*values)
268
271
  if values.empty?
@@ -276,11 +279,11 @@ module ActionDispatch # :nodoc:
276
279
 
277
280
  # Specify whether user agents should treat any assets over HTTP as HTTPS:
278
281
  #
279
- # policy.upgrade_insecure_requests
282
+ # policy.upgrade_insecure_requests
280
283
  #
281
- # Pass +false+ to disable it:
284
+ # Pass `false` to disable it:
282
285
  #
283
- # policy.upgrade_insecure_requests false
286
+ # policy.upgrade_insecure_requests false
284
287
  #
285
288
  def upgrade_insecure_requests(enabled = true)
286
289
  if enabled
@@ -1,16 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/parameter_filter"
4
6
 
5
7
  module ActionDispatch
6
8
  module Http
9
+ # # Action Dispatch HTTP Filter Parameters
10
+ #
7
11
  # Allows you to specify sensitive query string and POST parameters to filter
8
12
  # from the request log.
9
13
  #
10
- # # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
11
- # env["action_dispatch.parameter_filter"] = [:foo, "bar"]
14
+ # # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
15
+ # env["action_dispatch.parameter_filter"] = [:foo, "bar"]
12
16
  #
13
- # For more information about filter behavior, see ActiveSupport::ParameterFilter.
17
+ # For more information about filter behavior, see
18
+ # ActiveSupport::ParameterFilter.
14
19
  module FilterParameters
15
20
  ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc:
16
21
  NULL_PARAM_FILTER = ActiveSupport::ParameterFilter.new # :nodoc:
@@ -21,6 +26,7 @@ module ActionDispatch
21
26
  @filtered_parameters = nil
22
27
  @filtered_env = nil
23
28
  @filtered_path = nil
29
+ @parameter_filter = nil
24
30
  end
25
31
 
26
32
  # Returns a hash of parameters with all sensitive data replaced.
@@ -40,13 +46,17 @@ module ActionDispatch
40
46
  @filtered_path ||= query_string.empty? ? path : "#{path}?#{filtered_query_string}"
41
47
  end
42
48
 
43
- private
44
- def parameter_filter # :doc:
45
- parameter_filter_for fetch_header("action_dispatch.parameter_filter") {
46
- return NULL_PARAM_FILTER
47
- }
49
+ # Returns the `ActiveSupport::ParameterFilter` object used to filter in this
50
+ # request.
51
+ def parameter_filter
52
+ @parameter_filter ||= if has_header?("action_dispatch.parameter_filter")
53
+ parameter_filter_for get_header("action_dispatch.parameter_filter")
54
+ else
55
+ NULL_PARAM_FILTER
56
+ end
48
57
  end
49
58
 
59
+ private
50
60
  def env_filter # :doc:
51
61
  user_key = fetch_header("action_dispatch.parameter_filter") {
52
62
  return NULL_ENV_FILTER
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  module Http
5
7
  module FilterRedirect
@@ -9,7 +11,7 @@ module ActionDispatch
9
11
  if location_filter_match?
10
12
  FILTERED
11
13
  else
12
- location
14
+ parameter_filtered_location
13
15
  end
14
16
  end
15
17
 
@@ -31,6 +33,25 @@ module ActionDispatch
31
33
  end
32
34
  end
33
35
  end
36
+
37
+ def parameter_filtered_location
38
+ uri = URI.parse(location)
39
+ unless uri.query.nil? || uri.query.empty?
40
+ parts = uri.query.split(/([&;])/)
41
+ filtered_parts = parts.map do |part|
42
+ if part.include?("=")
43
+ key, value = part.split("=", 2)
44
+ request.parameter_filter.filter(key => value).first.join("=")
45
+ else
46
+ part
47
+ end
48
+ end
49
+ uri.query = filtered_parts.join("")
50
+ end
51
+ uri.to_s
52
+ rescue URI::Error
53
+ FILTERED
54
+ end
34
55
  end
35
56
  end
36
57
  end
@@ -1,26 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  module Http
7
+ # # Action Dispatch HTTP Headers
8
+ #
5
9
  # Provides access to the request's HTTP headers from the environment.
6
10
  #
7
- # env = { "CONTENT_TYPE" => "text/plain", "HTTP_USER_AGENT" => "curl/7.43.0" }
8
- # headers = ActionDispatch::Http::Headers.from_hash(env)
9
- # headers["Content-Type"] # => "text/plain"
10
- # headers["User-Agent"] # => "curl/7.43.0"
11
+ # env = { "CONTENT_TYPE" => "text/plain", "HTTP_USER_AGENT" => "curl/7.43.0" }
12
+ # headers = ActionDispatch::Http::Headers.from_hash(env)
13
+ # headers["Content-Type"] # => "text/plain"
14
+ # headers["User-Agent"] # => "curl/7.43.0"
11
15
  #
12
16
  # Also note that when headers are mapped to CGI-like variables by the Rack
13
17
  # server, both dashes and underscores are converted to underscores. This
14
18
  # ambiguity cannot be resolved at this stage anymore. Both underscores and
15
19
  # dashes have to be interpreted as if they were originally sent as dashes.
16
20
  #
17
- # # GET / HTTP/1.1
18
- # # ...
19
- # # User-Agent: curl/7.43.0
20
- # # X_Custom_Header: token
21
+ # # GET / HTTP/1.1
22
+ # # ...
23
+ # # User-Agent: curl/7.43.0
24
+ # # X_Custom_Header: token
21
25
  #
22
- # headers["X_Custom_Header"] # => nil
23
- # headers["X-Custom-Header"] # => "token"
26
+ # headers["X_Custom_Header"] # => nil
27
+ # headers["X-Custom-Header"] # => "token"
24
28
  class Headers
25
29
  CGI_VARIABLES = Set.new(%W[
26
30
  AUTH_TYPE
@@ -65,7 +69,7 @@ module ActionDispatch
65
69
  @req.set_header env_name(key), value
66
70
  end
67
71
 
68
- # Add a value to a multivalued header like +Vary+ or +Accept-Encoding+.
72
+ # Add a value to a multivalued header like `Vary` or `Accept-Encoding`.
69
73
  def add(key, value)
70
74
  @req.add_header env_name(key), value
71
75
  end
@@ -79,11 +83,10 @@ module ActionDispatch
79
83
 
80
84
  # Returns the value for the given key mapped to @env.
81
85
  #
82
- # If the key is not found and an optional code block is not provided,
83
- # raises a <tt>KeyError</tt> exception.
86
+ # If the key is not found and an optional code block is not provided, raises a
87
+ # `KeyError` exception.
84
88
  #
85
- # If the code block is provided, then it will be run and
86
- # its result returned.
89
+ # If the code block is provided, then it will be run and its result returned.
87
90
  def fetch(key, default = DEFAULT)
88
91
  @req.fetch_header(env_name(key)) do
89
92
  return default unless default == DEFAULT
@@ -97,16 +100,15 @@ module ActionDispatch
97
100
  end
98
101
 
99
102
  # Returns a new Http::Headers instance containing the contents of
100
- # <tt>headers_or_env</tt> and the original instance.
103
+ # `headers_or_env` and the original instance.
101
104
  def merge(headers_or_env)
102
105
  headers = @req.dup.headers
103
106
  headers.merge!(headers_or_env)
104
107
  headers
105
108
  end
106
109
 
107
- # Adds the contents of <tt>headers_or_env</tt> to original instance
108
- # entries; duplicate keys are overwritten with the values from
109
- # <tt>headers_or_env</tt>.
110
+ # Adds the contents of `headers_or_env` to original instance entries; duplicate
111
+ # keys are overwritten with the values from `headers_or_env`.
110
112
  def merge!(headers_or_env)
111
113
  headers_or_env.each do |key, value|
112
114
  @req.set_header env_name(key), value
@@ -116,8 +118,8 @@ module ActionDispatch
116
118
  def env; @req.env.dup; end
117
119
 
118
120
  private
119
- # Converts an HTTP header name to an environment variable name if it is
120
- # not contained within the headers hash.
121
+ # Converts an HTTP header name to an environment variable name if it is not
122
+ # contained within the headers hash.
121
123
  def env_name(key)
122
124
  key = key.to_s
123
125
  if HTTP_HEADER.match?(key)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/core_ext/module/attribute_accessors"
4
6
 
5
7
  module ActionDispatch
@@ -16,10 +18,9 @@ module ActionDispatch
16
18
 
17
19
  included do
18
20
  mattr_accessor :ignore_accept_header, default: false
19
- cattr_accessor :return_only_media_type_on_content_type, default: false
20
21
  end
21
22
 
22
- # The MIME type of the HTTP request, such as Mime[:xml].
23
+ # The MIME type of the HTTP request, such as [Mime](:xml).
23
24
  def content_mime_type
24
25
  fetch_header("action_dispatch.request.content_type") do |k|
25
26
  v = if get_header("CONTENT_TYPE") =~ /^([^,;]*)/
@@ -33,19 +34,6 @@ module ActionDispatch
33
34
  end
34
35
  end
35
36
 
36
- def content_type
37
- if self.class.return_only_media_type_on_content_type
38
- ActiveSupport::Deprecation.warn(
39
- "Rails 7.1 will return Content-Type header without modification." \
40
- " If you want just the MIME type, please use `#media_type` instead."
41
- )
42
-
43
- content_mime_type&.to_s
44
- else
45
- super
46
- end
47
- end
48
-
49
37
  def has_content_type? # :nodoc:
50
38
  get_header "CONTENT_TYPE"
51
39
  end
@@ -66,13 +54,13 @@ module ActionDispatch
66
54
  end
67
55
  end
68
56
 
69
- # Returns the MIME type for the \format used in the request.
57
+ # Returns the MIME type for the format used in the request.
70
58
  #
71
- # GET /posts/5.xml | request.format => Mime[:xml]
72
- # GET /posts/5.xhtml | request.format => Mime[:html]
73
- # GET /posts/5 | request.format => Mime[:html] or Mime[:js], or request.accepts.first
59
+ # GET /posts/5.xml | request.format => Mime[:xml]
60
+ # GET /posts/5.xhtml | request.format => Mime[:html]
61
+ # GET /posts/5 | request.format => Mime[:html] or Mime[:js], or request.accepts.first
74
62
  #
75
- def format(view_path = [])
63
+ def format(_view_path = nil)
76
64
  formats.first || Mime::NullType.instance
77
65
  end
78
66
 
@@ -81,7 +69,7 @@ module ActionDispatch
81
69
  v = if params_readable?
82
70
  Array(Mime[parameters[:format]])
83
71
  elsif use_accept_header && valid_accept_header
84
- accepts
72
+ accepts.dup
85
73
  elsif extension_format = format_from_path_extension
86
74
  [extension_format]
87
75
  elsif xhr?
@@ -90,7 +78,7 @@ module ActionDispatch
90
78
  [Mime[:html]]
91
79
  end
92
80
 
93
- v = v.select do |format|
81
+ v.select! do |format|
94
82
  format.symbol || format.ref == "*/*"
95
83
  end
96
84
 
@@ -98,7 +86,7 @@ module ActionDispatch
98
86
  end
99
87
  end
100
88
 
101
- # Sets the \variant for template.
89
+ # Sets the variant for template.
102
90
  def variant=(variant)
103
91
  variant = Array(variant)
104
92
 
@@ -113,36 +101,37 @@ module ActionDispatch
113
101
  @variant ||= ActiveSupport::ArrayInquirer.new
114
102
  end
115
103
 
116
- # Sets the \format by string extension, which can be used to force custom formats
104
+ # Sets the format by string extension, which can be used to force custom formats
117
105
  # that are not controlled by the extension.
118
106
  #
119
- # class ApplicationController < ActionController::Base
120
- # before_action :adjust_format_for_iphone
107
+ # class ApplicationController < ActionController::Base
108
+ # before_action :adjust_format_for_iphone
121
109
  #
122
- # private
123
- # def adjust_format_for_iphone
124
- # request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/]
125
- # end
126
- # end
110
+ # private
111
+ # def adjust_format_for_iphone
112
+ # request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/]
113
+ # end
114
+ # end
127
115
  def format=(extension)
128
116
  parameters[:format] = extension.to_s
129
117
  set_header "action_dispatch.request.formats", [Mime::Type.lookup_by_extension(parameters[:format])]
130
118
  end
131
119
 
132
- # Sets the \formats by string extensions. This differs from #format= by allowing you
133
- # to set multiple, ordered formats, which is useful when you want to have a fallback.
120
+ # Sets the formats by string extensions. This differs from #format= by allowing
121
+ # you to set multiple, ordered formats, which is useful when you want to have a
122
+ # fallback.
134
123
  #
135
- # In this example, the +:iphone+ format will be used if it's available, otherwise it'll fallback
136
- # to the +:html+ format.
124
+ # In this example, the `:iphone` format will be used if it's available,
125
+ # otherwise it'll fall back to the `:html` format.
137
126
  #
138
- # class ApplicationController < ActionController::Base
139
- # before_action :adjust_format_for_iphone_with_html_fallback
127
+ # class ApplicationController < ActionController::Base
128
+ # before_action :adjust_format_for_iphone_with_html_fallback
140
129
  #
141
- # private
142
- # def adjust_format_for_iphone_with_html_fallback
143
- # request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/]
144
- # end
145
- # end
130
+ # private
131
+ # def adjust_format_for_iphone_with_html_fallback
132
+ # request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/]
133
+ # end
134
+ # end
146
135
  def formats=(extensions)
147
136
  parameters[:format] = extensions.first.to_s
148
137
  set_header "action_dispatch.request.formats", extensions.collect { |extension|
@@ -168,26 +157,26 @@ module ActionDispatch
168
157
  end
169
158
 
170
159
  private
171
- # We use normal content negotiation unless you include */* in your list,
172
- # in which case we assume you're a browser and send HTML.
160
+ # We use normal content negotiation unless you include **/** in your list, in
161
+ # which case we assume you're a browser and send HTML.
173
162
  BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/
174
163
 
175
- def params_readable? # :doc:
164
+ def params_readable?
176
165
  parameters[:format]
177
166
  rescue *RESCUABLE_MIME_FORMAT_ERRORS
178
167
  false
179
168
  end
180
169
 
181
- def valid_accept_header # :doc:
170
+ def valid_accept_header
182
171
  (xhr? && (accept.present? || content_mime_type)) ||
183
172
  (accept.present? && !accept.match?(BROWSER_LIKE_ACCEPTS))
184
173
  end
185
174
 
186
- def use_accept_header # :doc:
175
+ def use_accept_header
187
176
  !self.class.ignore_accept_header
188
177
  end
189
178
 
190
- def format_from_path_extension # :doc:
179
+ def format_from_path_extension
191
180
  path = get_header("action_dispatch.original_path") || get_header("PATH_INFO")
192
181
  if match = path && path.match(/\.(\w+)\z/)
193
182
  Mime[match.captures.first]