actionpack 7.1.3.4 → 7.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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -541
  3. data/lib/abstract_controller/asset_paths.rb +2 -0
  4. data/lib/abstract_controller/base.rb +102 -98
  5. data/lib/abstract_controller/caching/fragments.rb +50 -53
  6. data/lib/abstract_controller/caching.rb +2 -0
  7. data/lib/abstract_controller/callbacks.rb +66 -64
  8. data/lib/abstract_controller/collector.rb +6 -6
  9. data/lib/abstract_controller/deprecator.rb +2 -0
  10. data/lib/abstract_controller/error.rb +2 -0
  11. data/lib/abstract_controller/helpers.rb +70 -85
  12. data/lib/abstract_controller/logger.rb +2 -0
  13. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  14. data/lib/abstract_controller/rendering.rb +13 -12
  15. data/lib/abstract_controller/translation.rb +11 -10
  16. data/lib/abstract_controller/url_for.rb +8 -6
  17. data/lib/abstract_controller.rb +2 -0
  18. data/lib/action_controller/api/api_rendering.rb +2 -0
  19. data/lib/action_controller/api.rb +74 -72
  20. data/lib/action_controller/base.rb +155 -117
  21. data/lib/action_controller/caching.rb +15 -12
  22. data/lib/action_controller/deprecator.rb +2 -0
  23. data/lib/action_controller/form_builder.rb +20 -17
  24. data/lib/action_controller/log_subscriber.rb +3 -1
  25. data/lib/action_controller/metal/allow_browser.rb +119 -0
  26. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  27. data/lib/action_controller/metal/conditional_get.rb +188 -174
  28. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  29. data/lib/action_controller/metal/cookies.rb +4 -2
  30. data/lib/action_controller/metal/data_streaming.rb +64 -55
  31. data/lib/action_controller/metal/default_headers.rb +5 -3
  32. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  34. data/lib/action_controller/metal/exceptions.rb +11 -9
  35. data/lib/action_controller/metal/flash.rb +12 -10
  36. data/lib/action_controller/metal/head.rb +12 -10
  37. data/lib/action_controller/metal/helpers.rb +63 -55
  38. data/lib/action_controller/metal/http_authentication.rb +209 -201
  39. data/lib/action_controller/metal/implicit_render.rb +17 -15
  40. data/lib/action_controller/metal/instrumentation.rb +15 -12
  41. data/lib/action_controller/metal/live.rb +113 -107
  42. data/lib/action_controller/metal/logging.rb +6 -4
  43. data/lib/action_controller/metal/mime_responds.rb +151 -142
  44. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  45. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  46. data/lib/action_controller/metal/permissions_policy.rb +13 -12
  47. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  48. data/lib/action_controller/metal/redirecting.rb +108 -82
  49. data/lib/action_controller/metal/renderers.rb +50 -49
  50. data/lib/action_controller/metal/rendering.rb +103 -75
  51. data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
  52. data/lib/action_controller/metal/rescue.rb +11 -9
  53. data/lib/action_controller/metal/streaming.rb +138 -136
  54. data/lib/action_controller/metal/strong_parameters.rb +525 -480
  55. data/lib/action_controller/metal/testing.rb +2 -0
  56. data/lib/action_controller/metal/url_for.rb +17 -15
  57. data/lib/action_controller/metal.rb +58 -57
  58. data/lib/action_controller/railtie.rb +3 -0
  59. data/lib/action_controller/railties/helpers.rb +2 -0
  60. data/lib/action_controller/renderer.rb +42 -36
  61. data/lib/action_controller/template_assertions.rb +4 -2
  62. data/lib/action_controller/test_case.rb +146 -126
  63. data/lib/action_controller.rb +10 -3
  64. data/lib/action_dispatch/constants.rb +2 -0
  65. data/lib/action_dispatch/deprecator.rb +2 -0
  66. data/lib/action_dispatch/http/cache.rb +27 -26
  67. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  68. data/lib/action_dispatch/http/content_security_policy.rb +44 -38
  69. data/lib/action_dispatch/http/filter_parameters.rb +9 -5
  70. data/lib/action_dispatch/http/filter_redirect.rb +15 -1
  71. data/lib/action_dispatch/http/headers.rb +22 -22
  72. data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
  73. data/lib/action_dispatch/http/mime_type.rb +29 -22
  74. data/lib/action_dispatch/http/mime_types.rb +2 -0
  75. data/lib/action_dispatch/http/parameters.rb +11 -9
  76. data/lib/action_dispatch/http/permissions_policy.rb +27 -37
  77. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  78. data/lib/action_dispatch/http/request.rb +71 -71
  79. data/lib/action_dispatch/http/response.rb +61 -61
  80. data/lib/action_dispatch/http/upload.rb +18 -16
  81. data/lib/action_dispatch/http/url.rb +75 -73
  82. data/lib/action_dispatch/journey/formatter.rb +13 -6
  83. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  84. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  85. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  86. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  87. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  88. data/lib/action_dispatch/journey/parser.rb +4 -3
  89. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  90. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  91. data/lib/action_dispatch/journey/route.rb +9 -7
  92. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  93. data/lib/action_dispatch/journey/router.rb +4 -2
  94. data/lib/action_dispatch/journey/routes.rb +4 -2
  95. data/lib/action_dispatch/journey/scanner.rb +4 -2
  96. data/lib/action_dispatch/journey/visitors.rb +2 -0
  97. data/lib/action_dispatch/journey.rb +2 -0
  98. data/lib/action_dispatch/log_subscriber.rb +2 -0
  99. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  100. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  101. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  102. data/lib/action_dispatch/middleware/cookies.rb +119 -104
  103. data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
  104. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  105. data/lib/action_dispatch/middleware/debug_view.rb +2 -0
  106. data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
  107. data/lib/action_dispatch/middleware/executor.rb +8 -0
  108. data/lib/action_dispatch/middleware/flash.rb +63 -51
  109. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  110. data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
  111. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  112. data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
  113. data/lib/action_dispatch/middleware/request_id.rb +14 -9
  114. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  115. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  116. data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
  117. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  118. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  119. data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
  120. data/lib/action_dispatch/middleware/ssl.rb +43 -40
  121. data/lib/action_dispatch/middleware/stack.rb +11 -10
  122. data/lib/action_dispatch/middleware/static.rb +33 -31
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
  124. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
  125. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  126. data/lib/action_dispatch/railtie.rb +2 -4
  127. data/lib/action_dispatch/request/session.rb +23 -21
  128. data/lib/action_dispatch/request/utils.rb +2 -0
  129. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  130. data/lib/action_dispatch/routing/inspector.rb +5 -3
  131. data/lib/action_dispatch/routing/mapper.rb +670 -635
  132. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  133. data/lib/action_dispatch/routing/redirection.rb +37 -32
  134. data/lib/action_dispatch/routing/route_set.rb +59 -45
  135. data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
  136. data/lib/action_dispatch/routing/url_for.rb +130 -125
  137. data/lib/action_dispatch/routing.rb +150 -148
  138. data/lib/action_dispatch/system_test_case.rb +91 -81
  139. data/lib/action_dispatch/system_testing/browser.rb +10 -3
  140. data/lib/action_dispatch/system_testing/driver.rb +3 -1
  141. data/lib/action_dispatch/system_testing/server.rb +2 -0
  142. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
  143. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  144. data/lib/action_dispatch/testing/assertion_response.rb +8 -6
  145. data/lib/action_dispatch/testing/assertions/response.rb +26 -23
  146. data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
  147. data/lib/action_dispatch/testing/assertions.rb +2 -0
  148. data/lib/action_dispatch/testing/integration.rb +223 -222
  149. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  150. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  151. data/lib/action_dispatch/testing/test_process.rb +12 -8
  152. data/lib/action_dispatch/testing/test_request.rb +3 -1
  153. data/lib/action_dispatch/testing/test_response.rb +27 -26
  154. data/lib/action_dispatch.rb +22 -28
  155. data/lib/action_pack/gem_version.rb +6 -4
  156. data/lib/action_pack/version.rb +3 -1
  157. data/lib/action_pack.rb +17 -16
  158. metadata +30 -13
