actionpack 7.2.2.1 → 8.1.2

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 (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +408 -95
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller/asset_paths.rb +4 -2
  5. data/lib/abstract_controller/base.rb +12 -17
  6. data/lib/abstract_controller/caching.rb +6 -3
  7. data/lib/abstract_controller/callbacks.rb +6 -0
  8. data/lib/abstract_controller/collector.rb +1 -1
  9. data/lib/abstract_controller/helpers.rb +1 -1
  10. data/lib/abstract_controller/logger.rb +2 -1
  11. data/lib/abstract_controller/rendering.rb +0 -1
  12. data/lib/action_controller/api.rb +1 -0
  13. data/lib/action_controller/base.rb +3 -2
  14. data/lib/action_controller/caching.rb +1 -2
  15. data/lib/action_controller/form_builder.rb +4 -4
  16. data/lib/action_controller/log_subscriber.rb +22 -3
  17. data/lib/action_controller/metal/allow_browser.rb +12 -2
  18. data/lib/action_controller/metal/conditional_get.rb +30 -1
  19. data/lib/action_controller/metal/data_streaming.rb +5 -5
  20. data/lib/action_controller/metal/exceptions.rb +5 -0
  21. data/lib/action_controller/metal/flash.rb +1 -4
  22. data/lib/action_controller/metal/head.rb +3 -1
  23. data/lib/action_controller/metal/instrumentation.rb +1 -2
  24. data/lib/action_controller/metal/live.rb +66 -26
  25. data/lib/action_controller/metal/params_wrapper.rb +3 -3
  26. data/lib/action_controller/metal/permissions_policy.rb +9 -0
  27. data/lib/action_controller/metal/rate_limiting.rb +39 -9
  28. data/lib/action_controller/metal/redirecting.rb +109 -16
  29. data/lib/action_controller/metal/renderers.rb +29 -9
  30. data/lib/action_controller/metal/rendering.rb +8 -2
  31. data/lib/action_controller/metal/request_forgery_protection.rb +21 -11
  32. data/lib/action_controller/metal/rescue.rb +9 -0
  33. data/lib/action_controller/metal/streaming.rb +5 -84
  34. data/lib/action_controller/metal/strong_parameters.rb +277 -92
  35. data/lib/action_controller/railtie.rb +33 -15
  36. data/lib/action_controller/renderer.rb +0 -1
  37. data/lib/action_controller/structured_event_subscriber.rb +116 -0
  38. data/lib/action_controller/test_case.rb +12 -2
  39. data/lib/action_dispatch/constants.rb +6 -0
  40. data/lib/action_dispatch/http/cache.rb +138 -11
  41. data/lib/action_dispatch/http/content_security_policy.rb +14 -1
  42. data/lib/action_dispatch/http/filter_parameters.rb +5 -3
  43. data/lib/action_dispatch/http/mime_negotiation.rb +63 -4
  44. data/lib/action_dispatch/http/mime_types.rb +1 -0
  45. data/lib/action_dispatch/http/param_builder.rb +187 -0
  46. data/lib/action_dispatch/http/param_error.rb +26 -0
  47. data/lib/action_dispatch/http/parameters.rb +3 -3
  48. data/lib/action_dispatch/http/permissions_policy.rb +6 -0
  49. data/lib/action_dispatch/http/query_parser.rb +55 -0
  50. data/lib/action_dispatch/http/request.rb +73 -23
  51. data/lib/action_dispatch/http/response.rb +65 -17
  52. data/lib/action_dispatch/http/url.rb +112 -16
  53. data/lib/action_dispatch/journey/formatter.rb +8 -3
  54. data/lib/action_dispatch/journey/gtg/simulator.rb +33 -12
  55. data/lib/action_dispatch/journey/gtg/transition_table.rb +37 -45
  56. data/lib/action_dispatch/journey/nodes/node.rb +2 -1
  57. data/lib/action_dispatch/journey/parser.rb +99 -196
  58. data/lib/action_dispatch/journey/route.rb +45 -31
  59. data/lib/action_dispatch/journey/router/utils.rb +8 -14
  60. data/lib/action_dispatch/journey/router.rb +59 -81
  61. data/lib/action_dispatch/journey/routes.rb +7 -0
  62. data/lib/action_dispatch/journey/scanner.rb +44 -42
  63. data/lib/action_dispatch/journey/visitors.rb +55 -23
  64. data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
  65. data/lib/action_dispatch/log_subscriber.rb +7 -3
  66. data/lib/action_dispatch/middleware/cookies.rb +8 -4
  67. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -5
  68. data/lib/action_dispatch/middleware/debug_view.rb +11 -5
  69. data/lib/action_dispatch/middleware/exception_wrapper.rb +14 -14
  70. data/lib/action_dispatch/middleware/executor.rb +17 -4
  71. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -6
  72. data/lib/action_dispatch/middleware/remote_ip.rb +11 -5
  73. data/lib/action_dispatch/middleware/request_id.rb +2 -1
  74. data/lib/action_dispatch/middleware/session/cache_store.rb +17 -0
  75. data/lib/action_dispatch/middleware/ssl.rb +13 -3
  76. data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
  77. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -5
  78. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
  79. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
  80. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
  81. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -0
  82. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -0
  83. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
  84. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
  85. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
  86. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
  87. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
  88. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
  89. data/lib/action_dispatch/railtie.rb +21 -0
  90. data/lib/action_dispatch/request/session.rb +1 -0
  91. data/lib/action_dispatch/request/utils.rb +9 -3
  92. data/lib/action_dispatch/routing/inspector.rb +80 -57
  93. data/lib/action_dispatch/routing/mapper.rb +409 -228
  94. data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -2
  95. data/lib/action_dispatch/routing/redirection.rb +10 -7
  96. data/lib/action_dispatch/routing/route_set.rb +21 -12
  97. data/lib/action_dispatch/routing/routes_proxy.rb +1 -0
  98. data/lib/action_dispatch/structured_event_subscriber.rb +20 -0
  99. data/lib/action_dispatch/system_test_case.rb +3 -3
  100. data/lib/action_dispatch/system_testing/browser.rb +12 -21
  101. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +2 -2
  102. data/lib/action_dispatch/testing/assertion_response.rb +1 -1
  103. data/lib/action_dispatch/testing/assertions/response.rb +26 -2
  104. data/lib/action_dispatch/testing/assertions/routing.rb +27 -15
  105. data/lib/action_dispatch/testing/integration.rb +16 -7
  106. data/lib/action_dispatch/testing/request_encoder.rb +9 -9
  107. data/lib/action_dispatch/testing/test_process.rb +1 -2
  108. data/lib/action_dispatch.rb +14 -4
  109. data/lib/action_pack/gem_version.rb +3 -3
  110. metadata +19 -38
  111. data/lib/action_dispatch/journey/parser.y +0 -50
  112. data/lib/action_dispatch/journey/parser_extras.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2f850764c42d33756dafc52b3a241cd1264cf780ef17f52b9b3b0a8b1c3d98e
4
- data.tar.gz: 7febf80d5ab5a57de20b9658daaa10fb21216b30590837e66ceb43cb6cdfe38f
3
+ metadata.gz: b072680373752ca3a9a2b837cac08f7b0f91dd61026dcbad3c8639aff3d3d87e
4
+ data.tar.gz: 5c5835d778ba95993c1ddb1da5321c5f3b81dc1cd2041ef7ab259e041c694463
5
5
  SHA512:
6
- metadata.gz: 6cd119f952b01a8fdf78c1a3c364bf5e681b6b0de52758a1830b935362bc7c0c9950d371bd6b6667e49dc49e8b9f98d0f60b06781a155bcf752be705e19c875f
7
- data.tar.gz: 15339819a72191cd86e77924f9a108ec6c9f7bcc7f3169ba2127bc1ccdefc2a7fdb98609689a7271faf467664df7841f163610445294dbe8eed08c48c431aa01
6
+ metadata.gz: 0b7ba997d7ee51886a1c6e1c49c397b60deb477c5608f54740529c21857142ed45d79a6a4f5aa917095f2005199d2289153223b54d57cb4249b11226d64558ef
7
+ data.tar.gz: d2a9daa41336f39a153b0c2e864edf732533a768a38385795a2a8e86b34e4ff10969be62b83e635d3e517e497726f9346609a7ecb48a39f3aa9d7c02888cad22
data/CHANGELOG.md CHANGED
@@ -1,191 +1,504 @@
1
- ## Rails 7.2.2.1 (December 10, 2024) ##
1
+ ## Rails 8.1.2 (January 08, 2026) ##
2
2
 
3
- * Add validation to content security policies to disallow spaces and semicolons.
4
- Developers should use multiple arguments, and different directive methods instead.
3
+ * Add `config.action_controller.live_streaming_excluded_keys` to control execution state sharing in ActionController::Live.
5
4
 
6
- [CVE-2024-54133]
5
+ When using ActionController::Live, actions are executed in a separate thread that shares
6
+ state from the parent thread. This new configuration allows applications to opt-out specific
7
+ state keys that should not be shared.
7
8
 
8
- *Gannon McGibbon*
9
+ This is useful when streaming inside a `connected_to` block, where you may want
10
+ the streaming thread to use its own database connection context.
9
11
 
12
+ ```ruby
13
+ # config/application.rb
14
+ config.action_controller.live_streaming_excluded_keys = [:active_record_connected_to_stack]
15
+ ```
10
16
 
11
- ## Rails 7.2.2 (October 30, 2024) ##
17
+ By default, all keys are shared.
12
18
 
13
- * Fix non-GET requests not updating cookies in `ActionController::TestCase`.
19
+ *Eileen M. Uchitelle*
14
20
 
15
- *Jon Moss*, *Hartley McGuire*
21
+ * Fix `IpSpoofAttackError` message to include `Forwarded` header content.
16
22
 
23
+ Without it, the error message may be misleading.
17
24
 
18
- ## Rails 7.2.1.2 (October 23, 2024) ##
25
+ *zzak*
19
26
 
20
- * No changes.
21
27
 
28
+ ## Rails 8.1.1 (October 28, 2025) ##
22
29
 
23
- ## Rails 7.2.1.1 (October 15, 2024) ##
30
+ * Allow methods starting with underscore to be action methods.
24
31
 
25
- * Avoid regex backtracking in HTTP Token authentication
32
+ Disallowing methods starting with an underscore from being action methods
33
+ was an unintended side effect of the performance optimization in
34
+ 207a254.
26
35
 
27
- [CVE-2024-47887]
36
+ Fixes #55985.
28
37
 
29
- *John Hawthorn*
38
+ *Rafael Mendonça França*
30
39
 
31
- * Avoid regex backtracking in query parameter filtering
32
40
 
33
- [CVE-2024-41128]
41
+ ## Rails 8.1.0 (October 22, 2025) ##
34
42
 
35
- *John Hawthorn*
43
+ * Submit test requests using `as: :html` with `Content-Type: x-www-form-urlencoded`
36
44
 
45
+ *Sean Doyle*
37
46
 
38
- ## Rails 7.2.1 (August 22, 2024) ##
47
+ * Add link-local IP ranges to `ActionDispatch::RemoteIp` default proxies.
39
48
 
40
- * Fix `Request#raw_post` raising `NoMethodError` when `rack.input` is `nil`.
49
+ Link-local addresses (`169.254.0.0/16` for IPv4 and `fe80::/10` for IPv6)
50
+ are now included in the default trusted proxy list, similar to private IP ranges.
41
51
 
42
- *Hartley McGuire*
52
+ *Adam Daniels*
43
53
 
54
+ * `remote_ip` will no longer ignore IPs in X-Forwarded-For headers if they
55
+ are accompanied by port information.
44
56
 
45
- ## Rails 7.2.0 (August 09, 2024) ##
57
+ *Duncan Brown*, *Prevenios Marinos*, *Masafumi Koba*, *Adam Daniels*
46
58
 
47
- * Allow bots to ignore `allow_browser`.
59
+ * Add `action_dispatch.verbose_redirect_logs` setting that logs where redirects were called from.
48
60
 
49
- *Matthew Nguyen*
61
+ Similar to `active_record.verbose_query_logs` and `active_job.verbose_enqueue_logs`, this adds a line in your logs that shows where a redirect was called from.
50
62
 
51
- * Include the HTTP Permissions-Policy on non-HTML Content-Types
52
- [CVE-2024-28103]
63
+ Example:
53
64
 
54
- *Aaron Patterson*, *Zack Deveau*
65
+ ```
66
+ Redirected to http://localhost:3000/posts/1
67
+ ↳ app/controllers/posts_controller.rb:32:in `block (2 levels) in create'
68
+ ```
55
69
 
56
- * Fix `Mime::Type.parse` handling type parameters for HTTP Accept headers.
70
+ *Dennis Paagman*
57
71
 
58
- *Taylor Chaparro*
72
+ * Add engine route filtering and better formatting in `bin/rails routes`.
59
73
 
60
- * Fix the error page that is displayed when a view template is missing to account for nested controller paths in the
61
- suggested correct location for the missing template.
74
+ Allow engine routes to be filterable in the routing inspector, and
75
+ improve formatting of engine routing output.
62
76
 
63
- *Joshua Young*
77
+ Before:
78
+ ```
79
+ > bin/rails routes -e engine_only
80
+ No routes were found for this grep pattern.
81
+ For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html.
82
+ ```
64
83
 
65
- * Add `save_and_open_page` helper to `IntegrationTest`.
84
+ After:
85
+ ```
86
+ > bin/rails routes -e engine_only
87
+ Routes for application:
88
+ No routes were found for this grep pattern.
89
+ For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html.
90
+
91
+ Routes for Test::Engine:
92
+ Prefix Verb URI Pattern Controller#Action
93
+ engine GET /engine_only(.:format) a#b
94
+ ```
95
+
96
+ *Dennis Paagman*, *Gannon McGibbon*
97
+
98
+ * Add structured events for Action Pack and Action Dispatch:
99
+ - `action_dispatch.redirect`
100
+ - `action_controller.request_started`
101
+ - `action_controller.request_completed`
102
+ - `action_controller.callback_halted`
103
+ - `action_controller.rescue_from_handled`
104
+ - `action_controller.file_sent`
105
+ - `action_controller.redirected`
106
+ - `action_controller.data_sent`
107
+ - `action_controller.unpermitted_parameters`
108
+ - `action_controller.fragment_cache`
109
+
110
+ *Adrianna Chang*
111
+
112
+ * URL helpers for engines mounted at the application root handle `SCRIPT_NAME` correctly.
66
113
 
67
- `save_and_open_page` is a helpful helper to keep a short feedback loop when working on system tests.
68
- A similar helper with matching signature has been added to integration tests.
114
+ Fixed an issue where `SCRIPT_NAME` is not applied to paths generated for routes in an engine
115
+ mounted at "/".
69
116
 
70
- *Joé Dupuis*
117
+ *Mike Dalessio*
71
118
 
72
- * Fix a regression in 7.1.3 passing a `to:` option without a controller when the controller is already defined by a scope.
119
+ * Update `ActionController::Metal::RateLimiting` to support passing method names to `:by` and `:with`
73
120
 
74
121
  ```ruby
75
- Rails.application.routes.draw do
76
- controller :home do
77
- get "recent", to: "recent_posts"
78
- end
122
+ class SignupsController < ApplicationController
123
+ rate_limit to: 10, within: 1.minute, with: :redirect_with_flash
124
+
125
+ private
126
+ def redirect_with_flash
127
+ redirect_to root_url, alert: "Too many requests!"
128
+ end
79
129
  end
80
130
  ```
81
131
 
82
- *Étienne Barrié*
132
+ *Sean Doyle*
133
+
134
+ * Optimize `ActionDispatch::Http::URL.build_host_url` when protocol is included in host.
135
+
136
+ When using URL helpers with a host that includes the protocol (e.g., `{ host: "https://example.com" }`),
137
+ skip unnecessary protocol normalization and string duplication since the extracted protocol is already
138
+ in the correct format. This eliminates 2 string allocations per URL generation and provides a ~10%
139
+ performance improvement for this case.
140
+
141
+ *Joshua Young*, *Hartley McGuire*
142
+
143
+ * Allow `action_controller.logger` to be disabled by setting it to `nil` or `false` instead of always defaulting to `Rails.logger`.
144
+
145
+ *Roberto Miranda*
146
+
147
+ * Remove deprecated support to a route to multiple paths.
148
+
149
+ *Rafael Mendonça França*
150
+
151
+ * Remove deprecated support for using semicolons as a query string separator.
152
+
153
+ Before:
154
+
155
+ ```ruby
156
+ ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
157
+ # => [["foo", "bar"], ["baz", "quux"]]
158
+ ```
159
+
160
+ After:
83
161
 
84
- * Request Forgery takes relative paths into account.
162
+ ```ruby
163
+ ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
164
+ # => [["foo", "bar;baz=quux"]]
165
+ ```
85
166
 
86
- *Stefan Wienert*
167
+ *Rafael Mendonça França*
168
+
169
+ * Remove deprecated support to skipping over leading brackets in parameter names in the parameter parser.
87
170
 
88
- * Add ".test" as a default allowed host in development to ensure smooth golden-path setup with puma.dev.
171
+ Before:
172
+
173
+ ```ruby
174
+ ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "foo" => "bar" }
175
+ ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "foo" => { "bar" => "baz" } }
176
+ ```
177
+
178
+ After:
179
+
180
+ ```ruby
181
+ ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "[foo]" => "bar" }
182
+ ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "[foo]" => { "bar" => "baz" } }
183
+ ```
184
+
185
+ *Rafael Mendonça França*
186
+
187
+ * Deprecate `Rails.application.config.action_dispatch.ignore_leading_brackets`.
188
+
189
+ *Rafael Mendonça França*
190
+
191
+ * Raise `ActionController::TooManyRequests` error from `ActionController::RateLimiting`
192
+
193
+ Requests that exceed the rate limit raise an `ActionController::TooManyRequests` error.
194
+ By default, Action Dispatch rescues the error and responds with a `429 Too Many Requests` status.
195
+
196
+ *Sean Doyle*
197
+
198
+ * Add .md/.markdown as Markdown extensions and add a default `markdown:` renderer:
199
+
200
+ ```ruby
201
+ class Page
202
+ def to_markdown
203
+ body
204
+ end
205
+ end
206
+
207
+ class PagesController < ActionController::Base
208
+ def show
209
+ @page = Page.find(params[:id])
210
+
211
+ respond_to do |format|
212
+ format.html
213
+ format.md { render markdown: @page }
214
+ end
215
+ end
216
+ end
217
+ ```
89
218
 
90
219
  *DHH*
91
220
 
92
- * Add `allow_browser` to set minimum browser versions for the application.
221
+ * Add headers to engine routes inspection command
222
+
223
+ *Petrik de Heus*
224
+
225
+ * Add "Copy as text" button to error pages
226
+
227
+ *Mikkel Malmberg*
228
+
229
+ * Add `scope:` option to `rate_limit` method.
230
+
231
+ Previously, it was not possible to share a rate limit count between several controllers, since the count was by
232
+ default separate for each controller.
93
233
 
94
- A browser that's blocked will by default be served the file in `public/406-unsupported-browser.html` with a HTTP status code of "406 Not Acceptable".
234
+ Now, the `scope:` option solves this problem.
95
235
 
96
236
  ```ruby
