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