@@ -1,28 +1,31 @@
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
- # = Action Dispatch Content Security Policy
9
+ # # Action Dispatch Content Security Policy
8
10
  #
9
- # Configures the HTTP
10
- # {Content-Security-Policy}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy]
11
- # response header to help protect against XSS and injection attacks.
11
+ # Configures the HTTP [Content-Security-Policy]
12
+ # (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
13
+ # response header to help protect against XSS and
14
+ # injection attacks.
12
15
  #
13
16
  # Example global policy:
14
17
  #
15
- # Rails.application.config.content_security_policy do |policy|
16
- # policy.default_src :self, :https
17
- # policy.font_src :self, :https, :data
18
- # policy.img_src :self, :https, :data
19
- # policy.object_src :none
20
- # policy.script_src :self, :https
21
- # policy.style_src :self, :https
18
+ # Rails.application.config.content_security_policy do |policy|
19
+ # policy.default_src :self, :https
20
+ # policy.font_src :self, :https, :data
21
+ # policy.img_src :self, :https, :data
22
+ # policy.object_src :none
23
+ # policy.script_src :self, :https
24
+ # policy.style_src :self, :https
22
25
  #
23
- # # Specify URI for violation reports
24
- # policy.report_uri "/csp-violation-report-endpoint"
25
- # end
26
+ # # Specify URI for violation reports
27
+ # policy.report_uri "/csp-violation-report-endpoint"
28
+ # end
26
29
  class ContentSecurityPolicy