97
- class ApplicationController < ActionController::Base
98
- # Allow only browsers natively supporting webp images, web push, badges, import maps, CSS nesting + :has
99
- allow_browser versions: :modern
237
+ class APIController < ActionController::API
238
+ rate_limit to: 2, within: 2.seconds, scope: "api"
100
239
  end
101
240
 
102
- class ApplicationController < ActionController::Base
103
- # All versions of Chrome and Opera will be allowed, but no versions of "internet explorer" (ie). Safari needs to be 16.4+ and Firefox 121+.
104
- allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
241
+ class API::PostsController < APIController
242
+ # ...
105
243
  end
106
244
 
107
- class MessagesController < ApplicationController
108
- # In addition to the browsers blocked by ApplicationController, also block Opera below 104 and Chrome below 119 for the show action.
109
- allow_browser versions: { opera: 104, chrome: 119 }, only: :show
245
+ class API::UsersController < APIController
246
+ # ...
110
247
  end
111
248
  ```
112
249
 
113
- *DHH*
250
+ *ArthurPV*, *Kamil Hanus*
251
+
252
+ * Add support for `rack.response_finished` callbacks in ActionDispatch::Executor.
253
+
254
+ The executor middleware now supports deferring completion callbacks to later
255
+ in the request lifecycle by utilizing Rack's `rack.response_finished` mechanism,
256
+ when available. This enables applications to define `rack.response_finished` callbacks
257
+ that may rely on state that would be cleaned up by the executor's completion callbacks.
258
+
259
+ *Adrianna Chang*, *Hartley McGuire*
260
+
261
+ * Produce a log when `rescue_from` is invoked.
262
+
263
+ *Steven Webb*, *Jean Boussier*
264
+
265
+ * Allow hosts redirects from `hosts` Rails configuration
266
+
267
+ ```ruby
268
+ config.action_controller.allowed_redirect_hosts << "example.com"
269
+ ```
270
+
271
+ *Kevin Robatel*
272
+
273
+ * `rate_limit.action_controller` notification has additional payload
274
+
275
+ additional values: count, to, within, by, name, cache_key
276
+
277
+ *Jonathan Rochkind*
278
+
279
+ * Add JSON support to the built-in health controller.
280
+
281
+ The health controller now responds to JSON requests with a structured response
282
+ containing status and timestamp information. This makes it easier for monitoring
283
+ tools and load balancers to consume health check data programmatically.
284
+
285
+ ```ruby
286
+ # /up.json
287
+ {
288
+ "status": "up",
289
+ "timestamp": "2025-09-19T12:00:00Z"
290
+ }
291
+ ```
292
+
293
+ *Francesco Loreti*, *Juan Vásquez*
294
+
295
+ * Allow to open source file with a crash from the browser.
296
+
297
+ *Igor Kasyanchuk*
298
+
299
+ * Always check query string keys for valid encoding just like values are checked.
300
+
301
+ *Casper Smits*
302
+
303
+ * Always return empty body for HEAD requests in `PublicExceptions` and
304
+ `DebugExceptions`.
305
+
306
+ This is required by `Rack::Lint` (per RFC9110).
307
+
308
+ *Hartley McGuire*
114
309
 
115
- * Add rate limiting API.
310
+ * Add comprehensive support for HTTP Cache-Control request directives according to RFC 9111.
311
+
312
+ Provides a `request.cache_control_directives` object that gives access to request cache directives:
313
+
314
+ ```ruby
315
+ # Boolean directives
316
+ request.cache_control_directives.only_if_cached? # => true/false
317
+ request.cache_control_directives.no_cache? # => true/false
318
+ request.cache_control_directives.no_store? # => true/false
319
+ request.cache_control_directives.no_transform? # => true/false
320
+
321
+ # Value directives
322
+ request.cache_control_directives.max_age # => integer or nil
323
+ request.cache_control_directives.max_stale # => integer or nil (or true for valueless max-stale)
324
+ request.cache_control_directives.min_fresh # => integer or nil
325
+ request.cache_control_directives.stale_if_error # => integer or nil
326
+
327
+ # Special helpers for max-stale
328
+ request.cache_control_directives.max_stale? # => true if max-stale present (with or without value)
329
+ request.cache_control_directives.max_stale_unlimited? # => true only for valueless max-stale
330
+ ```
331
+
332
+ Example usage:
116
333
 
117
334
  ```ruby
