actionpack 8.0.2 → 8.1.0.beta1

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +252 -137
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller/asset_paths.rb +4 -2
  5. data/lib/abstract_controller/base.rb +11 -14
  6. data/lib/abstract_controller/caching.rb +6 -3
  7. data/lib/abstract_controller/collector.rb +1 -1
  8. data/lib/abstract_controller/logger.rb +2 -1
  9. data/lib/action_controller/base.rb +1 -1
  10. data/lib/action_controller/caching.rb +1 -2
  11. data/lib/action_controller/form_builder.rb +1 -1
  12. data/lib/action_controller/log_subscriber.rb +7 -0
  13. data/lib/action_controller/metal/allow_browser.rb +1 -1
  14. data/lib/action_controller/metal/conditional_get.rb +25 -0
  15. data/lib/action_controller/metal/data_streaming.rb +1 -3
  16. data/lib/action_controller/metal/exceptions.rb +5 -0
  17. data/lib/action_controller/metal/flash.rb +1 -4
  18. data/lib/action_controller/metal/head.rb +3 -1
  19. data/lib/action_controller/metal/live.rb +0 -6
  20. data/lib/action_controller/metal/permissions_policy.rb +9 -0
  21. data/lib/action_controller/metal/rate_limiting.rb +22 -7
  22. data/lib/action_controller/metal/redirecting.rb +63 -7
  23. data/lib/action_controller/metal/renderers.rb +27 -6
  24. data/lib/action_controller/metal/rendering.rb +8 -2
  25. data/lib/action_controller/metal/request_forgery_protection.rb +18 -10
  26. data/lib/action_controller/metal/rescue.rb +9 -0
  27. data/lib/action_controller/railtie.rb +2 -6
  28. data/lib/action_controller/renderer.rb +0 -1
  29. data/lib/action_dispatch/constants.rb +6 -0
  30. data/lib/action_dispatch/http/cache.rb +111 -1
  31. data/lib/action_dispatch/http/content_security_policy.rb +13 -1
  32. data/lib/action_dispatch/http/filter_parameters.rb +5 -3
  33. data/lib/action_dispatch/http/mime_negotiation.rb +8 -3
  34. data/lib/action_dispatch/http/mime_types.rb +1 -0
  35. data/lib/action_dispatch/http/param_builder.rb +28 -27
  36. data/lib/action_dispatch/http/parameters.rb +3 -3
  37. data/lib/action_dispatch/http/permissions_policy.rb +4 -0
  38. data/lib/action_dispatch/http/query_parser.rb +12 -10
  39. data/lib/action_dispatch/http/request.rb +10 -5
  40. data/lib/action_dispatch/http/response.rb +65 -17
  41. data/lib/action_dispatch/http/url.rb +101 -5
  42. data/lib/action_dispatch/journey/gtg/simulator.rb +33 -12
  43. data/lib/action_dispatch/journey/gtg/transition_table.rb +29 -39
  44. data/lib/action_dispatch/journey/nodes/node.rb +2 -1
  45. data/lib/action_dispatch/journey/route.rb +45 -31
  46. data/lib/action_dispatch/journey/router/utils.rb +8 -14
  47. data/lib/action_dispatch/journey/router.rb +59 -81
  48. data/lib/action_dispatch/journey/routes.rb +7 -0
  49. data/lib/action_dispatch/journey/visitors.rb +55 -23
  50. data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
  51. data/lib/action_dispatch/middleware/cookies.rb +4 -2
  52. data/lib/action_dispatch/middleware/debug_exceptions.rb +10 -2
  53. data/lib/action_dispatch/middleware/debug_view.rb +11 -0
  54. data/lib/action_dispatch/middleware/exception_wrapper.rb +14 -8
  55. data/lib/action_dispatch/middleware/executor.rb +12 -2
  56. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -6
  57. data/lib/action_dispatch/middleware/session/cache_store.rb +17 -0
  58. data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
  59. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -2
  60. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
  61. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
  62. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
  63. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +1 -0
  64. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
  65. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
  66. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
  67. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
  68. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
  69. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
  70. data/lib/action_dispatch/railtie.rb +10 -2
  71. data/lib/action_dispatch/routing/inspector.rb +4 -1
  72. data/lib/action_dispatch/routing/mapper.rb +323 -173
  73. data/lib/action_dispatch/routing/route_set.rb +3 -6
  74. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +2 -2
  75. data/lib/action_dispatch/testing/assertion_response.rb +1 -1
  76. data/lib/action_dispatch/testing/assertions/response.rb +14 -0
  77. data/lib/action_dispatch/testing/assertions/routing.rb +11 -3
  78. data/lib/action_pack/gem_version.rb +3 -3
  79. metadata +13 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14abb1a6b812efa40da31cf30c3171405982457ed80984d231dae2af352f43f4