27
30
  class Middleware
28
31
  def initialize(app)
@@ -32,8 +35,8 @@ module ActionDispatch # :nodoc:
32
35
  def call(env)
33
36
  status, headers, _ = response = @app.call(env)
34
37
 
35
- # Returning CSP headers with a 304 Not Modified is harmful, since nonces in the new
36
- # CSP headers might not match nonces in the cached HTML.
38
+ # Returning CSP headers with a 304 Not Modified is harmful, since nonces in the
39
+ # new CSP headers might not match nonces in the cached HTML.
37
40
  return response if status == 304
38
41
 
39
42
  return response if policy_present?(headers)
@@ -190,14 +193,14 @@ module ActionDispatch # :nodoc:
190
193
  end
191
194
  end
192
195
 
193
- # Specify whether to prevent the user agent from loading any assets over
194
- # HTTP when the page uses HTTPS:
196
+ # Specify whether to prevent the user agent from loading any assets over HTTP
197
+ # when the page uses HTTPS:
195
198
  #
196
- # policy.block_all_mixed_content
199
+ # policy.block_all_mixed_content
197
200
  #
198
- # Pass +false+ to allow it again:
201
+ # Pass `false` to allow it again:
199
202
  #
200
- # policy.block_all_mixed_content false
203
+ # policy.block_all_mixed_content false
201
204
  #
202
205
  def block_all_mixed_content(enabled = true)
203
206
  if enabled
@@ -209,11 +212,11 @@ module ActionDispatch # :nodoc:
209
212
 
210
213
  # Restricts the set of plugins that can be embedded:
211
214
  #
212
- # policy.plugin_types "application/x-shockwave-flash"
215
+ # policy.plugin_types "application/x-shockwave-flash"
213
216
  #
214
217
  # Leave empty to allow all plugins:
215
218
  #
216
- # policy.plugin_types
219
+ # policy.plugin_types
217
220
  #
218
221
  def plugin_types(*types)
219
222
  if types.first
@@ -223,23 +226,25 @@ module ActionDispatch # :nodoc:
223
226
  end
224
227
  end
225
228
 
226
- # Enable the {report-uri}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri]
227
- # directive. Violation reports will be sent to the specified URI:
229
+ # Enable the [report-uri]
230
+ # (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri)
231
+ # directive. Violation reports will be sent to the
232
+ # specified URI:
228
233
  #
229
- # policy.report_uri "/csp-violation-report-endpoint"
234
+ # policy.report_uri "/csp-violation-report-endpoint"
230
235
  #
231
236
  def report_uri(uri)
232
237
  @directives["report-uri"] = [uri]
233
238
  end
234
239
 