118
- class SessionsController < ApplicationController
119
- rate_limit to: 10, within: 3.minutes, only: :create
335
+ def show
336
+ if request.cache_control_directives.only_if_cached?
337
+ @article = Article.find_cached(params[:id])
338
+ return head(:gateway_timeout) if @article.nil?
339
+ else
340
+ @article = Article.find(params[:id])
341
+ end
342
+
343
+ render :show
120
344
  end
345
+ ```
121
346
 
122
- class SignupsController < ApplicationController
123
- rate_limit to: 1000, within: 10.seconds,
124
- by: -> { request.domain }, with: -> { redirect_to busy_controller_url, alert: "Too many signups!" }, only: :new
347
+ *egg528*
348
+
349
+ * Add assert_in_body/assert_not_in_body as the simplest way to check if a piece of text is in the response body.
350
+
351
+ *DHH*
352
+
353
+ * Include cookie name when calculating maximum allowed size.
354
+
355
+ *Hartley McGuire*
356
+
357
+ * Implement `must-understand` directive according to RFC 9111.
358
+
359
+ The `must-understand` directive indicates that a cache must understand the semantics of the response status code, or discard the response. This directive is enforced to be used only with `no-store` to ensure proper cache behavior.
360
+
361
+ ```ruby
362
+ class ArticlesController < ApplicationController
363
+ def show
364
+ @article = Article.find(params[:id])
365
+
366
+ if @article.special_format?
367
+ must_understand
368
+ render status: 203 # Non-Authoritative Information
369
+ else
370
+ fresh_when @article
371
+ end
372
+ end
125
373
  end