4
- data.tar.gz: 3e934fe98cf59aa4727eb76b0f13567861fe01c04dbc6cd9c4e313b165a0a64e
3
+ metadata.gz: ed45caa459109b7c6009c7b63f8be21dfe1965dc7bc745e8e7588579a9384391
4
+ data.tar.gz: aabc44311112b16f6e9b8c3f34f391d1fc1abe91cb1b0df7e920dd0068cbc8b0
5
5
  SHA512:
6
- metadata.gz: dde2e5f17a6d54ae692f64ec2d05a3dc8e54d4fb30d97dd4b1fa3e4c7363d1132facf04286c1b3f25ffdb78f8302eafa7a6c13d027b890589813e4e60e6f5e77
7
- data.tar.gz: 773181339ec3539e73607f4e1588082893c3ac38d54e6c32a930ccf85bcffb41c95ad568a6bbe00bbc41967f98ed964d3200880a3c1f7b1dbfafeef405d8b1b5
6
+ metadata.gz: 05dc45165c2451cf7a0bd23c7b5baf55ba3e970cde0877211b208f227b98e538237c373135f5d8c3ba905c18af5834d69086ab8e223a11f7d77fed3f0e067746
7
+ data.tar.gz: 43cba6f2e00ce49bc0b4ef8172eb26b6571325dcfa5c8b5deebcec90cfad8f6d8d7d0804459dc29e5fd36073aa8f1b09348999e6258197360be3306d9c41134e
data/CHANGELOG.md CHANGED
@@ -1,245 +1,360 @@
1
- ## Rails 8.0.2 (March 12, 2025) ##
1
+ ## Rails 8.1.0.beta1 (September 04, 2025) ##
2
2
 
3
- * No changes.
3
+ * Remove deprecated support to a route to multiple paths.
4
4
 
5
+ *Rafael Mendonça França*
5
6
 
6
- ## Rails 8.0.2 (March 12, 2025) ##
7
+ * Remove deprecated support for using semicolons as a query string separator.
7
8
 
8
- * Improve `with_routing` test helper to not rebuild the middleware stack.
9
+ Before:
9
10
 
10
- Otherwise some middleware configuration could be lost.
11
+ ```ruby
12
+ ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
13
+ # => [["foo", "bar"], ["baz", "quux"]]
14
+ ```
11
15
 
12
- *Édouard Chin*
16
+ After:
13
17
 
14
- * Add resource name to the `ArgumentError` that's raised when invalid `:only` or `:except` options are given to `#resource` or `#resources`
18
+ ```ruby
19
+ ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
20
+ # => [["foo", "bar;baz=quux"]]
21
+ ```
15
22
 
16
- This makes it easier to locate the source of the problem, especially for routes drawn by gems.
23
+ *Rafael Mendonça França*
24
+
25
+ * Remove deprecated support to skipping over leading brackets in parameter names in the parameter parser.
17
26
 
18
27
  Before:
19
- ```
20
- :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
28
+
29
+ ```ruby
30
+ ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "foo" => "bar" }
31
+ ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "foo" => { "bar" => "baz" } }
21
32
  ```
22
33
 
23
34
  After:
24
- ```
25
- Route `resources :products` - :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
35
+
36
+ ```ruby
37
+ ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "[foo]" => "bar" }
38
+ ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "[foo]" => { "bar" => "baz" } }
26
39
  ```
27
40
 
28
- *Jeremy Green*
41
+ *Rafael Mendonça França*
29
42
 
30
- * Fix `url_for` to handle `:path_params` gracefully when it's not a `Hash`.
43
+ * Deprecate `Rails.application.config.action_dispatch.ignore_leading_brackets`.
31
44
 
32
- Prevents various security scanners from causing exceptions.
45
+ *Rafael Mendonça França*
33
46
 
34
- *Martin Emde*
47
+ * Raise `ActionController::TooManyRequests` error from `ActionController::RateLimiting`
35
48
 
36
- * Fix `ActionDispatch::Executor` to unwrap exceptions like other error reporting middlewares.
49
+ Requests that exceed the rate limit raise an `ActionController::TooManyRequests` error.
50
+ By default, Action Dispatch rescues the error and responds with a `429 Too Many Requests` status.
37
51
 
38
- *Jean Boussier*
52
+ *Sean Doyle*
39
53
 
54
+ * Add .md/.markdown as Markdown extensions and add a default `markdown:` renderer:
40
55
 
41
- ## Rails 8.0.1 (December 13, 2024) ##
56
+ ```ruby
57
+ class Page
58
+ def to_markdown
59
+ body
60
+ end
61
+ end
42
62
 
43
- * Add `ActionDispatch::Request::Session#store` method to conform Rack spec.
63
+ class PagesController < ActionController::Base
64
+ def show
65
+ @page = Page.find(params[:id])
44
66
 
45
- *Yaroslav*
67
+ respond_to do |format|
68
+ format.html
69
+ format.md { render markdown: @page }
70
+ end
71
+ end
72
+ end
73
+ ```
46
74
 
75
+ *DHH*
47
76
 
48
- ## Rails 8.0.0.1 (December 10, 2024) ##
77
+ * Add headers to engine routes inspection command
49
78
 
50
- * Add validation to content security policies to disallow spaces and semicolons.
51
- Developers should use multiple arguments, and different directive methods instead.
79
+ *Petrik de Heus*
52
80
 
53
- [CVE-2024-54133]
81
+ * Add "Copy as text" button to error pages
54
82
 
55
- *Gannon McGibbon*
83
+ *Mikkel Malmberg*
56
84
 
85
+ * Add `scope:` option to `rate_limit` method.
57
86
 
58
- ## Rails 8.0.0 (November 07, 2024) ##
87
+ Previously, it was not possible to share a rate limit count between several controllers, since the count was by
88
+ default separate for each controller.
59
89
 
60
- * No changes.
90
+ Now, the `scope:` option solves this problem.
61
91
 
92
+ ```ruby
93
+ class APIController < ActionController::API
94
+ rate_limit to: 2, within: 2.seconds, scope: "api"
95
+ end
62
96
 
63
- ## Rails 8.0.0.rc2 (October 30, 2024) ##
97
+ class API::PostsController < APIController
98
+ # ...
99
+ end
64
100
 