235
- # Specify asset types for which {Subresource Integrity}[https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity]
236
- # is required:
240
+ # Specify asset types for which [Subresource Integrity]
241
+ # (https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) is required:
237
242
  #
238
- # policy.require_sri_for :script, :style
243
+ # policy.require_sri_for :script, :style
239
244
  #
240
245
  # Leave empty to not require Subresource Integrity:
241
246
  #
242
- # policy.require_sri_for
247
+ # policy.require_sri_for
243
248
  #
244
249
  def require_sri_for(*types)
245
250
  if types.first
@@ -249,18 +254,19 @@ module ActionDispatch # :nodoc:
249
254
  end
250
255
  end
251
256
 
252
- # Specify whether a {sandbox}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox]
257
+ # Specify whether a [sandbox]
258
+ # (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox)
253
259
  # should be enabled for the requested resource:
254
260
  #
255
- # policy.sandbox
261
+ # policy.sandbox
256
262
  #
257
263
  # Values can be passed as arguments:
258
264
  #
259
- # policy.sandbox "allow-scripts", "allow-modals"
265
+ # policy.sandbox "allow-scripts", "allow-modals"
260
266
  #
261
- # Pass +false+ to disable the sandbox:
267
+ # Pass `false` to disable the sandbox:
262
268
  #
263
- # policy.sandbox false
269
+ # policy.sandbox false
264
270
  #
265
271
  def sandbox(*values)
266
272
  if values.empty?
@@ -274,11 +280,11 @@ module ActionDispatch # :nodoc:
274
280
 
275
281
  # Specify whether user agents should treat any assets over HTTP as HTTPS:
276
282
  #
277
- # policy.upgrade_insecure_requests
283
+ # policy.upgrade_insecure_requests
278
284
  #
279
- # Pass +false+ to disable it:
285
+ # Pass `false` to disable it:
280
286
  #
281
- # policy.upgrade_insecure_requests false
287
+ # policy.upgrade_insecure_requests false
282
288
  #
283
289
  def upgrade_insecure_requests(enabled = true)
284
290
  if enabled
@@ -1,18 +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
7
- # = Action Dispatch HTTP Filter Parameters
9
+ # # Action Dispatch HTTP Filter Parameters
8
10
  #
9
11
  # Allows you to specify sensitive query string and POST parameters to filter
10
12
  # from the request log.
11
13
  #
12
- # # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
13
- # 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"]
14
16
  #
15
- # For more information about filter behavior, see ActiveSupport::ParameterFilter.
17
+ # For more information about filter behavior, see
18
+ # ActiveSupport::ParameterFilter.
16
19
  module FilterParameters
17
20
  ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc:
18
21
  NULL_PARAM_FILTER = ActiveSupport::ParameterFilter.new # :nodoc:
@@ -43,7 +46,8 @@ module ActionDispatch
43
46
  @filtered_path ||= query_string.empty? ? path : "#{path}?#{filtered_query_string}"
44
47
  end
45
48
 
46
- # Returns the +ActiveSupport::ParameterFilter+ object used to filter in this request.
49
+ # Returns the `ActiveSupport::ParameterFilter` object used to filter in this
50
+ # request.
47
51
  def parameter_filter
48
52
  @parameter_filter ||= if has_header?("action_dispatch.parameter_filter")