126
374
  ```
127
375
 
128
- *DHH*, *Jean Boussier*
376
+ *heka1024*
377
+
378
+ * The JSON renderer doesn't escape HTML entities or Unicode line separators anymore.
379
+
380
+ Using `render json:` will no longer escape `<`, `>`, `&`, `U+2028` and `U+2029` characters that can cause errors
381
+ when the resulting JSON is embedded in JavaScript, or vulnerabilities when the resulting JSON is embedded in HTML.
129
382
 
130
- * Add `image/svg+xml` to the compressible content types of `ActionDispatch::Static`.
383
+ Since the renderer is used to return a JSON document as `application/json`, it's typically not necessary to escape
384
+ those characters, and it improves performance.
131
385
 
132
- *Georg Ledermann*
386
+ Escaping will still occur when the `:callback` option is set, since the JSON is used as JavaScript code in this
387
+ situation (JSONP).
133
388
 
134
- * Add instrumentation for `ActionController::Live#send_stream`.
389
+ You can use the `:escape` option or set `config.action_controller.escape_json_responses` to `true` to restore the
390
+ escaping behavior.
391
+
392
+ ```ruby
393
+ class PostsController < ApplicationController
394
+ def index
395
+ render json: Post.last(30), escape: true
396
+ end
397
+ end
398
+ ```
135
399
 
