actionpack 7.2.3 → 8.0.4
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 +172 -119
- data/lib/abstract_controller/rendering.rb +0 -1
- data/lib/action_controller/base.rb +1 -1
- data/lib/action_controller/form_builder.rb +3 -3
- data/lib/action_controller/metal/allow_browser.rb +11 -1
- data/lib/action_controller/metal/conditional_get.rb +5 -1
- data/lib/action_controller/metal/data_streaming.rb +4 -2
- data/lib/action_controller/metal/instrumentation.rb +1 -2
- data/lib/action_controller/metal/live.rb +16 -9
- data/lib/action_controller/metal/rate_limiting.rb +13 -4
- data/lib/action_controller/metal/renderers.rb +2 -3
- data/lib/action_controller/metal/streaming.rb +5 -84
- data/lib/action_controller/metal/strong_parameters.rb +277 -89
- data/lib/action_controller/railtie.rb +1 -7
- data/lib/action_controller/test_case.rb +12 -2
- data/lib/action_dispatch/http/cache.rb +27 -10
- data/lib/action_dispatch/http/content_security_policy.rb +14 -1
- data/lib/action_dispatch/http/param_builder.rb +186 -0
- data/lib/action_dispatch/http/param_error.rb +26 -0
- data/lib/action_dispatch/http/permissions_policy.rb +2 -0
- data/lib/action_dispatch/http/query_parser.rb +53 -0
- data/lib/action_dispatch/http/request.rb +60 -16
- data/lib/action_dispatch/http/response.rb +34 -13
- data/lib/action_dispatch/journey/parser.rb +99 -196
- data/lib/action_dispatch/journey/scanner.rb +44 -42
- data/lib/action_dispatch/middleware/cookies.rb +4 -2
- data/lib/action_dispatch/middleware/debug_exceptions.rb +16 -3
- data/lib/action_dispatch/middleware/debug_view.rb +0 -5
- data/lib/action_dispatch/middleware/exception_wrapper.rb +0 -6
- data/lib/action_dispatch/middleware/request_id.rb +2 -1
- data/lib/action_dispatch/middleware/ssl.rb +13 -3
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +0 -3
- data/lib/action_dispatch/railtie.rb +8 -0
- data/lib/action_dispatch/request/session.rb +1 -0
- data/lib/action_dispatch/request/utils.rb +9 -3
- data/lib/action_dispatch/routing/inspector.rb +1 -1
- data/lib/action_dispatch/routing/mapper.rb +91 -62
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -2
- data/lib/action_dispatch/routing/route_set.rb +21 -10
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -0
- data/lib/action_dispatch/system_testing/browser.rb +12 -21
- data/lib/action_dispatch/testing/assertions/response.rb +12 -2
- data/lib/action_dispatch/testing/assertions/routing.rb +16 -12
- data/lib/action_dispatch/testing/integration.rb +14 -4
- data/lib/action_dispatch.rb +6 -4
- data/lib/action_pack/gem_version.rb +3 -3
- metadata +14 -47
- data/lib/action_dispatch/journey/parser.y +0 -50
- data/lib/action_dispatch/journey/parser_extras.rb +0 -33
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1fea6ba071295e83d6e5781df7582dfe27d5f3757183dfac91bf650b090e445e
|
|
4
|
+
data.tar.gz: ffcc0f47bbc76b7491946fbd0cf039d3d61201e9e389417dba5d6b2fd5b66a77
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 787632a979e611d3c63181e8cde8c4da8b1c7aabdcff0e8bed08bc675f0140cd0de24f8c867130e8db78512a2db2f6ad529c1fc28d5df76106c14b382e1c306a
|
|
7
|
+
data.tar.gz: 3171d0030c6cff57a0797a88d6b3250c9c074f150d2ca44b577e020d913158eaaa80fd860dd8e42982bc36b32e9aa7c7630f760ac451615358d1f6be478fd53d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
|
-
## Rails
|
|
1
|
+
## Rails 8.0.4 (October 28, 2025) ##
|
|
2
2
|
|
|
3
3
|
* Submit test requests using `as: :html` with `Content-Type: x-www-form-urlencoded`
|
|
4
4
|
|
|
5
5
|
*Sean Doyle*
|
|
6
6
|
|
|
7
|
+
|
|
8
|
+
## Rails 8.0.3 (September 22, 2025) ##
|
|
9
|
+
|
|
10
|
+
* URL helpers for engines mounted at the application root handle `SCRIPT_NAME` correctly.
|
|
11
|
+
|
|
12
|
+
Fixed an issue where `SCRIPT_NAME` is not applied to paths generated for routes in an engine
|
|
13
|
+
mounted at "/".
|
|
14
|
+
|
|
15
|
+
*Mike Dalessio*
|
|
16
|
+
|
|
17
|
+
* Fix `Rails.application.reload_routes!` from clearing almost all routes.
|
|
18
|
+
|
|
19
|
+
When calling `Rails.application.reload_routes!` inside a middleware of
|
|
20
|
+
a Rake task, it was possible under certain conditions that all routes would be cleared.
|
|
21
|
+
If ran inside a middleware, this would result in getting a 404 on most page you visit.
|
|
22
|
+
This issue was only happening in development.
|
|
23
|
+
|
|
24
|
+
*Edouard Chin*
|
|
25
|
+
|
|
7
26
|
* Address `rack 3.2` deprecations warnings.
|
|
8
27
|
|
|
9
28
|
```
|
|
@@ -11,10 +30,14 @@
|
|
|
11
30
|
Please use :unprocessable_content instead.
|
|
12
31
|
```
|
|
13
32
|
|
|
14
|
-
Rails API will transparently convert one into the other for the
|
|
33
|
+
Rails API will transparently convert one into the other for the foreseeable future.
|
|
15
34
|
|
|
16
35
|
*Earlopain*, *Jean Boussier*
|
|
17
36
|
|
|
37
|
+
* Support hash-source in Content Security Policy.
|
|
38
|
+
|
|
39
|
+
*madogiwa*
|
|
40
|
+
|
|
18
41
|
* Always return empty body for HEAD requests in `PublicExceptions` and
|
|
19
42
|
`DebugExceptions`.
|
|
20
43
|
|
|
@@ -22,218 +45,248 @@
|
|
|
22
45
|
|
|
23
46
|
*Hartley McGuire*
|
|
24
47
|
|
|
25
|
-
* Fix `url_for` to handle `:path_params` gracefully when it's not a `Hash`.
|
|
26
48
|
|
|
27
|
-
|
|
49
|
+
## Rails 8.0.2.1 (August 13, 2025) ##
|
|
28
50
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
* Fix `ActionDispatch::Executor` to unwrap exceptions like other error reporting middlewares.
|
|
51
|
+
* No changes.
|
|
32
52
|
|
|
33
|
-
|
|
53
|
+
## Rails 8.0.2 (March 12, 2025) ##
|
|
34
54
|
|
|
35
|
-
*
|
|
55
|
+
* Improve `with_routing` test helper to not rebuild the middleware stack.
|
|
36
56
|
|
|
37
|
-
|
|
57
|
+
Otherwise some middleware configuration could be lost.
|
|
38
58
|
|
|
39
|
-
*
|
|
59
|
+
*Édouard Chin*
|
|
40
60
|
|
|
41
|
-
|
|
61
|
+
* Add resource name to the `ArgumentError` that's raised when invalid `:only` or `:except` options are given to `#resource` or `#resources`
|
|
42
62
|
|
|
63
|
+
This makes it easier to locate the source of the problem, especially for routes drawn by gems.
|
|
43
64
|
|
|
44
|
-
|
|
65
|
+
Before:
|
|
66
|
+
```
|
|
67
|
+
:only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
|
|
68
|
+
```
|
|
45
69
|
|
|
46
|
-
|
|
70
|
+
After:
|
|
71
|
+
```
|
|
72
|
+
Route `resources :products` - :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
|
|
73
|
+
```
|
|
47
74
|
|
|
75
|
+
*Jeremy Green*
|
|
48
76
|
|
|
49
|
-
|
|
77
|
+
* Fix `url_for` to handle `:path_params` gracefully when it's not a `Hash`.
|
|
50
78
|
|
|
51
|
-
|
|
52
|
-
Developers should use multiple arguments, and different directive methods instead.
|
|
79
|
+
Prevents various security scanners from causing exceptions.
|
|
53
80
|
|
|
54
|
-
|
|
81
|
+
*Martin Emde*
|
|
55
82
|
|
|
56
|
-
|
|
83
|
+
* Fix `ActionDispatch::Executor` to unwrap exceptions like other error reporting middlewares.
|
|
57
84
|
|
|
85
|
+
*Jean Boussier*
|
|
58
86
|
|
|
59
|
-
## Rails 7.2.2 (October 30, 2024) ##
|
|
60
87
|
|
|
61
|
-
|
|
88
|
+
## Rails 8.0.1 (December 13, 2024) ##
|
|
62
89
|
|
|
63
|
-
|
|
90
|
+
* Add `ActionDispatch::Request::Session#store` method to conform Rack spec.
|
|
64
91
|
|
|
92
|
+
*Yaroslav*
|
|
65
93
|
|
|
66
|
-
## Rails 7.2.1.2 (October 23, 2024) ##
|
|
67
94
|
|
|
68
|
-
|
|
95
|
+
## Rails 8.0.0.1 (December 10, 2024) ##
|
|
69
96
|
|
|
97
|
+
* Add validation to content security policies to disallow spaces and semicolons.
|
|
98
|
+
Developers should use multiple arguments, and different directive methods instead.
|
|
70
99
|
|
|
71
|
-
|
|
100
|
+
[CVE-2024-54133]
|
|
72
101
|
|
|
73
|
-
*
|
|
102
|
+
*Gannon McGibbon*
|
|
74
103
|
|
|
75
|
-
[CVE-2024-47887]
|
|
76
104
|
|
|
77
|
-
|
|
105
|
+
## Rails 8.0.0 (November 07, 2024) ##
|
|
78
106
|
|
|
79
|
-
*
|
|
107
|
+
* No changes.
|
|
80
108
|
|
|
81
|
-
[CVE-2024-41128]
|
|
82
109
|
|
|
83
|
-
|
|
110
|
+
## Rails 8.0.0.rc2 (October 30, 2024) ##
|
|
84
111
|
|
|
112
|
+
* Fix routes with `::` in the path.
|
|
85
113
|
|
|
86
|
-
|
|
114
|
+
*Rafael Mendonça França*
|
|
87
115
|
|
|
88
|
-
*
|
|
116
|
+
* Maintain Rack 2 parameter parsing behaviour.
|
|
89
117
|
|
|
90
|
-
*
|
|
118
|
+
*Matthew Draper*
|
|
91
119
|
|
|
92
120
|
|
|
93
|
-
## Rails
|
|
121
|
+
## Rails 8.0.0.rc1 (October 19, 2024) ##
|
|
94
122
|
|
|
95
|
-
*
|
|
123
|
+
* Remove `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality`.
|
|
96
124
|
|
|
97
|
-
*
|
|
125
|
+
*Rafael Mendonça França*
|
|
98
126
|
|
|
99
|
-
*
|
|
100
|
-
[CVE-2024-28103]
|
|
127
|
+
* Improve `ActionController::TestCase` to expose a binary encoded `request.body`.
|
|
101
128
|
|
|
102
|
-
|
|
129
|
+
The rack spec clearly states:
|
|
103
130
|
|
|
104
|
-
|
|
131
|
+
> The input stream is an IO-like object which contains the raw HTTP POST data.
|
|
132
|
+
> When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode.
|
|
105
133
|
|
|
106
|
-
|
|
134
|
+
Until now its encoding was generally UTF-8, which doesn't accurately reflect production
|
|
135
|
+
behavior.
|
|
107
136
|
|
|
108
|
-
*
|
|
109
|
-
suggested correct location for the missing template.
|
|
137
|
+
*Jean Boussier*
|
|
110
138
|
|
|
111
|
-
|
|
139
|
+
* Update `ActionController::AllowBrowser` to support passing method names to `:block`
|
|
112
140
|
|
|
113
|
-
|
|
141
|
+
```ruby
|
|
142
|
+
class ApplicationController < ActionController::Base
|
|
143
|
+
allow_browser versions: :modern, block: :handle_outdated_browser
|
|
114
144
|
|
|
115
|
-
|
|
116
|
-
|
|
145
|
+
private
|
|
146
|
+
def handle_outdated_browser
|
|
147
|
+
render file: Rails.root.join("public/custom-error.html"), status: :not_acceptable
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
```
|
|
117
151
|
|
|
118
|
-
*
|
|
152
|
+
*Sean Doyle*
|
|
119
153
|
|
|
120
|
-
*
|
|
154
|
+
* Raise an `ArgumentError` when invalid `:only` or `:except` options are passed into `#resource` and `#resources`.
|
|
121
155
|
|
|
122
|
-
|
|
123
|
-
Rails.application.routes.draw do
|
|
124
|
-
controller :home do
|
|
125
|
-
get "recent", to: "recent_posts"
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
```
|
|
156
|
+
*Joshua Young*
|
|
129
157
|
|
|
130
|
-
|
|
158
|
+
## Rails 8.0.0.beta1 (September 26, 2024) ##
|
|
131
159
|
|
|
132
|
-
*
|
|
160
|
+
* Fix non-GET requests not updating cookies in `ActionController::TestCase`.
|
|
133
161
|
|
|
134
|
-
*
|
|
162
|
+
*Jon Moss*, *Hartley McGuire*
|
|
135
163
|
|
|
136
|
-
*
|
|
164
|
+
* Update `ActionController::Live` to use a thread-pool to reuse threads across requests.
|
|
137
165
|
|
|
138
|
-
*
|
|
166
|
+
*Adam Renberg Tamm*
|
|
139
167
|
|
|
140
|
-
*
|
|
168
|
+
* Introduce safer, more explicit params handling method with `params#expect` such that
|
|
169
|
+
`params.expect(table: [ :attr ])` replaces `params.require(:table).permit(:attr)`
|
|
141
170
|
|
|
142
|
-
|
|
171
|
+
Ensures params are filtered with consideration for the expected
|
|
172
|
+
types of values, improving handling of params and avoiding ignorable
|
|
173
|
+
errors caused by params tampering.
|
|
143
174
|
|
|
144
175
|
```ruby
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
176
|
+
# If the url is altered to ?person=hacked
|
|
177
|
+
# Before
|
|
178
|
+
params.require(:person).permit(:name, :age, pets: [:name])
|
|
179
|
+
# raises NoMethodError, causing a 500 and potential error reporting
|
|
180
|
+
|
|
181
|
+
# After
|
|
182
|
+
params.expect(person: [ :name, :age, pets: [[:name]] ])
|
|
183
|
+
# raises ActionController::ParameterMissing, correctly returning a 400 error
|
|
184
|
+
```
|
|
149
185
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
186
|
+
You may also notice the new double array `[[:name]]`. In order to
|
|
187
|
+
declare when a param is expected to be an array of parameter hashes,
|
|
188
|
+
this new double array syntax is used to explicitly declare an array.
|
|
189
|
+
`expect` requires you to declare expected arrays in this way, and will
|
|
190
|
+
ignore arrays that are passed when, for example, `pet: [:name]` is used.
|
|
154
191
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
end
|
|
159
|
-
```
|
|
192
|
+
In order to preserve compatibility, `permit` does not adopt the new
|
|
193
|
+
double array syntax and is therefore more permissive about unexpected
|
|
194
|
+
types. Using `expect` everywhere is recommended.
|
|
160
195
|
|
|
161
|
-
|
|
196
|
+
We suggest replacing `params.require(:person).permit(:name, :age)`
|
|
197
|
+
with the direct replacement `params.expect(person: [:name, :age])`
|
|
198
|
+
to prevent external users from manipulating params to trigger 500
|
|
199
|
+
errors. A 400 error will be returned instead, using public/400.html
|
|
162
200
|
|
|
163
|
-
|
|
201
|
+
Usage of `params.require(:id)` should likewise be replaced with
|
|
202
|
+
`params.expect(:id)` which is designed to ensure that `params[:id]`
|
|
203
|
+
is a scalar and not an array or hash, also requiring the param.
|
|
164
204
|
|
|
165
205
|
```ruby
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
end
|
|
206
|
+
# Before
|
|
207
|
+
User.find(params.require(:id)) # allows an array, altering behavior
|
|
169
208
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
by: -> { request.domain }, with: -> { redirect_to busy_controller_url, alert: "Too many signups!" }, only: :new
|
|
173
|
-
end
|
|
209
|
+
# After
|
|
210
|
+
User.find(params.expect(:id)) # expect only returns non-blank permitted scalars (excludes Hash, Array, nil, "", etc)
|
|
174
211
|
```
|
|
175
212
|
|
|
176
|
-
*
|
|
213
|
+
*Martin Emde*
|
|
177
214
|
|
|
178
|
-
*
|
|
215
|
+
* System Testing: Disable Chrome's search engine choice by default in system tests.
|
|
179
216
|
|
|
180
|
-
*
|
|
217
|
+
*glaszig*
|
|
181
218
|
|
|
182
|
-
*
|
|
219
|
+
* Fix `Request#raw_post` raising `NoMethodError` when `rack.input` is `nil`.
|
|
220
|
+
|
|
221
|
+
*Hartley McGuire*
|
|
183
222
|
|
|
184
|
-
|
|
223
|
+
* Remove `racc` dependency by manually writing `ActionDispatch::Journey::Scanner`.
|
|
185
224
|
|
|
186
|
-
*
|
|
225
|
+
*Gannon McGibbon*
|
|
187
226
|
|
|
188
|
-
*
|
|
227
|
+
* Speed up `ActionDispatch::Routing::Mapper::Scope#[]` by merging frame hashes.
|
|
189
228
|
|
|
190
229
|
*Gannon McGibbon*
|
|
191
230
|
|
|
192
|
-
*
|
|
231
|
+
* Allow bots to ignore `allow_browser`.
|
|
193
232
|
|
|
194
|
-
*
|
|
233
|
+
*Matthew Nguyen*
|
|
195
234
|
|
|
196
|
-
*
|
|
235
|
+
* Deprecate drawing routes with multiple paths to make routing faster.
|
|
236
|
+
You may use `with_options` or a loop to make drawing multiple paths easier.
|
|
197
237
|
|
|
198
|
-
|
|
238
|
+
```ruby
|
|
239
|
+
# Before
|
|
240
|
+
get "/users", "/other_path", to: "users#index"
|
|
199
241
|
|
|
200
|
-
|
|
242
|
+
# After
|
|
243
|
+
get "/users", to: "users#index"
|
|
244
|
+
get "/other_path", to: "users#index"
|
|
245
|
+
```
|
|
201
246
|
|
|
202
|
-
*
|
|
247
|
+
*Gannon McGibbon*
|
|
203
248
|
|
|
204
|
-
*
|
|
249
|
+
* Make `http_cache_forever` use `immutable: true`
|
|
205
250
|
|
|
206
|
-
*
|
|
251
|
+
*Nate Matykiewicz*
|
|
207
252
|
|
|
208
|
-
*
|
|
253
|
+
* Add `config.action_dispatch.strict_freshness`.
|
|
209
254
|
|
|
210
|
-
|
|
255
|
+
When set to `true`, the `ETag` header takes precedence over the `Last-Modified` header when both are present,
|
|
256
|
+
as specified by RFC 7232, Section 6.
|
|
211
257
|
|
|
212
|
-
|
|
258
|
+
Defaults to `false` to maintain compatibility with previous versions of Rails, but is enabled as part of
|
|
259
|
+
Rails 8.0 defaults.
|
|
213
260
|
|
|
214
|
-
*
|
|
261
|
+
*heka1024*
|
|
215
262
|
|
|
216
|
-
*
|
|
217
|
-
error with parallel system tests.
|
|
263
|
+
* Support `immutable` directive in Cache-Control
|
|
218
264
|
|
|
219
|
-
|
|
265
|
+
```ruby
|
|
266
|
+
expires_in 1.minute, public: true, immutable: true
|
|
267
|
+
# Cache-Control: public, max-age=60, immutable
|
|
268
|
+
```
|
|
220
269
|
|
|
221
|
-
*
|
|
270
|
+
*heka1024*
|
|
222
271
|
|
|
223
|
-
|
|
224
|
-
* Remove deprecated constant `ActionDispatch::IllegalStateError`.
|
|
272
|
+
* Add `:wasm_unsafe_eval` mapping for `content_security_policy`
|
|
225
273
|
|
|
226
|
-
|
|
274
|
+
```ruby
|
|
275
|
+
# Before
|
|
276
|
+
policy.script_src "'wasm-unsafe-eval'"
|
|
277
|
+
|
|
278
|
+
# After
|
|
279
|
+
policy.script_src :wasm_unsafe_eval
|
|
280
|
+
```
|
|
227
281
|
|
|
228
|
-
*
|
|
282
|
+
*Joe Haig*
|
|
229
283
|
|
|
230
|
-
|
|
231
|
-
The result would be like this:
|
|
284
|
+
* Add `display_capture` and `keyboard_map` in `permissions_policy`
|
|
232
285
|
|
|
233
|
-
|
|
286
|
+
*Cyril Blaecke*
|
|
234
287
|
|
|
235
|
-
|
|
288
|
+
* Add `connect` route helper.
|
|
236
289
|
|
|
237
|
-
*
|
|
290
|
+
*Samuel Williams*
|
|
238
291
|
|
|
239
|
-
Please check [7-
|
|
292
|
+
Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/actionpack/CHANGELOG.md) for previous changes.
|
|
@@ -266,7 +266,7 @@ module ActionController
|
|
|
266
266
|
ParamsWrapper
|
|
267
267
|
]
|
|
268
268
|
|
|
269
|
-
# Note: Documenting these severely
|
|
269
|
+
# Note: Documenting these severely degrades the performance of rdoc
|
|
270
270
|
# :stopdoc:
|
|
271
271
|
include AbstractController::Rendering
|
|
272
272
|
include AbstractController::Translation
|
|
@@ -22,10 +22,10 @@ module ActionController
|
|
|
22
22
|
# default_form_builder AdminFormBuilder
|
|
23
23
|
# end
|
|
24
24
|
#
|
|
25
|
-
# Then in the view any form using `form_for` will be an
|
|
26
|
-
# specified form builder:
|
|
25
|
+
# Then in the view any form using `form_with` or `form_for` will be an
|
|
26
|
+
# instance of the specified form builder:
|
|
27
27
|
#
|
|
28
|
-
# <%=
|
|
28
|
+
# <%= form_with(model: @instance) do |builder| %>
|
|
29
29
|
# <%= builder.special_field(:name) %>
|
|
30
30
|
# <% end %>
|
|
31
31
|
module FormBuilder
|
|
@@ -36,6 +36,16 @@ module ActionController # :nodoc:
|
|
|
36
36
|
# end
|
|
37
37
|
#
|
|
38
38
|
# class ApplicationController < ActionController::Base
|
|
39
|
+
# # Allow only browsers natively supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has
|
|
40
|
+
# allow_browser versions: :modern, block: :handle_outdated_browser
|
|
41
|
+
#
|
|
42
|
+
# private
|
|
43
|
+
# def handle_outdated_browser
|
|
44
|
+
# render file: Rails.root.join("public/custom-error.html"), status: :not_acceptable
|
|
45
|
+
# end
|
|
46
|
+
# end
|
|
47
|
+
#
|
|
48
|
+
# class ApplicationController < ActionController::Base
|
|
39
49
|
# # All versions of Chrome and Opera will be allowed, but no versions of "internet explorer" (ie). Safari needs to be 16.4+ and Firefox 121+.
|
|
40
50
|
# allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
|
|
41
51
|
# end
|
|
@@ -55,7 +65,7 @@ module ActionController # :nodoc:
|
|
|
55
65
|
|
|
56
66
|
if BrowserBlocker.new(request, versions: versions).blocked?
|
|
57
67
|
ActiveSupport::Notifications.instrument("browser_block.action_controller", request: request, versions: versions) do
|
|
58
|
-
instance_exec(&block)
|
|
68
|
+
block.is_a?(Symbol) ? send(block) : instance_exec(&block)
|
|
59
69
|
end
|
|
60
70
|
end
|
|
61
71
|
end
|
|
@@ -259,6 +259,9 @@ module ActionController
|
|
|
259
259
|
# `:stale_if_error`
|
|
260
260
|
# : Sets the value of the `stale-if-error` directive.
|
|
261
261
|
#
|
|
262
|
+
# `:immutable`
|
|
263
|
+
# : If true, adds the `immutable` directive.
|
|
264
|
+
#
|
|
262
265
|
#
|
|
263
266
|
# Any additional key-value pairs are concatenated as directives. For a list of
|
|
264
267
|
# supported `Cache-Control` directives, see the [article on
|
|
@@ -292,6 +295,7 @@ module ActionController
|
|
|
292
295
|
must_revalidate: options.delete(:must_revalidate),
|
|
293
296
|
stale_while_revalidate: options.delete(:stale_while_revalidate),
|
|
294
297
|
stale_if_error: options.delete(:stale_if_error),
|
|
298
|
+
immutable: options.delete(:immutable),
|
|
295
299
|
)
|
|
296
300
|
options.delete(:private)
|
|
297
301
|
|
|
@@ -315,7 +319,7 @@ module ActionController
|
|
|
315
319
|
# user's web browser. To allow proxies to cache the response, set `true` to
|
|
316
320
|
# indicate that they can serve the cached response to all users.
|
|
317
321
|
def http_cache_forever(public: false)
|
|
318
|
-
expires_in 100.years, public: public
|
|
322
|
+
expires_in 100.years, public: public, immutable: true
|
|
319
323
|
|
|
320
324
|
yield if stale?(etag: request.fullpath,
|
|
321
325
|
last_modified: Time.new(2011, 1, 1).utc,
|
|
@@ -28,7 +28,8 @@ module ActionController # :nodoc:
|
|
|
28
28
|
# `send_file(params[:path])` allows a malicious user to download any file on
|
|
29
29
|
# your server.
|
|
30
30
|
#
|
|
31
|
-
# Options:
|
|
31
|
+
# #### Options:
|
|
32
|
+
#
|
|
32
33
|
# * `:filename` - suggests a filename for the browser to use. Defaults to
|
|
33
34
|
# `File.basename(path)`.
|
|
34
35
|
# * `:type` - specifies an HTTP content type. You can specify either a string
|
|
@@ -90,7 +91,8 @@ module ActionController # :nodoc:
|
|
|
90
91
|
# inline data. You may also set the content type, the file name, and other
|
|
91
92
|
# things.
|
|
92
93
|
#
|
|
93
|
-
# Options:
|
|
94
|
+
# #### Options:
|
|
95
|
+
#
|
|
94
96
|
# * `:filename` - suggests a filename for the browser to use.
|
|
95
97
|
# * `:type` - specifies an HTTP content type. Defaults to
|
|
96
98
|
# `application/octet-stream`. You can specify either a string or a symbol
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
# :markup: markdown
|
|
4
4
|
|
|
5
|
-
require "benchmark"
|
|
6
5
|
require "abstract_controller/logger"
|
|
7
6
|
|
|
8
7
|
module ActionController
|
|
@@ -29,7 +28,7 @@ module ActionController
|
|
|
29
28
|
def render(*)
|
|
30
29
|
render_output = nil
|
|
31
30
|
self.view_runtime = cleanup_view_runtime do
|
|
32
|
-
Benchmark.
|
|
31
|
+
ActiveSupport::Benchmark.realtime(:float_millisecond) { render_output = super }
|
|
33
32
|
end
|
|
34
33
|
render_output
|
|
35
34
|
end
|
|
@@ -171,12 +171,6 @@ module ActionController
|
|
|
171
171
|
@ignore_disconnect = false
|
|
172
172
|
end
|
|
173
173
|
|
|
174
|
-
# ActionDispatch::Response delegates #to_ary to the internal
|
|
175
|
-
# ActionDispatch::Response::Buffer, defining #to_ary is an indicator that the
|
|
176
|
-
# response body can be buffered and/or cached by Rack middlewares, this is not
|
|
177
|
-
# the case for Live responses so we undefine it for this Buffer subclass.
|
|
178
|
-
undef_method :to_ary
|
|
179
|
-
|
|
180
174
|
def write(string)
|
|
181
175
|
unless @response.committed?
|
|
182
176
|
@response.headers["Cache-Control"] ||= "no-cache"
|
|
@@ -307,6 +301,9 @@ module ActionController
|
|
|
307
301
|
error = e
|
|
308
302
|
end
|
|
309
303
|
ensure
|
|
304
|
+
ActiveSupport::IsolatedExecutionState.clear
|
|
305
|
+
clean_up_thread_locals(locals, t2)
|
|
306
|
+
|
|
310
307
|
@_response.commit!
|
|
311
308
|
end
|
|
312
309
|
end
|
|
@@ -328,7 +325,8 @@ module ActionController
|
|
|
328
325
|
# or other running data where you don't want the entire file buffered in memory
|
|
329
326
|
# first. Similar to send_data, but where the data is generated live.
|
|
330
327
|
#
|
|
331
|
-
# Options:
|
|
328
|
+
# #### Options:
|
|
329
|
+
#
|
|
332
330
|
# * `:filename` - suggests a filename for the browser to use.
|
|
333
331
|
# * `:type` - specifies an HTTP content type. You can specify either a string
|
|
334
332
|
# or a symbol for a registered type with `Mime::Type.register`, for example
|
|
@@ -371,11 +369,20 @@ module ActionController
|
|
|
371
369
|
# data from the response bodies. Nobody should call this method except in Rails
|
|
372
370
|
# internals. Seriously!
|
|
373
371
|
def new_controller_thread # :nodoc:
|
|
374
|
-
|
|
372
|
+
ActionController::Live.live_thread_pool_executor.post do
|
|
375
373
|
t2 = Thread.current
|
|
376
374
|
t2.abort_on_exception = true
|
|
377
375
|
yield
|
|
378
|
-
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# Ensure we clean up any thread locals we copied so that the thread can reused.
|
|
380
|
+
def clean_up_thread_locals(locals, thread) # :nodoc:
|
|
381
|
+
locals.each { |k, _| thread[k] = nil }
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def self.live_thread_pool_executor
|
|
385
|
+
@live_thread_pool_executor ||= Concurrent::CachedThreadPool.new(name: "action_controller.live")
|
|
379
386
|
end
|
|
380
387
|
|
|
381
388
|
def log_error(exception)
|
|
@@ -29,6 +29,9 @@ module ActionController # :nodoc:
|
|
|
29
29
|
# datastore as your general caches, you can pass a custom store in the `store`
|
|
30
30
|
# parameter.
|
|
31
31
|
#
|
|
32
|
+
# If you want to use multiple rate limits per controller, you need to give each of
|
|
33
|
+
# them an explicit name via the `name:` option.
|
|
34
|
+
#
|
|
32
35
|
# Examples:
|
|
33
36
|
#
|
|
34
37
|
# class SessionsController < ApplicationController
|
|
@@ -44,14 +47,20 @@ module ActionController # :nodoc:
|
|
|
44
47
|
# RATE_LIMIT_STORE = ActiveSupport::Cache::RedisCacheStore.new(url: ENV["REDIS_URL"])
|
|
45
48
|
# rate_limit to: 10, within: 3.minutes, store: RATE_LIMIT_STORE
|
|
46
49
|
# end
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
#
|
|
51
|
+
# class SessionsController < ApplicationController
|
|
52
|
+
# rate_limit to: 3, within: 2.seconds, name: "short-term"
|
|
53
|
+
# rate_limit to: 10, within: 5.minutes, name: "long-term"
|
|
54
|
+
# end
|
|
55
|
+
def rate_limit(to:, within:, by: -> { request.remote_ip }, with: -> { head :too_many_requests }, store: cache_store, name: nil, **options)
|
|
56
|
+
before_action -> { rate_limiting(to: to, within: within, by: by, with: with, store: store, name: name) }, **options
|
|
49
57
|
end
|
|
50
58
|
end
|
|
51
59
|
|
|
52
60
|
private
|
|
53
|
-
def rate_limiting(to:, within:, by:, with:, store:)
|
|
54
|
-
|
|
61
|
+
def rate_limiting(to:, within:, by:, with:, store:, name:)
|
|
62
|
+
cache_key = ["rate-limit", controller_path, name, instance_exec(&by)].compact.join(":")
|
|
63
|
+
count = store.increment(cache_key, 1, expires_in: within)
|
|
55
64
|
if count && count > to
|
|
56
65
|
ActiveSupport::Notifications.instrument("rate_limit.action_controller", request: request) do
|
|
57
66
|
instance_exec(&with)
|