49
53
  parameter_filter_for get_header("action_dispatch.parameter_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,18 @@ 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
+ uri.query.gsub!(FilterParameters::PAIR_RE) do
41
+ request.parameter_filter.filter($1 => $2).first.join("=")
42
+ end
43
+ end
44
+ uri.to_s
45
+ rescue URI::Error
46
+ FILTERED
47
+ end
34
48
  end
35
49
  end
36
50
  end
@@ -1,28 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  module Http
5
- # = Action Dispatch HTTP \Headers
7
+ # # Action Dispatch HTTP Headers
6
8
  #
7
9
  # Provides access to the request's HTTP headers from the environment.
8
10
  #
9
- # env = { "CONTENT_TYPE" => "text/plain", "HTTP_USER_AGENT" => "curl/7.43.0" }
10
- # headers = ActionDispatch::Http::Headers.from_hash(env)
11
- # headers["Content-Type"] # => "text/plain"
12
- # 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"
13
15
  #
14
16
  # Also note that when headers are mapped to CGI-like variables by the Rack
15
17
  # server, both dashes and underscores are converted to underscores. This
16
18
  # ambiguity cannot be resolved at this stage anymore. Both underscores and
17
19
  # dashes have to be interpreted as if they were originally sent as dashes.
18
20
  #
19
- # # GET / HTTP/1.1
20
- # # ...
21
- # # User-Agent: curl/7.43.0
22
- # # X_Custom_Header: token
21
+ # # GET / HTTP/1.1
22
+ # # ...
23
+ # # User-Agent: curl/7.43.0
24
+ # # X_Custom_Header: token
23
25
  #
24
- # headers["X_Custom_Header"] # => nil
25
- # headers["X-Custom-Header"] # => "token"
26
+ # headers["X_Custom_Header"] # => nil
27
+ # headers["X-Custom-Header"] # => "token"
26
28
  class Headers
27
29
  CGI_VARIABLES = Set.new(%W[
28
30
  AUTH_TYPE
@@ -67,7 +69,7 @@ module ActionDispatch
67
69
  @req.set_header env_name(key), value
68
70
  end
69
71
 
70
- # 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`.
71
73
  def add(key, value)
72
74
  @req.add_header env_name(key), value
73
75
  end
@@ -81,11 +83,10 @@ module ActionDispatch
81
83
 
82
84
  # Returns the value for the given key mapped to @env.
83
85
  #
84
- # If the key is not found and an optional code block is not provided,
85
- # 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.
86
88
  #
87
- # If the code block is provided, then it will be run and
88
- # its result returned.
89
+ # If the code block is provided, then it will be run and its result returned.
89
90
  def fetch(key, default = DEFAULT)
90
91
  @req.fetch_header(env_name(key)) do
91
92
  return default unless default == DEFAULT
@@ -99,16 +100,15 @@ module ActionDispatch
99
100
  end
100
101
 
101
102
  # Returns a new Http::Headers instance containing the contents of
102
- # <tt>headers_or_env</tt> and the original instance.
103
+ # `headers_or_env` and the original instance.
103
104
  def merge(headers_or_env)
104
105
  headers = @req.dup.headers
105
106
  headers.merge!(headers_or_env)
106
107
  headers
107
108
  end
108
109
 
109
- # Adds the contents of <tt>headers_or_env</tt> to original instance
110
- # entries; duplicate keys are overwritten with the values from
111
- # <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`.
112
112
  def merge!(headers_or_env)
113
113
  headers_or_env.each do |key, value|
114
114
  @req.set_header env_name(key), value
@@ -118,8 +118,8 @@ module ActionDispatch
118
118
  def env; @req.env.dup; end
119
119
 
120
120
  private
121
- # Converts an HTTP header name to an environment variable name if it is
122
- # 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.
123
123
  def env_name(key)
124
124
  key = key.to_s
125
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,23 +18,9 @@ module ActionDispatch
16
18
 
17
19
  included do
18
20
  mattr_accessor :ignore_accept_header, default: false
19
-
20
- def return_only_media_type_on_content_type=(value)
21
- ActionDispatch.deprecator.warn(
22
- "`config.action_dispatch.return_only_request_media_type_on_content_type` is deprecated and will" \
23
- " be removed in Rails 7.2."
24
- )
25
- end
26
-
27
- def return_only_media_type_on_content_type
28
- ActionDispatch.deprecator.warn(
29
- "`config.action_dispatch.return_only_request_media_type_on_content_type` is deprecated and will" \
30
- " be removed in Rails 7.2."
31
- )
32
- end
33
21
  end
34
22
 
35
- # The MIME type of the HTTP request, such as Mime[:xml].
23
+ # The MIME type of the HTTP request, such as [Mime](:xml).
36
24
  def content_mime_type
37
25
  fetch_header("action_dispatch.request.content_type") do |k|
38
26
  v = if get_header("CONTENT_TYPE") =~ /^([^,;]*)/
@@ -66,11 +54,11 @@ 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
63
  def format(_view_path = nil)
76
64
  formats.first || Mime::NullType.instance
@@ -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 fall back
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,8 +157,8 @@ 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
164
  def params_readable?
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "singleton"
4
6
 
5
7
  module Mime
@@ -65,19 +67,20 @@ module Mime
65
67
  end
66
68
  end
67
69
 
68
- # Encapsulates the notion of a MIME type. Can be used at render time, for example, with:
70
+ # Encapsulates the notion of a MIME type. Can be used at render time, for
71
+ # example, with:
69
72
  #
70
- # class PostsController < ActionController::Base
71
- # def show
72
- # @post = Post.find(params[:id])
73
+ # class PostsController < ActionController::Base
74
+ # def show
75
+ # @post = Post.find(params[:id])
73
76
  #
74
- # respond_to do |format|
75
- # format.html
76
- # format.ics { render body: @post.to_ics, mime_type: Mime::Type.lookup("text/calendar") }
77
- # format.xml { render xml: @post }
77
+ # respond_to do |format|
78
+ # format.html
79
+ # format.ics { render body: @post.to_ics, mime_type: Mime::Type.lookup("text/calendar") }
80
+ # format.xml { render xml: @post }
81
+ # end
78
82
  # end
79
83
  # end
80
- # end
81
84
  class Type
82
85
  attr_reader :symbol
83
86
 
@@ -162,16 +165,20 @@ module Mime
162
165
  end
163
166
 
164
167
  def lookup(string)
168
+ return LOOKUP[string] if LOOKUP.key?(string)
169
+
165
170
  # fallback to the media-type without parameters if it was not found
166
- LOOKUP[string] || LOOKUP[string.split(";", 2)[0]&.rstrip] || Type.new(string)
171
+ string = string.split(";", 2)[0]&.rstrip
172
+ LOOKUP[string] || Type.new(string)
167
173
  end
168
174
 
169
175
  def lookup_by_extension(extension)
170
176
  EXTENSION_LOOKUP[extension.to_s]
171
177
  end
172
178
 
173
- # Registers an alias that's not used on MIME type lookup, but can be referenced directly. Especially useful for
174
- # rendering different HTML versions depending on the user agent, like an iPhone.
179
+ # Registers an alias that's not used on MIME type lookup, but can be referenced
180
+ # directly. Especially useful for rendering different HTML versions depending on
181
+ # the user agent, like an iPhone.
175
182
  def register_alias(string, symbol, extension_synonyms = [])
176
183
  register(string, symbol, [], extension_synonyms, true)
177
184
  end
@@ -221,11 +228,11 @@ module Mime
221
228
  parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
222
229
  end
223
230
 
224
- # For an input of <tt>'text'</tt>, returns <tt>[Mime[:json], Mime[:xml], Mime[:ics],
225
- # Mime[:html], Mime[:css], Mime[:csv], Mime[:js], Mime[:yaml], Mime[:text]]</tt>.
231
+ # For an input of `'text'`, returns `[Mime[:json], Mime[:xml], Mime[:ics],
232
+ # Mime[:html], Mime[:css], Mime[:csv], Mime[:js], Mime[:yaml], Mime[:text]]`.
226
233
  #
227
- # For an input of <tt>'application'</tt>, returns <tt>[Mime[:html], Mime[:js],
228
- # Mime[:xml], Mime[:yaml], Mime[:atom], Mime[:json], Mime[:rss], Mime[:url_encoded_form]]</tt>.
234
+ # For an input of `'application'`, returns `[Mime[:html], Mime[:js], Mime[:xml],
235
+ # Mime[:yaml], Mime[:atom], Mime[:json], Mime[:rss], Mime[:url_encoded_form]]`.
229
236
  def parse_data_with_trailing_star(type)
230
237
  Mime::SET.select { |m| m.match?(type) }
231
238
  end
@@ -234,7 +241,7 @@ module Mime
234
241
  #
235
242
  # To unregister a MIME type:
236
243
  #
237
- # Mime::Type.unregister(:mobile)
244
+ # Mime::Type.unregister(:mobile)
238
245
  def unregister(symbol)
239
246
  symbol = symbol.downcase
240
247
  if mime = Mime[symbol]
@@ -326,7 +333,7 @@ module Mime
326
333
  def to_ary; end
327
334
  def to_a; end
328
335
 
329
- def method_missing(method, *args)
336
+ def method_missing(method, ...)
330
337
  if method.end_with?("?")
331
338
  method[0..-2].downcase.to_sym == to_sym
332
339
  else
@@ -350,9 +357,9 @@ module Mime
350
357
  def html?; true; end
351
358
  end
352
359
 
353
- # ALL isn't a real MIME type, so we don't register it for lookup with the
354
- # other concrete types. It's a wildcard match that we use for +respond_to+
355
- # negotiation internals.
360
+ # ALL isn't a real MIME type, so we don't register it for lookup with the other
361
+ # concrete types. It's a wildcard match that we use for `respond_to` negotiation
362
+ # internals.
356
363
  ALL = AllType.instance
357
364
 
358
365
  class NullType
@@ -373,7 +380,7 @@ module Mime
373
380
  method.end_with?("?")
374
381
  end
375
382
 
376
- def method_missing(method, *args)
383
+ def method_missing(method, ...)
377
384
  false if method.end_with?("?")
378
385
  end
379
386
  end
@@ -3,6 +3,8 @@
3
3
  # Build list of Mime types for HTTP responses
4
4
  # https://www.iana.org/assignments/media-types/
5
5
 
6
+ # :markup: markdown
7
+
6
8
  Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml )
7
9
  Mime::Type.register "text/plain", :text, [], %w(txt)
8
10
  Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript )
@@ -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 Parameters
@@ -14,8 +16,8 @@ module ActionDispatch
14
16
  }