136
- Allows subscribing to `send_stream` events. The event payload contains the filename, disposition, and type.
400
+ *Étienne Barrié*, *Jean Boussier*
137
401
 
138
- *Hannah Ramadan*
402
+ * Load lazy route sets before inserting test routes
139
403
 
140
- * Add support for `with_routing` test helper in `ActionDispatch::IntegrationTest`.
404
+ Without loading lazy route sets early, we miss `after_routes_loaded` callbacks, or risk
405
+ invoking them with the test routes instead of the real ones if another load is triggered by an engine.
141
406
 
142
407
  *Gannon McGibbon*
143
408
 
144
- * Remove deprecated support to set `Rails.application.config.action_dispatch.show_exceptions` to `true` and `false`.
409
+ * Raise `AbstractController::DoubleRenderError` if `head` is called after rendering.
145
410
 
146
- *Rafael Mendonça França*
411
+ After this change, invoking `head` will lead to an error if response body is already set:
147
412
 
148
- * Remove deprecated `speaker`, `vibrate`, and `vr` permissions policy directives.
413
+ ```ruby
414
+ class PostController < ApplicationController
415
+ def index
416
+ render locals: {}
417
+ head :ok
418
+ end
419
+ end
420
+ ```
149
421
 
150
- *Rafael Mendonça França*
422
+ *Iaroslav Kurbatov*
151
423
 