65
- * Fix routes with `::` in the path.
101
+ class API::UsersController < APIController
102
+ # ...
103
+ end
104
+ ```
66
105
 
67
- *Rafael Mendonça França*
106
+ *ArthurPV*, *Kamil Hanus*
68
107
 
69
- * Maintain Rack 2 parameter parsing behaviour.
108
+ * Add support for `rack.response_finished` callbacks in ActionDispatch::Executor.
70
109
 
71
- *Matthew Draper*
110
+ The executor middleware now supports deferring completion callbacks to later
111
+ in the request lifecycle by utilizing Rack's `rack.response_finished` mechanism,
112
+ when available. This enables applications to define `rack.response_finished` callbacks
113
+ that may rely on state that would be cleaned up by the executor's completion callbacks.
72
114
 
115
+ *Adrianna Chang*, *Hartley McGuire*
73
116
 
74
- ## Rails 8.0.0.rc1 (October 19, 2024) ##
117
+ * Produce a log when `rescue_from` is invoked.
75
118
 
76
- * Remove `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality`.
119
+ *Steven Webb*, *Jean Boussier*
77
120
 
78
- *Rafael Mendonça França*
121
+ * Allow hosts redirects from `hosts` Rails configuration
79
122
 
80
- * Improve `ActionController::TestCase` to expose a binary encoded `request.body`.
123
+ ```ruby
124
+ config.action_controller.allowed_redirect_hosts << "example.com"
125
+ ```
81
126
 
82
- The rack spec clearly states:
127
+ *Kevin Robatel*
83
128
 
84
- > The input stream is an IO-like object which contains the raw HTTP POST data.
85
- > When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode.
129
+ * `rate_limit.action_controller` notification has additional payload
86
130
 
87
- Until now its encoding was generally UTF-8, which doesn't accurately reflect production
88
- behavior.
131
+ additional values: count, to, within, by, name, cache_key
89
132
 
90
- *Jean Boussier*
133
+ *Jonathan Rochkind*
91
134
 
92
- * Update `ActionController::AllowBrowser` to support passing method names to `:block`
135
+ * Add JSON support to the built-in health controller.
93
136
 
94
- ```ruby
95
- class ApplicationController < ActionController::Base
96
- allow_browser versions: :modern, block: :handle_outdated_browser
137
+ The health controller now responds to JSON requests with a structured response
138
+ containing status and timestamp information. This makes it easier for monitoring
139
+ tools and load balancers to consume health check data programmatically.
97
140
 
98
- private
99
- def handle_outdated_browser
100
- render file: Rails.root.join("public/custom-error.html"), status: :not_acceptable
101
- end
102
- end
141
+ ```ruby
142
+ # /up.json
143
+ {
144
+ "status": "up",
145
+ "timestamp": "2025-09-19T12:00:00Z"
146
+ }
103
147
  ```
104
148
 
105
- *Sean Doyle*
149
+ *Francesco Loreti*, *Juan Vásquez*
106
150
 
107
- * Raise an `ArgumentError` when invalid `:only` or `:except` options are passed into `#resource` and `#resources`.
151
+ * Allow to open source file with a crash from the browser.
108
152
 
109
- *Joshua Young*
153
+ *Igor Kasyanchuk*
110
154
 
111
- ## Rails 8.0.0.beta1 (September 26, 2024) ##
155
+ * Always check query string keys for valid encoding just like values are checked.
112
156
 
113
- * Fix non-GET requests not updating cookies in `ActionController::TestCase`.
157
+ *Casper Smits*
114
158
 
115
- *Jon Moss*, *Hartley McGuire*
159
+ * Always return empty body for HEAD requests in `PublicExceptions` and
160
+ `DebugExceptions`.
116
161
 
117
- * Update `ActionController::Live` to use a thread-pool to reuse threads across requests.
162
+ This is required by `Rack::Lint` (per RFC9110).
118
163
 
119
- *Adam Renberg Tamm*
164
+ *Hartley McGuire*
120
165
 
121
- * Introduce safer, more explicit params handling method with `params#expect` such that
122
- `params.expect(table: [ :attr ])` replaces `params.require(:table).permit(:attr)`
166
+ * Add comprehensive support for HTTP Cache-Control request directives according to RFC 9111.
123
167
 
124
- Ensures params are filtered with consideration for the expected
125
- types of values, improving handling of params and avoiding ignorable
126
- errors caused by params tampering.
168
+ Provides a `request.cache_control_directives` object that gives access to request cache directives:
127
169
 