15
17
  }
16
18
 
17
- # Raised when raw data from the request cannot be parsed by the parser
18
- # defined for request's content MIME type.
19
+ # Raised when raw data from the request cannot be parsed by the parser defined
20
+ # for request's content MIME type.
19
21
  class ParseError < StandardError
20
22
  def initialize(message = $!.message)
21
23
  super(message)
@@ -34,8 +36,8 @@ module ActionDispatch
34
36
  module ClassMethods
35
37
  # Configure the parameter parser for a given MIME type.
36
38
  #
37
- # It accepts a hash where the key is the symbol of the MIME type
38
- # and the value is a proc.
39
+ # It accepts a hash where the key is the symbol of the MIME type and the value
40
+ # is a proc.
39
41
  #
40
42
  # original_parsers = ActionDispatch::Request.parameter_parsers
41
43
  # xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} }
@@ -46,7 +48,7 @@ module ActionDispatch
46
48
  end
47
49
  end
48
50
 
49
- # Returns both GET and POST \parameters in a single hash.
51
+ # Returns both GET and POST parameters in a single hash.
50
52
  def parameters
51
53
  params = get_header("action_dispatch.request.parameters")
52
54
  return params if params
@@ -66,8 +68,8 @@ module ActionDispatch
66
68
  delete_header("action_dispatch.request.parameters")
67
69
 
68
70
  parameters = Request::Utils.set_binary_encoding(self, parameters, parameters[:controller], parameters[:action])
69
- # If any of the path parameters has an invalid encoding then
70
- # raise since it's likely to trigger errors further on.
71
+ # If any of the path parameters has an invalid encoding then raise since it's
72
+ # likely to trigger errors further on.
71
73
  Request::Utils.check_param_encoding(parameters)
72
74
 
73
75
  set_header PARAMETERS_KEY, parameters
@@ -75,10 +77,10 @@ module ActionDispatch
75
77
  raise ActionController::BadRequest.new("Invalid path parameters: #{e.message}")
76
78
  end
77
79
 
78
- # Returns a hash with the \parameters used to form the \path of the request.
80
+ # Returns a hash with the parameters used to form the path of the request.
79
81
  # Returned hash keys are symbols:
80
82
  #
81
- # { action: "my_action", controller: "my_controller" }
83
+ # { action: "my_action", controller: "my_controller" }
82
84
  def path_parameters
83
85
  get_header(PARAMETERS_KEY) || set_header(PARAMETERS_KEY, {})
84
86
  end