152
- * Remove deprecated `Rails.application.config.action_dispatch.return_only_request_media_type_on_content_type`.
424
+ * The Cookie Serializer can now serialize an Active Support SafeBuffer when using message pack.
153
425
 
154
- *Rafael Mendonça França*
426
+ Such code would previously produce an error if an application was using messagepack as its cookie serializer.
155
427
 
156
- * Deprecate `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality`.
428
+ ```ruby
429
+ class PostController < ApplicationController
430
+ def index
431
+ flash.notice = t(:hello_html) # This would try to serialize a SafeBuffer, which was not possible.
432
+ end
433
+ end
434
+ ```
157
435
 
158
- *Rafael Mendonça França*
436
+ *Edouard Chin*
159
437
 
160
- * Remove deprecated comparison between `ActionController::Parameters` and `Hash`.
438
+ * Fix `Rails.application.reload_routes!` from clearing almost all routes.
161
439
 
162
- *Rafael Mendonça França*
440
+ When calling `Rails.application.reload_routes!` inside a middleware of
441
+ a Rake task, it was possible under certain conditions that all routes would be cleared.
442
+ If ran inside a middleware, this would result in getting a 404 on most page you visit.
443
+ This issue was only happening in development.
163
444
 
164
- * Remove deprecated constant `AbstractController::Helpers::MissingHelperError`.
445
+ *Edouard Chin*
165
446
 
