actionpack 7.1.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +308 -523
- data/README.rdoc +1 -1
- data/lib/abstract_controller/asset_paths.rb +6 -2
- data/lib/abstract_controller/base.rb +104 -105
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +8 -3
- data/lib/abstract_controller/callbacks.rb +70 -62
- data/lib/abstract_controller/collector.rb +7 -7
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +71 -84
- data/lib/abstract_controller/logger.rb +4 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -13
- data/lib/abstract_controller/translation.rb +12 -13
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +76 -72
- data/lib/action_controller/base.rb +199 -126
- data/lib/action_controller/caching.rb +16 -14
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +21 -18
- data/lib/action_controller/log_subscriber.rb +23 -2
- data/lib/action_controller/metal/allow_browser.rb +133 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +217 -175
- data/lib/action_controller/metal/content_security_policy.rb +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +72 -63
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +16 -9
- data/lib/action_controller/metal/flash.rb +13 -14
- data/lib/action_controller/metal/head.rb +15 -11
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +209 -201
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +16 -14
- data/lib/action_controller/metal/live.rb +177 -128
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +22 -12
- data/lib/action_controller/metal/rate_limiting.rb +92 -0
- data/lib/action_controller/metal/redirecting.rb +213 -94
- data/lib/action_controller/metal/renderers.rb +78 -57
- data/lib/action_controller/metal/rendering.rb +111 -77
- data/lib/action_controller/metal/request_forgery_protection.rb +182 -143
- data/lib/action_controller/metal/rescue.rb +20 -9
- data/lib/action_controller/metal/streaming.rb +118 -195
- data/lib/action_controller/metal/strong_parameters.rb +720 -530
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +86 -60
- data/lib/action_controller/railtie.rb +36 -15
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +41 -36
- data/lib/action_controller/structured_event_subscriber.rb +116 -0
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +160 -131
- data/lib/action_controller.rb +5 -1
- data/lib/action_dispatch/constants.rb +8 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +163 -35
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +54 -39
- data/lib/action_dispatch/http/filter_parameters.rb +14 -8
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +89 -41
- data/lib/action_dispatch/http/mime_type.rb +25 -21
- data/lib/action_dispatch/http/mime_types.rb +3 -0
- data/lib/action_dispatch/http/param_builder.rb +187 -0
- data/lib/action_dispatch/http/param_error.rb +26 -0
- data/lib/action_dispatch/http/parameters.rb +14 -12
- data/lib/action_dispatch/http/permissions_policy.rb +25 -36
- data/lib/action_dispatch/http/query_parser.rb +55 -0
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +141 -92
- data/lib/action_dispatch/http/response.rb +137 -77
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +187 -89
- data/lib/action_dispatch/journey/formatter.rb +21 -9
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +34 -11
- data/lib/action_dispatch/journey/gtg/transition_table.rb +47 -53
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +8 -6
- data/lib/action_dispatch/journey/parser.rb +99 -195
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +54 -38
- data/lib/action_dispatch/journey/router/utils.rb +22 -27
- data/lib/action_dispatch/journey/router.rb +63 -83
- data/lib/action_dispatch/journey/routes.rb +11 -2
- data/lib/action_dispatch/journey/scanner.rb +46 -42
- data/lib/action_dispatch/journey/visitors.rb +57 -23
- data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +7 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +125 -106
- data/lib/action_dispatch/middleware/debug_exceptions.rb +37 -8
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +13 -5
- data/lib/action_dispatch/middleware/exception_wrapper.rb +18 -23
- data/lib/action_dispatch/middleware/executor.rb +19 -4
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +14 -12
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +87 -77
- data/lib/action_dispatch/middleware/request_id.rb +16 -10
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +30 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
- data/lib/action_dispatch/middleware/ssl.rb +53 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -5
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +23 -3
- data/lib/action_dispatch/request/session.rb +24 -21
- data/lib/action_dispatch/request/utils.rb +11 -3
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +85 -60
- data/lib/action_dispatch/routing/mapper.rb +1031 -851
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +47 -39
- data/lib/action_dispatch/routing/route_set.rb +79 -56
- data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/structured_event_subscriber.rb +20 -0
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +16 -23
- data/lib/action_dispatch/system_testing/driver.rb +2 -0
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +34 -23
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +9 -7
- data/lib/action_dispatch/testing/assertions/response.rb +52 -25
- data/lib/action_dispatch/testing/assertions/routing.rb +168 -87
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +233 -223
- data/lib/action_dispatch/testing/request_encoder.rb +11 -9
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +11 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +36 -32
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +36 -32
- data/lib/action_dispatch/journey/parser.y +0 -50
- data/lib/action_dispatch/journey/parser_extras.rb +0 -31
data/CHANGELOG.md
CHANGED
|
@@ -1,719 +1,504 @@
|
|
|
1
|
-
## Rails
|
|
1
|
+
## Rails 8.1.2 (January 08, 2026) ##
|
|
2
2
|
|
|
3
|
-
* Add
|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Rails 7.1.5 (October 30, 2024) ##
|
|
12
|
-
|
|
13
|
-
* No changes.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## Rails 7.1.4.2 (October 23, 2024) ##
|
|
17
|
-
|
|
18
|
-
* No changes.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
## Rails 7.1.4.1 (October 15, 2024) ##
|
|
22
|
-
|
|
23
|
-
* Avoid regex backtracking in HTTP Token authentication
|
|
24
|
-
|
|
25
|
-
[CVE-2024-47887]
|
|
26
|
-
|
|
27
|
-
*John Hawthorn*
|
|
28
|
-
|
|
29
|
-
* Avoid regex backtracking in query parameter filtering
|
|
30
|
-
|
|
31
|
-
[CVE-2024-41128]
|
|
32
|
-
|
|
33
|
-
*John Hawthorn*
|
|
34
|
-
|
|
35
|
-
## Rails 7.1.4 (August 22, 2024) ##
|
|
36
|
-
|
|
37
|
-
* Resolve deprecation warning in latest `selenium-webdriver`.
|
|
38
|
-
|
|
39
|
-
*Earlopain*
|
|
40
|
-
|
|
41
|
-
* Don't preload Selenium browser when remote.
|
|
42
|
-
|
|
43
|
-
*Noah Horton*
|
|
44
|
-
|
|
45
|
-
* Fix crash for invalid Content-Type in ShowExceptions middleware.
|
|
46
|
-
|
|
47
|
-
*Earlopain*
|
|
48
|
-
|
|
49
|
-
* Fix inconsistent results of `params.deep_transform_keys`.
|
|
50
|
-
|
|
51
|
-
*Iago Pimenta*
|
|
52
|
-
|
|
53
|
-
* Do not report rendered errors except 500.
|
|
54
|
-
|
|
55
|
-
*Nikita Vasilevsky*
|
|
56
|
-
|
|
57
|
-
* Improve routes source location detection.
|
|
58
|
-
|
|
59
|
-
*Jean Boussier*
|
|
60
|
-
|
|
61
|
-
* Fix `Request#raw_post` raising `NoMethodError` when `rack.input` is `nil`.
|
|
62
|
-
|
|
63
|
-
*Hartley McGuire*
|
|
64
|
-
|
|
65
|
-
* Fix url generation in nested engine when script name is empty.
|
|
66
|
-
|
|
67
|
-
*zzak*
|
|
68
|
-
|
|
69
|
-
* Fix `Mime::Type.parse` handling type parameters for HTTP Accept headers.
|
|
70
|
-
|
|
71
|
-
*Taylor Chaparro*
|
|
72
|
-
|
|
73
|
-
* Fix the error page that is displayed when a view template is missing to account for nested controller paths in the
|
|
74
|
-
suggested correct location for the missing template.
|
|
75
|
-
|
|
76
|
-
*Joshua Young*
|
|
77
|
-
|
|
78
|
-
* Fix a regression in 7.1.3 passing a `to:` option without a controller when the controller is already defined by a scope.
|
|
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.
|
|
79
11
|
|
|
80
12
|
```ruby
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
get "recent", to: "recent_posts"
|
|
84
|
-
end
|
|
85
|
-
end
|
|
13
|
+
# config/application.rb
|
|
14
|
+
config.action_controller.live_streaming_excluded_keys = [:active_record_connected_to_stack]
|
|
86
15
|
```
|
|
87
16
|
|
|
88
|
-
|
|
17
|
+
By default, all keys are shared.
|
|
89
18
|
|
|
90
|
-
*
|
|
91
|
-
|
|
92
|
-
In the default production environment, `ShowExceptions` rescues uncaught errors
|
|
93
|
-
and returns a response. Because of this the executor wouldn't report production
|
|
94
|
-
errors with the default Rails configuration.
|
|
95
|
-
|
|
96
|
-
*Jean Boussier*
|
|
19
|
+
*Eileen M. Uchitelle*
|
|
97
20
|
|
|
21
|
+
* Fix `IpSpoofAttackError` message to include `Forwarded` header content.
|
|
98
22
|
|
|
99
|
-
|
|
23
|
+
Without it, the error message may be misleading.
|
|
100
24
|
|
|
101
|
-
*
|
|
102
|
-
[CVE-2024-28103]
|
|
25
|
+
*zzak*
|
|
103
26
|
|
|
104
|
-
*Aaron Patterson*
|
|
105
27
|
|
|
106
|
-
## Rails
|
|
28
|
+
## Rails 8.1.1 (October 28, 2025) ##
|
|
107
29
|
|
|
108
|
-
*
|
|
30
|
+
* Allow methods starting with underscore to be action methods.
|
|
109
31
|
|
|
32
|
+
Disallowing methods starting with an underscore from being action methods
|
|
33
|
+
was an unintended side effect of the performance optimization in
|
|
34
|
+
207a254.
|
|
110
35
|
|
|
111
|
-
|
|
36
|
+
Fixes #55985.
|
|
112
37
|
|
|
113
|
-
*
|
|
114
|
-
`translate` method in controllers after the patch for CVE-2024-26143.
|
|
38
|
+
*Rafael Mendonça França*
|
|
115
39
|
|
|
116
|
-
*John Hawthorn*
|
|
117
40
|
|
|
118
|
-
## Rails
|
|
41
|
+
## Rails 8.1.0 (October 22, 2025) ##
|
|
119
42
|
|
|
120
|
-
*
|
|
43
|
+
* Submit test requests using `as: :html` with `Content-Type: x-www-form-urlencoded`
|
|
121
44
|
|
|
122
|
-
|
|
45
|
+
*Sean Doyle*
|
|
123
46
|
|
|
124
|
-
|
|
47
|
+
* Add link-local IP ranges to `ActionDispatch::RemoteIp` default proxies.
|
|
125
48
|
|
|
126
|
-
|
|
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.
|
|
127
51
|
|
|
128
|
-
|
|
52
|
+
*Adam Daniels*
|
|
129
53
|
|
|
130
|
-
|
|
54
|
+
* `remote_ip` will no longer ignore IPs in X-Forwarded-For headers if they
|
|
55
|
+
are accompanied by port information.
|
|
131
56
|
|
|
132
|
-
|
|
57
|
+
*Duncan Brown*, *Prevenios Marinos*, *Masafumi Koba*, *Adam Daniels*
|
|
133
58
|
|
|
134
|
-
*
|
|
135
|
-
`ActiveSupport::Concern.`
|
|
59
|
+
* Add `action_dispatch.verbose_redirect_logs` setting that logs where redirects were called from.
|
|
136
60
|
|
|
137
|
-
|
|
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.
|
|
138
62
|
|
|
139
|
-
|
|
140
|
-
Selenium.
|
|
63
|
+
Example:
|
|
141
64
|
|
|
142
|
-
|
|
65
|
+
```
|
|
66
|
+
Redirected to http://localhost:3000/posts/1
|
|
67
|
+
↳ app/controllers/posts_controller.rb:32:in `block (2 levels) in create'
|
|
68
|
+
```
|
|
143
69
|
|
|
70
|
+
*Dennis Paagman*
|
|
144
71
|
|
|
145
|
-
|
|
72
|
+
* Add engine route filtering and better formatting in `bin/rails routes`.
|
|
146
73
|
|
|
147
|
-
|
|
148
|
-
|
|
74
|
+
Allow engine routes to be filterable in the routing inspector, and
|
|
75
|
+
improve formatting of engine routing output.
|
|
149
76
|
|
|
150
|
-
|
|
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
|
+
```
|
|
151
83
|
|
|
152
|
-
|
|
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
|
+
```
|
|
153
95
|
|
|
154
|
-
|
|
155
|
-
component is blank.
|
|
96
|
+
*Dennis Paagman*, *Gannon McGibbon*
|
|
156
97
|
|
|
157
|
-
|
|
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`
|
|
158
109
|
|
|
159
|
-
*
|
|
110
|
+
*Adrianna Chang*
|
|
160
111
|
|
|
161
|
-
|
|
112
|
+
* URL helpers for engines mounted at the application root handle `SCRIPT_NAME` correctly.
|
|
162
113
|
|
|
163
|
-
|
|
114
|
+
Fixed an issue where `SCRIPT_NAME` is not applied to paths generated for routes in an engine
|
|
115
|
+
mounted at "/".
|
|
164
116
|
|
|
165
|
-
*
|
|
117
|
+
*Mike Dalessio*
|
|
166
118
|
|
|
119
|
+
* Update `ActionController::Metal::RateLimiting` to support passing method names to `:by` and `:with`
|
|
167
120
|
|
|
168
|
-
|
|
121
|
+
```ruby
|
|
122
|
+
class SignupsController < ApplicationController
|
|
123
|
+
rate_limit to: 10, within: 1.minute, with: :redirect_with_flash
|
|
169
124
|
|
|
170
|
-
|
|
125
|
+
private
|
|
126
|
+
def redirect_with_flash
|
|
127
|
+
redirect_to root_url, alert: "Too many requests!"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
```
|
|
171
131
|
|
|
132
|
+
*Sean Doyle*
|
|
172
133
|
|
|
173
|
-
|
|
134
|
+
* Optimize `ActionDispatch::Http::URL.build_host_url` when protocol is included in host.
|
|
174
135
|
|
|
175
|
-
|
|
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.
|
|
176
140
|
|
|
141
|
+
*Joshua Young*, *Hartley McGuire*
|
|
177
142
|
|
|
178
|
-
|
|
143
|
+
* Allow `action_controller.logger` to be disabled by setting it to `nil` or `false` instead of always defaulting to `Rails.logger`.
|
|
179
144
|
|
|
180
|
-
*
|
|
145
|
+
*Roberto Miranda*
|
|
181
146
|
|
|
147
|
+
* Remove deprecated support to a route to multiple paths.
|
|
182
148
|
|
|
183
|
-
|
|
149
|
+
*Rafael Mendonça França*
|
|
184
150
|
|
|
185
|
-
*
|
|
186
|
-
`ActionController::Parameters`.
|
|
151
|
+
* Remove deprecated support for using semicolons as a query string separator.
|
|
187
152
|
|
|
188
|
-
|
|
153
|
+
Before:
|
|
189
154
|
|
|
155
|
+
```ruby
|
|
156
|
+
ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
|
|
157
|
+
# => [["foo", "bar"], ["baz", "quux"]]
|
|
158
|
+
```
|
|
190
159
|
|
|
191
|
-
|
|
160
|
+
After:
|
|
192
161
|
|
|
193
|
-
|
|
162
|
+
```ruby
|
|
163
|
+
ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
|
|
164
|
+
# => [["foo", "bar;baz=quux"]]
|
|
165
|
+
```
|
|
194
166
|
|
|
195
|
-
|
|
196
|
-
`config.i18n.raise_on_missing_translations`. See the upgrading guide for more information.
|
|
167
|
+
*Rafael Mendonça França*
|
|
197
168
|
|
|
198
|
-
|
|
169
|
+
* Remove deprecated support to skipping over leading brackets in parameter names in the parameter parser.
|
|
199
170
|
|
|
200
|
-
|
|
171
|
+
Before:
|
|
201
172
|
|
|
202
173
|
```ruby
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails"]
|
|
174
|
+
ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "foo" => "bar" }
|
|
175
|
+
ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "foo" => { "bar" => "baz" } }
|
|
206
176
|
```
|
|
207
177
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
* Parse JSON `response.parsed_body` with `ActiveSupport::HashWithIndifferentAccess`
|
|
211
|
-
|
|
212
|
-
Integrate with Minitest's new `assert_pattern` by parsing the JSON contents
|
|
213
|
-
of `response.parsed_body` with `ActiveSupport::HashWithIndifferentAccess`, so
|
|
214
|
-
that it's pattern-matching compatible.
|
|
178
|
+
After:
|
|
215
179
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
+
```
|
|
219
184
|
|
|
220
|
-
*
|
|
185
|
+
*Rafael Mendonça França*
|
|
221
186
|
|
|
222
|
-
*
|
|
223
|
-
X_FORWARDED_HOST header when the HTTP_HOST header is being blocked.
|
|
187
|
+
* Deprecate `Rails.application.config.action_dispatch.ignore_leading_brackets`.
|
|
224
188
|
|
|
225
|
-
*
|
|
189
|
+
*Rafael Mendonça França*
|
|
226
190
|
|
|
227
|
-
*
|
|
191
|
+
* Raise `ActionController::TooManyRequests` error from `ActionController::RateLimiting`
|
|
228
192
|
|
|
229
|
-
|
|
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.
|
|
230
195
|
|
|
231
196
|
*Sean Doyle*
|
|
232
197
|
|
|
233
|
-
*
|
|
234
|
-
|
|
235
|
-
*Matija Čupić*
|
|
236
|
-
|
|
237
|
-
* `config.dom_testing_default_html_version` controls the HTML parser used by
|
|
238
|
-
`ActionDispatch::Assertions#html_document`.
|
|
239
|
-
|
|
240
|
-
The Rails 7.1 default configuration opts into the HTML5 parser when it is supported, to better
|
|
241
|
-
represent what the DOM would be in a browser user agent. Previously this test helper always used
|
|
242
|
-
Nokogiri's HTML4 parser.
|
|
243
|
-
|
|
244
|
-
*Mike Dalessio*
|
|
245
|
-
|
|
246
|
-
* Ensure an uncaught exception when rendering a Turbo Frame properly breaks
|
|
247
|
-
out of the Frame and shows the `DebugView` error page in development.
|
|
248
|
-
|
|
249
|
-
*Joé Dupuis*
|
|
250
|
-
|
|
251
|
-
* The `with_routing` helper can now be called at the class level. When called at the class level, the routes will
|
|
252
|
-
be setup before each test, and reset after every test. For example:
|
|
198
|
+
* Add .md/.markdown as Markdown extensions and add a default `markdown:` renderer:
|
|
253
199
|
|
|
254
200
|
```ruby
|
|
255
|
-
class
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
resources :articles
|
|
259
|
-
resources :authors
|
|
260
|
-
end
|
|
201
|
+
class Page
|
|
202
|
+
def to_markdown
|
|
203
|
+
body
|
|
261
204
|
end
|
|
205
|
+
end
|
|
262
206
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
207
|
+
class PagesController < ActionController::Base
|
|
208
|
+
def show
|
|
209
|
+
@page = Page.find(params[:id])
|
|
266
210
|
|
|
267
|
-
|
|
268
|
-
|
|
211
|
+
respond_to do |format|
|
|
212
|
+
format.html
|
|
213
|
+
format.md { render markdown: @page }
|
|
214
|
+
end
|
|
269
215
|
end
|
|
270
216
|
end
|
|
271
217
|
```
|
|
272
218
|
|
|
273
|
-
*
|
|
219
|
+
*DHH*
|
|
274
220
|
|
|
275
|
-
*
|
|
276
|
-
When parsing the accept header, the parameters before the q-parameter are kept and if a matching mime-type exists it is used.
|
|
277
|
-
To keep the current functionality, a fallback is created to look for the media-type without the parameters.
|
|
221
|
+
* Add headers to engine routes inspection command
|
|
278
222
|
|
|
279
|
-
|
|
223
|
+
*Petrik de Heus*
|
|
280
224
|
|
|
281
|
-
|
|
225
|
+
* Add "Copy as text" button to error pages
|
|
282
226
|
|
|
283
|
-
*
|
|
284
|
-
This is very useful in situations where you only want to add a required param that is part of the route's URL but for other route not append an extraneous query param.
|
|
227
|
+
*Mikkel Malmberg*
|
|
285
228
|
|
|
286
|
-
|
|
229
|
+
* Add `scope:` option to `rate_limit` method.
|
|
287
230
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
scope ":account_id" do
|
|
291
|
-
get "dashboard" => "pages#dashboard", as: :dashboard
|
|
292
|
-
get "search/:term" => "search#search", as: :search
|
|
293
|
-
end
|
|
294
|
-
delete "signout" => "sessions#destroy", as: :signout
|
|
295
|
-
end
|
|
296
|
-
```
|
|
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.
|
|
297
233
|
|
|
298
|
-
|
|
234
|
+
Now, the `scope:` option solves this problem.
|
|
299
235
|
|
|
300
236
|
```ruby
|
|
301
|
-
class
|
|
302
|
-
|
|
303
|
-
{ path_params: { account_id: "foo" } }
|
|
304
|
-
end
|
|
237
|
+
class APIController < ActionController::API
|
|
238
|
+
rate_limit to: 2, within: 2.seconds, scope: "api"
|
|
305
239
|
end
|
|
306
|
-
```
|
|
307
240
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
dashboard_path # => /foo/dashboard
|
|
312
|
-
dashboard_path(account_id: "bar") # => /bar/dashboard
|
|
241
|
+
class API::PostsController < APIController
|
|
242
|
+
# ...
|
|
243
|
+
end
|
|
313
244
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
search_path("quin") # => /foo/search/quin
|
|
245
|
+
class API::UsersController < APIController
|
|
246
|
+
# ...
|
|
247
|
+
end
|
|
318
248
|
```
|
|
319
249
|
|
|
320
|
-
*
|
|
250
|
+
*ArthurPV*, *Kamil Hanus*
|
|
321
251
|
|
|
322
|
-
*
|
|
323
|
-
`:none`. `:all` and `:none` behave the same as the previous `true` and
|
|
324
|
-
`false` respectively. The new `:rescuable` option will only show exceptions
|
|
325
|
-
that can be rescued (e.g. `ActiveRecord::RecordNotFound`). `:rescuable` is
|
|
326
|
-
now the default for the test environment.
|
|
252
|
+
* Add support for `rack.response_finished` callbacks in ActionDispatch::Executor.
|
|
327
253
|
|
|
328
|
-
|
|
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.
|
|
329
258
|
|
|
330
|
-
*
|
|
331
|
-
`:message_pack_allow_marshal` as serializers. These serializers require the
|
|
332
|
-
[`msgpack` gem](https://rubygems.org/gems/msgpack) (>= 1.7.0).
|
|
259
|
+
*Adrianna Chang*, *Hartley McGuire*
|
|
333
260
|
|
|
334
|
-
|
|
335
|
-
sizes. It also supports roundtripping some Ruby types that are not supported
|
|
336
|
-
by JSON. For example:
|
|
261
|
+
* Produce a log when `rescue_from` is invoked.
|
|
337
262
|
|
|
338
|
-
|
|
339
|
-
cookies.encrypted[:foo] = [{ a: 1 }, { b: 2 }.with_indifferent_access, 1.to_d, Time.at(0, 123)]
|
|
263
|
+
*Steven Webb*, *Jean Boussier*
|
|
340
264
|
|
|
341
|
-
|
|
342
|
-
cookies.encrypted[:foo]
|
|
343
|
-
# => [{"a"=>1}, {"b"=>2}, "1.0", "1969-12-31T18:00:00.000-06:00"]
|
|
344
|
-
cookies.encrypted[:foo].map(&:class)
|
|
345
|
-
# => [Hash, Hash, String, String]
|
|
265
|
+
* Allow hosts redirects from `hosts` Rails configuration
|
|
346
266
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
cookies.encrypted[:foo].map(&:class)
|
|
351
|
-
# => [Hash, ActiveSupport::HashWithIndifferentAccess, BigDecimal, Time]
|
|
352
|
-
```
|
|
267
|
+
```ruby
|
|
268
|
+
config.action_controller.allowed_redirect_hosts << "example.com"
|
|
269
|
+
```
|
|
353
270
|
|
|
354
|
-
|
|
355
|
-
`ActiveSupport::JSON` when necessary, and the `:message_pack_allow_marshal`
|
|
356
|
-
serializer can fall back to deserializing with `Marshal` as well as
|
|
357
|
-
`ActiveSupport::JSON`. Additionally, the `:marshal`, `:json`, and
|
|
358
|
-
`:json_allow_marshal` (AKA `:hybrid`) serializers can now fall back to
|
|
359
|
-
deserializing with `ActiveSupport::MessagePack` when necessary. These
|
|
360
|
-
behaviors ensure old cookies can still be read so that migration is easier.
|
|
271
|
+
*Kevin Robatel*
|
|
361
272
|
|
|
362
|
-
|
|
273
|
+
* `rate_limit.action_controller` notification has additional payload
|
|
363
274
|
|
|
364
|
-
|
|
275
|
+
additional values: count, to, within, by, name, cache_key
|
|
365
276
|
|
|
366
|
-
*
|
|
277
|
+
*Jonathan Rochkind*
|
|
367
278
|
|
|
368
|
-
*
|
|
279
|
+
* Add JSON support to the built-in health controller.
|
|
369
280
|
|
|
370
|
-
|
|
371
|
-
|
|
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.
|
|
372
284
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
Source Location | config/routes/gist.rb:3
|
|
285
|
+
```ruby
|
|
286
|
+
# /up.json
|
|
287
|
+
{
|
|
288
|
+
"status": "up",
|
|
289
|
+
"timestamp": "2025-09-19T12:00:00Z"
|
|
290
|
+
}
|
|
380
291
|
```
|
|
381
292
|
|
|
382
|
-
*
|
|
383
|
-
|
|
384
|
-
* Add `without` as an alias of `except` on `ActiveController::Parameters`.
|
|
293
|
+
*Francesco Loreti*, *Juan Vásquez*
|
|
385
294
|
|
|
386
|
-
|
|
295
|
+
* Allow to open source file with a crash from the browser.
|
|
387
296
|
|
|
388
|
-
*
|
|
297
|
+
*Igor Kasyanchuk*
|
|
389
298
|
|
|
390
|
-
|
|
299
|
+
* Always check query string keys for valid encoding just like values are checked.
|
|
391
300
|
|
|
392
|
-
*
|
|
301
|
+
*Casper Smits*
|
|
393
302
|
|
|
394
|
-
|
|
303
|
+
* Always return empty body for HEAD requests in `PublicExceptions` and
|
|
304
|
+
`DebugExceptions`.
|
|
395
305
|
|
|
396
|
-
|
|
306
|
+
This is required by `Rack::Lint` (per RFC9110).
|
|
397
307
|
|
|
398
|
-
*
|
|
399
|
-
|
|
400
|
-
* Deprecate `config.action_dispatch.return_only_request_media_type_on_content_type`.
|
|
401
|
-
|
|
402
|
-
*Rafael Mendonça França*
|
|
403
|
-
|
|
404
|
-
* Remove deprecated behavior on `Request#content_type`.
|
|
308
|
+
*Hartley McGuire*
|
|
405
309
|
|
|
406
|
-
|
|
310
|
+
* Add comprehensive support for HTTP Cache-Control request directives according to RFC 9111.
|
|
407
311
|
|
|
408
|
-
|
|
312
|
+
Provides a `request.cache_control_directives` object that gives access to request cache directives:
|
|
409
313
|
|
|
410
314
|
```ruby
|
|
411
|
-
|
|
412
|
-
request.
|
|
413
|
-
request.
|
|
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
|
|
414
330
|
```
|
|
415
331
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
* Deprecate `AbstractController::Helpers::MissingHelperError`
|
|
419
|
-
|
|
420
|
-
*Hartley McGuire*
|
|
421
|
-
|
|
422
|
-
* Change `ActionDispatch::Testing::TestResponse#parsed_body` to parse HTML as
|
|
423
|
-
a Nokogiri document
|
|
332
|
+
Example usage:
|
|
424
333
|
|
|
425
334
|
```ruby
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
* Deprecate `ActionDispatch::IllegalStateError`.
|
|
435
|
-
|
|
436
|
-
*Samuel Williams*
|
|
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
|
|
437
342
|
|
|
438
|
-
|
|
343
|
+
render :show
|
|
344
|
+
end
|
|
345
|
+
```
|
|
439
346
|
|
|
440
|
-
*
|
|
347
|
+
*egg528*
|
|
441
348
|
|
|
442
|
-
* Add
|
|
443
|
-
It makes the application believe that all requests are arriving over SSL. This is useful
|
|
444
|
-
when proxying through a load balancer that terminates SSL, the forwarded request will appear
|
|
445
|
-
as though its HTTP instead of HTTPS to the application. This makes redirects and cookie
|
|
446
|
-
security target HTTP instead of HTTPS. This middleware makes the server assume that the
|
|
447
|
-
proxy already terminated SSL, and that the request really is HTTPS.
|
|
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.
|
|
448
350
|
|
|
449
351
|
*DHH*
|
|
450
352
|
|
|
451
|
-
*
|
|
353
|
+
* Include cookie name when calculating maximum allowed size.
|
|
452
354
|
|
|
453
355
|
*Hartley McGuire*
|
|
454
356
|
|
|
455
|
-
*
|
|
456
|
-
|
|
457
|
-
When `before_action :callback, only: :action_name` is declared on a controller that doesn't respond to `action_name`, raise an exception at request time. This is a safety measure to ensure that typos or forgetfulness don't prevent a crucial callback from being run when it should.
|
|
458
|
-
|
|
459
|
-
For new applications, raising an error for undefined actions is turned on by default. If you do not want to opt-in to this behavior set `config.action_controller.raise_on_missing_callback_actions` to `false` in your application configuration. See #43487 for more details.
|
|
460
|
-
|
|
461
|
-
*Jess Bees*
|
|
462
|
-
|
|
463
|
-
* Allow cookie options[:domain] to accept a proc to set the cookie domain on a more flexible per-request basis
|
|
464
|
-
|
|
465
|
-
*RobL*
|
|
466
|
-
|
|
467
|
-
* When a host is not specified for an `ActionController::Renderer`'s env,
|
|
468
|
-
the host and related options will now be derived from the routes'
|
|
469
|
-
`default_url_options` and `ActionDispatch::Http::URL.secure_protocol`.
|
|
470
|
-
|
|
471
|
-
This means that for an application with a configuration like:
|
|
472
|
-
|
|
473
|
-
```ruby
|
|
474
|
-
Rails.application.default_url_options = { host: "rubyonrails.org" }
|
|
475
|
-
Rails.application.config.force_ssl = true
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
rendering a URL like:
|
|
479
|
-
|
|
480
|
-
```ruby
|
|
481
|
-
ApplicationController.renderer.render inline: "<%= blog_url %>"
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
will now return `"https://rubyonrails.org/blog"` instead of
|
|
485
|
-
`"http://example.org/blog"`.
|
|
486
|
-
|
|
487
|
-
*Jonathan Hefner*
|
|
488
|
-
|
|
489
|
-
* Add details of cookie name and size to `CookieOverflow` exception.
|
|
490
|
-
|
|
491
|
-
*Andy Waite*
|
|
492
|
-
|
|
493
|
-
* Don't double log the `controller`, `action`, or `namespaced_controller` when using `ActiveRecord::QueryLog`
|
|
494
|
-
|
|
495
|
-
Previously if you set `config.active_record.query_log_tags` to an array that included
|
|
496
|
-
`:controller`, `:namespaced_controller`, or `:action`, that item would get logged twice.
|
|
497
|
-
This bug has been fixed.
|
|
498
|
-
|
|
499
|
-
*Alex Ghiculescu*
|
|
500
|
-
|
|
501
|
-
* Add the following permissions policy directives: `hid`, `idle-detection`, `screen-wake-lock`,
|
|
502
|
-
`serial`, `sync-xhr`, `web-share`.
|
|
503
|
-
|
|
504
|
-
*Guillaume Cabanel*
|
|
505
|
-
|
|
506
|
-
* The `speaker`, `vibrate`, and `vr` permissions policy directives are now
|
|
507
|
-
deprecated.
|
|
508
|
-
|
|
509
|
-
There is no browser support for these directives, and no plan for browser
|
|
510
|
-
support in the future. You can just remove these directives from your
|
|
511
|
-
application.
|
|
512
|
-
|
|
513
|
-
*Jonathan Hefner*
|
|
514
|
-
|
|
515
|
-
* Added the `:status` option to `assert_redirected_to` to specify the precise
|
|
516
|
-
HTTP status of the redirect. Defaults to `:redirect` for backwards
|
|
517
|
-
compatibility.
|
|
518
|
-
|
|
519
|
-
*Jon Dufresne*
|
|
520
|
-
|
|
521
|
-
* Rescue `JSON::ParserError` in Cookies JSON deserializer to discards marshal dumps:
|
|
522
|
-
|
|
523
|
-
Without this change, if `action_dispatch.cookies_serializer` is set to `:json` and
|
|
524
|
-
the app tries to read a `:marshal` serialized cookie, it would error out which wouldn't
|
|
525
|
-
clear the cookie and force app users to manually clear it in their browser.
|
|
526
|
-
|
|
527
|
-
(See #45127 for original bug discussion)
|
|
528
|
-
|
|
529
|
-
*Nathan Bardoux*
|
|
530
|
-
|
|
531
|
-
* Add `HTTP_REFERER` when following redirects on integration tests
|
|
357
|
+
* Implement `must-understand` directive according to RFC 9111.
|
|
532
358
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
*Felipe Sateler*
|
|
536
|
-
|
|
537
|
-
* Added `exclude?` method to `ActionController::Parameters`.
|
|
538
|
-
|
|
539
|
-
*Ian Neubert*
|
|
540
|
-
|
|
541
|
-
* Rescue `EOFError` exception from `rack` on a multipart request.
|
|
542
|
-
|
|
543
|
-
*Nikita Vasilevsky*
|
|
544
|
-
|
|
545
|
-
* Log redirects from routes the same way as redirects from controllers.
|
|
546
|
-
|
|
547
|
-
*Dennis Paagman*
|
|
548
|
-
|
|
549
|
-
* Prevent `ActionDispatch::ServerTiming` from overwriting existing values in `Server-Timing`.
|
|
550
|
-
Previously, if another middleware down the chain set `Server-Timing` header,
|
|
551
|
-
it would overwritten by `ActionDispatch::ServerTiming`.
|
|
552
|
-
|
|
553
|
-
*Jakub Malinowski*
|
|
554
|
-
|
|
555
|
-
* Allow opting out of the `SameSite` cookie attribute when setting a cookie.
|
|
556
|
-
|
|
557
|
-
You can opt out of `SameSite` by passing `same_site: nil`.
|
|
558
|
-
|
|
559
|
-
`cookies[:foo] = { value: "bar", same_site: nil }`
|
|
560
|
-
|
|
561
|
-
Previously, this incorrectly set the `SameSite` attribute to the value of the `cookies_same_site_protection` setting.
|
|
562
|
-
|
|
563
|
-
*Alex Ghiculescu*
|
|
564
|
-
|
|
565
|
-
* Allow using `helper_method`s in `content_security_policy` and `permissions_policy`
|
|
566
|
-
|
|
567
|
-
Previously you could access basic helpers (defined in helper modules), but not
|
|
568
|
-
helper methods defined using `helper_method`. Now you can use either.
|
|
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.
|
|
569
360
|
|
|
570
361
|
```ruby
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
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
|
|
574
373
|
end
|
|
575
374
|
```
|
|
576
375
|
|
|
577
|
-
*
|
|
578
|
-
|
|
579
|
-
* Reimplement `ActionController::Parameters#has_value?` and `#value?` to avoid parameters and hashes comparison.
|
|
580
|
-
|
|
581
|
-
Deprecated equality between parameters and hashes is going to be removed in Rails 7.2.
|
|
582
|
-
The new implementation takes care of conversions.
|
|
583
|
-
|
|
584
|
-
*Seva Stefkin*
|
|
585
|
-
|
|
586
|
-
* Allow only String and Symbol keys in `ActionController::Parameters`.
|
|
587
|
-
Raise `ActionController::InvalidParameterKey` when initializing Parameters
|
|
588
|
-
with keys that aren't strings or symbols.
|
|
589
|
-
|
|
590
|
-
*Seva Stefkin*
|
|
591
|
-
|
|
592
|
-
* Add the ability to use custom logic for storing and retrieving CSRF tokens.
|
|
376
|
+
*heka1024*
|
|
593
377
|
|
|
594
|
-
|
|
595
|
-
defined to specify arbitrary behavior, but the ability to store them in
|
|
596
|
-
encrypted cookies is built in.
|
|
378
|
+
* The JSON renderer doesn't escape HTML entities or Unicode line separators anymore.
|
|
597
379
|
|
|
598
|
-
|
|
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.
|
|
599
382
|
|
|
600
|
-
|
|
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.
|
|
601
385
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
* Introduce `html:` and `screenshot:` kwargs for system test screenshot helper
|
|
386
|
+
Escaping will still occur when the `:callback` option is set, since the JSON is used as JavaScript code in this
|
|
387
|
+
situation (JSONP).
|
|
605
388
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
For example, this will display a screenshot in iTerm, save the HTML, and output
|
|
609
|
-
its path.
|
|
389
|
+
You can use the `:escape` option or set `config.action_controller.escape_json_responses` to `true` to restore the
|
|
390
|
+
escaping behavior.
|
|
610
391
|
|
|
611
392
|
```ruby
|
|
612
|
-
|
|
393
|
+
class PostsController < ApplicationController
|
|
394
|
+
def index
|
|
395
|
+
render json: Post.last(30), escape: true
|
|
396
|
+
end
|
|
397
|
+
end
|
|
613
398
|
```
|
|
614
399
|
|
|
615
|
-
*
|
|
616
|
-
|
|
617
|
-
* Allow `ActionController::Parameters#to_h` to receive a block.
|
|
618
|
-
|
|
619
|
-
*Bob Farrell*
|
|
400
|
+
*Étienne Barrié*, *Jean Boussier*
|
|
620
401
|
|
|
621
|
-
*
|
|
402
|
+
* Load lazy route sets before inserting test routes
|
|
622
403
|
|
|
623
|
-
|
|
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.
|
|
624
406
|
|
|
625
|
-
*
|
|
626
|
-
|
|
627
|
-
*Tim Wade*
|
|
407
|
+
*Gannon McGibbon*
|
|
628
408
|
|
|
629
|
-
*
|
|
409
|
+
* Raise `AbstractController::DoubleRenderError` if `head` is called after rendering.
|
|
630
410
|
|
|
631
|
-
|
|
411
|
+
After this change, invoking `head` will lead to an error if response body is already set:
|
|
632
412
|
|
|
633
413
|
```ruby
|
|
634
|
-
|
|
635
|
-
|
|
414
|
+
class PostController < ApplicationController
|
|
415
|
+
def index
|
|
416
|
+
render locals: {}
|
|
417
|
+
head :ok
|
|
418
|
+
end
|
|
636
419
|
end
|
|
637
420
|
```
|
|
638
421
|
|
|
639
|
-
|
|
422
|
+
*Iaroslav Kurbatov*
|
|
640
423
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
* Fix `content_security_policy` returning invalid directives.
|
|
424
|
+
* The Cookie Serializer can now serialize an Active Support SafeBuffer when using message pack.
|
|
644
425
|
|
|
645
|
-
|
|
646
|
-
single quoted when the directive was the result of calling a lambda
|
|
647
|
-
returning an array.
|
|
426
|
+
Such code would previously produce an error if an application was using messagepack as its cookie serializer.
|
|
648
427
|
|
|
649
428
|
```ruby
|
|
650
|
-
|
|
651
|
-
|
|
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
|
|
652
433
|
end
|
|
653
434
|
```
|
|
654
435
|
|
|
655
|
-
With this fix the policy generated from above will now be valid.
|
|
656
|
-
|
|
657
436
|
*Edouard Chin*
|
|
658
437
|
|
|
659
|
-
* Fix `
|
|
660
|
-
protection has not been enabled / `verify_authenticity_token` is not a
|
|
661
|
-
defined callback.
|
|
662
|
-
|
|
663
|
-
This fix prevents the Rails 7.0 Welcome Page (`/`) from raising an
|
|
664
|
-
`ArgumentError` if `default_protect_from_forgery` is false.
|
|
438
|
+
* Fix `Rails.application.reload_routes!` from clearing almost all routes.
|
|
665
439
|
|
|
666
|
-
|
|
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.
|
|
667
444
|
|
|
668
|
-
*
|
|
445
|
+
*Edouard Chin*
|
|
669
446
|
|
|
670
|
-
|
|
671
|
-
`redirect_to` can continue to do so.
|
|
447
|
+
* Add resource name to the `ArgumentError` that's raised when invalid `:only` or `:except` options are given to `#resource` or `#resources`
|
|
672
448
|
|
|
673
|
-
|
|
449
|
+
This makes it easier to locate the source of the problem, especially for routes drawn by gems.
|
|
674
450
|
|
|
675
|
-
|
|
451
|
+
Before:
|
|
452
|
+
```
|
|
453
|
+
:only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
|
|
454
|
+
```
|
|
676
455
|
|
|
677
|
-
|
|
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
|
+
```
|
|
678
460
|
|
|
679
|
-
*
|
|
461
|
+
*Jeremy Green*
|
|
680
462
|
|
|
681
|
-
*
|
|
463
|
+
* A route pointing to a non-existing controller now returns a 500 instead of a 404.
|
|
682
464
|
|
|
683
|
-
|
|
684
|
-
|
|
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.
|
|
685
468
|
|
|
686
|
-
|
|
687
|
-
`
|
|
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.
|
|
688
473
|
|
|
689
474
|
*Jean Boussier*
|
|
690
475
|
|
|
691
|
-
*
|
|
692
|
-
|
|
693
|
-
```ruby
|
|
694
|
-
get '/test' => "test#index", as: :test, trailing_slash: true
|
|
695
|
-
|
|
696
|
-
test_path() # => "/test/"
|
|
697
|
-
```
|
|
476
|
+
* Add `check_collisions` option to `ActionDispatch::Session::CacheStore`.
|
|
698
477
|
|
|
699
|
-
|
|
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.
|
|
700
483
|
|
|
701
|
-
*
|
|
484
|
+
*Shia*
|
|
702
485
|
|
|
703
|
-
|
|
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.
|
|
704
489
|
|
|
705
|
-
*
|
|
490
|
+
*Martin Emde*
|
|
706
491
|
|
|
707
|
-
*
|
|
492
|
+
* Allow setting content type with a symbol of the Mime type.
|
|
708
493
|
|
|
709
494
|
```ruby
|
|
710
495
|
# Before
|
|
711
|
-
|
|
496
|
+
response.content_type = "text/html"
|
|
712
497
|
|
|
713
498
|
# After
|
|
714
|
-
|
|
499
|
+
response.content_type = :html
|
|
715
500
|
```
|
|
716
501
|
|
|
717
|
-
*
|
|
502
|
+
*Petrik de Heus*
|
|
718
503
|
|
|
719
|
-
Please check [
|
|
504
|
+
Please check [8-0-stable](https://github.com/rails/rails/blob/8-0-stable/actionpack/CHANGELOG.md) for previous changes.
|