128
170
  ```ruby
129
- # If the url is altered to ?person=hacked
130
- # Before
131
- params.require(:person).permit(:name, :age, pets: [:name])
132
- # raises NoMethodError, causing a 500 and potential error reporting
171
+ # Boolean directives
172
+ request.cache_control_directives.only_if_cached? # => true/false
173
+ request.cache_control_directives.no_cache? # => true/false
174
+ request.cache_control_directives.no_store? # => true/false
175
+ request.cache_control_directives.no_transform? # => true/false
176
+
177
+ # Value directives
178
+ request.cache_control_directives.max_age # => integer or nil
179
+ request.cache_control_directives.max_stale # => integer or nil (or true for valueless max-stale)
180
+ request.cache_control_directives.min_fresh # => integer or nil
181
+ request.cache_control_directives.stale_if_error # => integer or nil
182
+
183
+ # Special helpers for max-stale
184
+ request.cache_control_directives.max_stale? # => true if max-stale present (with or without value)
185
+ request.cache_control_directives.max_stale_unlimited? # => true only for valueless max-stale
186
+ ```
133
187
 
134
- # After
135
- params.expect(person: [ :name, :age, pets: [[:name]] ])
136
- # raises ActionController::ParameterMissing, correctly returning a 400 error
188
+ Example usage:
189
+
190
+ ```ruby
191
+ def show
192
+ if request.cache_control_directives.only_if_cached?
193
+ @article = Article.find_cached(params[:id])
194
+ return head(:gateway_timeout) if @article.nil?
195
+ else
196
+ @article = Article.find(params[:id])
197
+ end
198
+
199
+ render :show
200
+ end
137
201
  ```
138
202
 
139
- You may also notice the new double array `[[:name]]`. In order to
140
- declare when a param is expected to be an array of parameter hashes,
141
- this new double array syntax is used to explicitly declare an array.
142
- `expect` requires you to declare expected arrays in this way, and will
143
- ignore arrays that are passed when, for example, `pet: [:name]` is used.
203
+ *egg528*
144
204
 
145
- In order to preserve compatibility, `permit` does not adopt the new
146
- double array syntax and is therefore more permissive about unexpected
147
- types. Using `expect` everywhere is recommended.
205
+ * Add assert_in_body/assert_not_in_body as the simplest way to check if a piece of text is in the response body.
148
206
 
149
- We suggest replacing `params.require(:person).permit(:name, :age)`
150
- with the direct replacement `params.expect(person: [:name, :age])`
151
- to prevent external users from manipulating params to trigger 500
152
- errors. A 400 error will be returned instead, using public/400.html
207
+ *DHH*
153
208
 
154
- Usage of `params.require(:id)` should likewise be replaced with
155
- `params.expect(:id)` which is designed to ensure that `params[:id]`
156
- is a scalar and not an array or hash, also requiring the param.
209
+ * Include cookie name when calculating maximum allowed size.
157
210
 
158
- ```ruby
159
- # Before
160
- User.find(params.require(:id)) # allows an array, altering behavior
211
+ *Hartley McGuire*
161
212
 
162
- # After
163
- User.find(params.expect(:id)) # expect only returns non-blank permitted scalars (excludes Hash, Array, nil, "", etc)
213
+ * Implement `must-understand` directive according to RFC 9111.
214
+
215
+ 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.
216
+
217
+ ```ruby
218
+ class ArticlesController < ApplicationController
219
+ def show
220
+ @article = Article.find(params[:id])
221
+
222
+ if @article.special_format?
223
+ must_understand
224
+ render status: 203 # Non-Authoritative Information
225
+ else
226
+ fresh_when @article
227
+ end
228
+ end
229
+ end
164
230
  ```
165
231
 
166
- *Martin Emde*
232
+ *heka1024*
167
233
 
168
- * System Testing: Disable Chrome's search engine choice by default in system tests.
234
+ * The JSON renderer doesn't escape HTML entities or Unicode line separators anymore.
169
235
 
170
- *glaszig*
236
+ Using `render json:` will no longer escape `<`, `>`, `&`, `U+2028` and `U+2029` characters that can cause errors
237
+ when the resulting JSON is embedded in JavaScript, or vulnerabilities when the resulting JSON is embedded in HTML.
171
238
 
172
- * Fix `Request#raw_post` raising `NoMethodError` when `rack.input` is `nil`.
239
+ Since the renderer is used to return a JSON document as `application/json`, it's typically not necessary to escape
240
+ those characters, and it improves performance.
173
241
 