166
- *Rafael Mendonça França*
447
+ * Add resource name to the `ArgumentError` that's raised when invalid `:only` or `:except` options are given to `#resource` or `#resources`
167
448
 
168
- * Fix a race condition that could cause a `Text file busy - chromedriver`
169
- error with parallel system tests.
449
+ This makes it easier to locate the source of the problem, especially for routes drawn by gems.
170
450
 
171
- *Matt Brictson*
451
+ Before:
452
+ ```
453
+ :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
454
+ ```
172
455
 
173
- * Add `racc` as a dependency since it will become a bundled gem in Ruby 3.4.0
456
+ After:
457
+ ```
458
+ Route `resources :products` - :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
459
+ ```
174
460
 
175
- *Hartley McGuire*
176
- * Remove deprecated constant `ActionDispatch::IllegalStateError`.
461
+ *Jeremy Green*
177
462
 
178
- *Rafael Mendonça França*
463
+ * A route pointing to a non-existing controller now returns a 500 instead of a 404.
179
464
 
180
- * Add parameter filter capability for redirect locations.
465
+ A controller not existing isn't a routing error that should result
466
+ in a 404, but a programming error that should result in a 500 and
467
+ be reported.
181
468
 
182
- It uses the `config.filter_parameters` to match what needs to be filtered.
183
- The result would be like this:
469
+ Until recently, this was hard to untangle because of the support
470
+ for dynamic `:controller` segment in routes, but since this is
471
+ deprecated and will be removed in Rails 8.1, we can now easily
472
+ not consider missing controllers as routing errors.
184
473
 