174
- *Hartley McGuire*
242
+ Escaping will still occur when the `:callback` option is set, since the JSON is used as JavaScript code in this
243
+ situation (JSONP).
175
244
 
176
- * Remove `racc` dependency by manually writing `ActionDispatch::Journey::Scanner`.
245
+ You can use the `:escape` option or set `config.action_controller.escape_json_responses` to `true` to restore the
246
+ escaping behavior.
177
247
 
178
- *Gannon McGibbon*
248
+ ```ruby
249
+ class PostsController < ApplicationController
250
+ def index
251
+ render json: Post.last(30), escape: true
252
+ end
253
+ end
254
+ ```
179
255
 
180
- * Speed up `ActionDispatch::Routing::Mapper::Scope#[]` by merging frame hashes.
256
+ *Étienne Barrié*, *Jean Boussier*
257
+
258
+ * Load lazy route sets before inserting test routes
259
+
260
+ Without loading lazy route sets early, we miss `after_routes_loaded` callbacks, or risk
261
+ invoking them with the test routes instead of the real ones if another load is triggered by an engine.
181
262
 
182
263
  *Gannon McGibbon*
183
264
 
184
- * Allow bots to ignore `allow_browser`.
265
+ * Raise `AbstractController::DoubleRenderError` if `head` is called after rendering.
266
+
267
+ After this change, invoking `head` will lead to an error if response body is already set:
268
+
269
+ ```ruby
270
+ class PostController < ApplicationController
271
+ def index
272
+ render locals: {}
273
+ head :ok
274
+ end
275
+ end
276
+ ```
185
277
 
186
- *Matthew Nguyen*
278
+ *Iaroslav Kurbatov*
187
279
 
188
- * Deprecate drawing routes with multiple paths to make routing faster.
189
- You may use `with_options` or a loop to make drawing multiple paths easier.
280
+ * The Cookie Serializer can now serialize an Active Support SafeBuffer when using message pack.
281
+
282
+ Such code would previously produce an error if an application was using messagepack as its cookie serializer.
190
283
 
191
284
  ```ruby
192
- # Before
193
- get "/users", "/other_path", to: "users#index"
285
+ class PostController < ApplicationController
286
+ def index
287
+ flash.notice = t(:hello_html) # This would try to serialize a SafeBuffer, which was not possible.
288
+ end
289
+ end
290
+ ```
194
291
 
195
- # After
196
- get "/users", to: "users#index"
197
- get "/other_path", to: "users#index"
292
+ *Edouard Chin*
293
+
294
+ * Fix `Rails.application.reload_routes!` from clearing almost all routes.
295
+
296
+ When calling `Rails.application.reload_routes!` inside a middleware of
297
+ a Rake task, it was possible under certain conditions that all routes would be cleared.
298
+ If ran inside a middleware, this would result in getting a 404 on most page you visit.
299
+ This issue was only happening in development.
300
+
301
+ *Edouard Chin*
302
+
303
+ * Add resource name to the `ArgumentError` that's raised when invalid `:only` or `:except` options are given to `#resource` or `#resources`
304
+
305
+ This makes it easier to locate the source of the problem, especially for routes drawn by gems.
306
+
307
+ Before:
308
+ ```
309
+ :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
198
310
  ```
199
311
 
200
- *Gannon McGibbon*
312
+ After:
313
+ ```
314
+ Route `resources :products` - :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
315
+ ```
201
316
 
202
- * Make `http_cache_forever` use `immutable: true`
317
+ *Jeremy Green*
203
318
 
204
- *Nate Matykiewicz*
319
+ * A route pointing to a non-existing controller now returns a 500 instead of a 404.
205
320
 
206
- * Add `config.action_dispatch.strict_freshness`.
321
+ A controller not existing isn't a routing error that should result
322
+ in a 404, but a programming error that should result in a 500 and
323
+ be reported.
207
324
 
208
- When set to `true`, the `ETag` header takes precedence over the `Last-Modified` header when both are present,
209
- as specified by RFC 7232, Section 6.
325
+ Until recently, this was hard to untangle because of the support
326
+ for dynamic `:controller` segment in routes, but since this is
327
+ deprecated and will be removed in Rails 8.1, we can now easily
328
+ not consider missing controllers as routing errors.
210
329
 
211
- Defaults to `false` to maintain compatibility with previous versions of Rails, but is enabled as part of
212
- Rails 8.0 defaults.
330
+ *Jean Boussier*
213
331
 
214
- *heka1024*
332
+ * Add `check_collisions` option to `ActionDispatch::Session::CacheStore`.
215
333
 
216
- * Support `immutable` directive in Cache-Control
334
+ Newly generated session ids use 128 bits of randomness, which is more than
335
+ enough to ensure collisions can't happen, but if you need to harden sessions
336
+ even more, you can enable this option to check in the session store that the id
337
+ is indeed free you can enable that option. This however incurs an extra write
338
+ on session creation.
217
339
 
218
- ```ruby
219
- expires_in 1.minute, public: true, immutable: true
220
- # Cache-Control: public, max-age=60, immutable
221
- ```
340
+ *Shia*
222
341
 
223
- *heka1024*
342
+ * In ExceptionWrapper, match backtrace lines with built templates more often,
343
+ allowing improved highlighting of errors within do-end blocks in templates.
344
+ Fix for Ruby 3.4 to match new method labels in backtrace.
224
345
 
225
- * Add `:wasm_unsafe_eval` mapping for `content_security_policy`
346
+ *Martin Emde*
347
+
348
+ * Allow setting content type with a symbol of the Mime type.
226
349
 
227
350
  ```ruby
228
351
  # Before
229
- policy.script_src "'wasm-unsafe-eval'"
352
+ response.content_type = "text/html"
230
353
 
231
354
  # After
232
- policy.script_src :wasm_unsafe_eval
355
+ response.content_type = :html
233
356
  ```
234
357
 
235
- *Joe Haig*
236
-
237
- * Add `display_capture` and `keyboard_map` in `permissions_policy`
238
-
239
- *Cyril Blaecke*
240
-
241
- * Add `connect` route helper.
242
-
243
- *Samuel Williams*
358
+ *Petrik de Heus*
244
359
 
245
- Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/actionpack/CHANGELOG.md) for previous changes.
360
+ 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
@@ -3,7 +3,6 @@
3
3
  # :markup: markdown
4
4
 
5
5
  require "abstract_controller/error"
6
- require "active_support/configurable"
7
6
  require "active_support/descendants_tracker"
8
7
  require "active_support/core_ext/module/anonymous"
9
8
  require "active_support/core_ext/module/attr_internal"
@@ -47,7 +46,7 @@ module AbstractController
47
46
  # Returns the formats that can be processed by the controller.
48
47
  attr_internal :formats
49
48
 
50
- include ActiveSupport::Configurable
49
+ class_attribute :config, instance_predicate: false, default: ActiveSupport::OrderedOptions.new
51
50
  extend ActiveSupport::DescendantsTracker
52
51
 
53
52
  class << self
@@ -65,6 +64,7 @@ module AbstractController
65
64
  unless klass.instance_variable_defined?(:@abstract)
66
65
  klass.instance_variable_set(:@abstract, false)
67
66
  end
67
+ klass.config = ActiveSupport::InheritableOptions.new(config)
68
68
  super
69
69
  end