185
- Redirected to http://secret.foo.bar?username=roque&password=[FILTERED]
474
+ *Jean Boussier*
186
475
 
187
- Fixes #14055.
476
+ * Add `check_collisions` option to `ActionDispatch::Session::CacheStore`.
477
+
478
+ Newly generated session ids use 128 bits of randomness, which is more than
479
+ enough to ensure collisions can't happen, but if you need to harden sessions
480
+ even more, you can enable this option to check in the session store that the id
481
+ is indeed free you can enable that option. This however incurs an extra write
482
+ on session creation.
483
+
484
+ *Shia*
485
+
486
+ * In ExceptionWrapper, match backtrace lines with built templates more often,
487
+ allowing improved highlighting of errors within do-end blocks in templates.
488
+ Fix for Ruby 3.4 to match new method labels in backtrace.
489
+
490
+ *Martin Emde*
491
+
492
+ * Allow setting content type with a symbol of the Mime type.
493
+
494
+ ```ruby
495
+ # Before
496
+ response.content_type = "text/html"
497
+
498
+ # After
499
+ response.content_type = :html
500
+ ```
188
501
 
189
- *Roque Pinel*, *Trevor Turk*, *tonytonyjan*
502
+ *Petrik de Heus*
190
503
 
191
- Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/actionpack/CHANGELOG.md) for previous changes.
504
+ Please check [8-0-stable](https://github.com/rails/rails/blob/8-0-stable/actionpack/CHANGELOG.md) for previous changes.
data/README.rdoc CHANGED
@@ -52,6 +52,6 @@ Bug reports for the Ruby on \Rails project can be filed here:
52
52
 
53
53
  * https://github.com/rails/rails/issues
54
54
 
55
- Feature requests should be discussed on the rails-core mailing list here:
55
+ Feature requests should be discussed on the rubyonrails-core forum here:
56
56
 
57
57
  * https://discuss.rubyonrails.org/c/rubyonrails-core
@@ -7,8 +7,10 @@ module AbstractController
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
- config_accessor :asset_host, :assets_dir, :javascripts_dir,
11
- :stylesheets_dir, :default_asset_host_protocol, :relative_url_root
10
+ singleton_class.delegate :asset_host, :asset_host=, :assets_dir, :assets_dir=, :javascripts_dir, :javascripts_dir=,
11
+ :stylesheets_dir, :stylesheets_dir=, :default_asset_host_protocol, :default_asset_host_protocol=, :relative_url_root, :relative_url_root=, to: :config
12
+ delegate :asset_host, :asset_host=, :assets_dir, :assets_dir=, :javascripts_dir, :javascripts_dir=,
13
+ :stylesheets_dir, :stylesheets_dir=, :default_asset_host_protocol, :default_asset_host_protocol=, :relative_url_root, :relative_url_root=, to: :config
12
14
  end
13
15
  end
14
16
  end