70
70
 
@@ -86,14 +86,10 @@ module AbstractController
86
86
  controller.public_instance_methods(true) - methods
87
87
  end
88
88
 
89
- # A list of method names that should be considered actions. This includes all
89
+ # A `Set` of method names that should be considered actions. This includes all
90
90
  # public instance methods on a controller, less any internal methods (see
91
91
  # internal_methods), adding back in any methods that are internal, but still
92
92
  # exist on the class itself.
93
- #
94
- # #### Returns
95
- # * `Set` - A set of all methods that should be considered actions.
96
- #
97
93
  def action_methods
98
94
  @action_methods ||= begin
99
95
  # All public instance methods of this class, including ancestors except for
@@ -121,13 +117,14 @@ module AbstractController
121
117
  #
122
118
  # MyApp::MyPostsController.controller_path # => "my_app/my_posts"
123
119
  #
124
- # #### Returns
125
- # * `String`
126
- #
127
120
  def controller_path
128
121
  @controller_path ||= name.delete_suffix("Controller").underscore unless anonymous?
129
122
  end
130
123
 
124
+ def configure # :nodoc:
125
+ yield config
126
+ end
127
+
131
128
  # Refresh the cached action_methods when a new action_method is added.
132
129
  def method_added(name)
133
130
  super
@@ -147,10 +144,6 @@ module AbstractController
147
144
  # The actual method that is called is determined by calling #method_for_action.
148
145
  # If no method can handle the action, then an AbstractController::ActionNotFound
149
146
  # error is raised.
150
- #
151
- # #### Returns
152
- # * `self`
153
- #
154
147
  def process(action, ...)
155
148
  @_action_name = action.to_s
156
149
 
@@ -201,6 +194,10 @@ module AbstractController
201
194
  true
202
195
  end
203
196
 
197
+ def config # :nodoc:
198
+ @_config ||= self.class.config.inheritable_copy
199
+ end
200
+
204
201
  def inspect # :nodoc:
205
202
  "#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>"
206
203
  end
@@ -32,13 +32,16 @@ module AbstractController
32
32
  included do
33
33
  extend ConfigMethods
34
34
 
35
- config_accessor :default_static_extension
35
+ singleton_class.delegate :default_static_extension, :default_static_extension=, to: :config
36
+ delegate :default_static_extension, :default_static_extension=, to: :config
36
37
  self.default_static_extension ||= ".html"
37
38
 
38
- config_accessor :perform_caching
39
+ singleton_class.delegate :perform_caching, :perform_caching=, to: :config
40
+ delegate :perform_caching, :perform_caching=, to: :config
39
41
  self.perform_caching = true if perform_caching.nil?
40
42
 
41
- config_accessor :enable_fragment_cache_logging
43
+ singleton_class.delegate :enable_fragment_cache_logging, :enable_fragment_cache_logging=, to: :config
44
+ delegate :enable_fragment_cache_logging, :enable_fragment_cache_logging=, to: :config
42
45
  self.enable_fragment_cache_logging = false
43
46
 
44
47
  class_attribute :_view_cache_dependencies, default: []
@@ -27,7 +27,7 @@ module AbstractController
27
27
  def method_missing(symbol, ...)
28
28
  unless mime_constant = Mime[symbol]
29
29
  raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \
30
- "https://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
30
+ "https://guides.rubyonrails.org/action_controller_advanced_topics.html#restful-downloads. " \
31
31
  "If you meant to respond to a variant like :tablet or :phone, not a custom format, " \
32
32
  "be sure to nest your variant response within a format response: " \
33
33
  "format.html { |html| html.tablet { ... } }"
@@ -9,7 +9,8 @@ module AbstractController
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  included do
12
- config_accessor :logger
12
+ singleton_class.delegate :logger, :logger=, to: :config
13
+ delegate :logger, :logger=, to: :config
13
14
  include ActiveSupport::Benchmarkable
14
15
  end
15
16
  end