actionpack 8.0.0.beta1 → 8.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/lib/abstract_controller/helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +0 -1
- data/lib/action_controller/form_builder.rb +3 -3
- data/lib/action_controller/metal/allow_browser.rb +12 -2
- data/lib/action_controller/metal/rate_limiting.rb +1 -1
- data/lib/action_controller/metal/renderers.rb +0 -2
- data/lib/action_controller/metal/strong_parameters.rb +0 -15
- data/lib/action_controller/railtie.rb +0 -6
- data/lib/action_controller/test_case.rb +2 -2
- data/lib/action_dispatch/http/content_security_policy.rb +4 -8
- data/lib/action_dispatch/http/param_builder.rb +163 -0
- data/lib/action_dispatch/http/param_error.rb +26 -0
- data/lib/action_dispatch/http/query_parser.rb +31 -0
- data/lib/action_dispatch/http/request.rb +56 -14
- 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/templates/rescues/_source.html.erb +0 -3
- data/lib/action_dispatch/request/utils.rb +9 -3
- data/lib/action_dispatch/routing/mapper.rb +65 -45
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -2
- data/lib/action_dispatch/routing/route_set.rb +2 -2
- data/lib/action_dispatch/testing/assertions/response.rb +12 -2
- data/lib/action_dispatch/testing/assertions/routing.rb +4 -4
- data/lib/action_dispatch/testing/integration.rb +11 -1
- data/lib/action_dispatch.rb +6 -0
- data/lib/action_pack/gem_version.rb +1 -1
- metadata +14 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbf30070e8c7658bcda189e9c07184b10bfdeb1ae28ae9b7c6e354189e96eac6
|
4
|
+
data.tar.gz: c21576442cf2c2e3ef1cf7e36f5e412349b6f933c651cca641a9afe48229cd96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d09731d99912ded6338f7a0fcc0d98706efbf4721f26d35edcede064e240d607f6ddc5ed43a979ebe3c8d6c1e9b90347d84725c6b504c91c79fb9821edca478
|
7
|
+
data.tar.gz: 5b981e0db05e7d35cda56797acbf513050fd099bb3778ec2247012e1a338dec2b1fe608a6653a4dbe54c621de63f576588b98b8d77b172f9456b78e2e9a7cd9b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,40 @@
|
|
1
|
+
## Rails 8.0.0.rc1 (October 19, 2024) ##
|
2
|
+
|
3
|
+
* Remove `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality`.
|
4
|
+
|
5
|
+
*Rafael Mendonça França*
|
6
|
+
|
7
|
+
* Improve `ActionController::TestCase` to expose a binary encoded `request.body`.
|
8
|
+
|
9
|
+
The rack spec clearly states:
|
10
|
+
|
11
|
+
> The input stream is an IO-like object which contains the raw HTTP POST data.
|
12
|
+
> When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode.
|
13
|
+
|
14
|
+
Until now its encoding was generally UTF-8, which doesn't accurately reflect production
|
15
|
+
behavior.
|
16
|
+
|
17
|
+
*Jean Boussier*
|
18
|
+
|
19
|
+
* Update `ActionController::AllowBrowser` to support passing method names to `:block`
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
class ApplicationController < ActionController::Base
|
23
|
+
allow_browser versions: :modern, block: :handle_outdated_browser
|
24
|
+
|
25
|
+
private
|
26
|
+
def handle_outdated_browser
|
27
|
+
render file: Rails.root.join("public/custom-error.html"), status: :not_acceptable
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
*Sean Doyle*
|
33
|
+
|
34
|
+
* Raise an `ArgumentError` when invalid `:only` or `:except` options are passed into `#resource` and `#resources`.
|
35
|
+
|
36
|
+
*Joshua Young*
|
37
|
+
|
1
38
|
## Rails 8.0.0.beta1 (September 26, 2024) ##
|
2
39
|
|
3
40
|
* Fix non-GET requests not updating cookies in `ActionController::TestCase`.
|
@@ -104,6 +104,7 @@ module AbstractController
|
|
104
104
|
# Declare a controller method as a helper. For example, the following
|
105
105
|
# makes the `current_user` and `logged_in?` controller methods available
|
106
106
|
# to the view:
|
107
|
+
#
|
107
108
|
# class ApplicationController < ActionController::Base
|
108
109
|
# helper_method :current_user, :logged_in?
|
109
110
|
#
|
@@ -118,6 +119,7 @@ module AbstractController
|
|
118
119
|
# end
|
119
120
|
#
|
120
121
|
# In a view:
|
122
|
+
#
|
121
123
|
# <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
|
122
124
|
#
|
123
125
|
# #### Parameters
|
@@ -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,12 +65,12 @@ 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
|
62
72
|
|
63
|
-
class BrowserBlocker
|
73
|
+
class BrowserBlocker # :nodoc:
|
64
74
|
SETS = {
|
65
75
|
modern: { safari: 17.2, chrome: 120, firefox: 121, opera: 106, ie: false }
|
66
76
|
}
|
@@ -30,7 +30,7 @@ module ActionController # :nodoc:
|
|
30
30
|
# parameter.
|
31
31
|
#
|
32
32
|
# If you want to use multiple rate limits per controller, you need to give each of
|
33
|
-
# them
|
33
|
+
# them an explicit name via the `name:` option.
|
34
34
|
#
|
35
35
|
# Examples:
|
36
36
|
#
|
@@ -10,7 +10,6 @@ require "active_support/deep_mergeable"
|
|
10
10
|
require "action_dispatch/http/upload"
|
11
11
|
require "rack/test"
|
12
12
|
require "stringio"
|
13
|
-
require "set"
|
14
13
|
require "yaml"
|
15
14
|
|
16
15
|
module ActionController
|
@@ -262,20 +261,6 @@ module ActionController
|
|
262
261
|
cattr_accessor :always_permitted_parameters, default: %w( controller action )
|
263
262
|
|
264
263
|
class << self
|
265
|
-
def allow_deprecated_parameters_hash_equality
|
266
|
-
ActionController.deprecator.warn <<-WARNING.squish
|
267
|
-
`Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality` is
|
268
|
-
deprecated and will be removed in Rails 8.0.
|
269
|
-
WARNING
|
270
|
-
end
|
271
|
-
|
272
|
-
def allow_deprecated_parameters_hash_equality=(value)
|
273
|
-
ActionController.deprecator.warn <<-WARNING.squish
|
274
|
-
`Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality`
|
275
|
-
is deprecated and will be removed in Rails 8.0.
|
276
|
-
WARNING
|
277
|
-
end
|
278
|
-
|
279
264
|
def nested_attribute?(key, value) # :nodoc:
|
280
265
|
/\A-?\d+\z/.match?(key) && (value.is_a?(Hash) || value.is_a?(Parameters))
|
281
266
|
end
|
@@ -48,11 +48,6 @@ module ActionController
|
|
48
48
|
end
|
49
49
|
|
50
50
|
ActionController::Parameters.action_on_unpermitted_parameters = action_on_unpermitted_parameters
|
51
|
-
|
52
|
-
unless options.allow_deprecated_parameters_hash_equality.nil?
|
53
|
-
ActionController::Parameters.allow_deprecated_parameters_hash_equality =
|
54
|
-
options.allow_deprecated_parameters_hash_equality
|
55
|
-
end
|
56
51
|
end
|
57
52
|
end
|
58
53
|
|
@@ -85,7 +80,6 @@ module ActionController
|
|
85
80
|
:action_on_unpermitted_parameters,
|
86
81
|
:always_permitted_parameters,
|
87
82
|
:wrap_parameters_by_default,
|
88
|
-
:allow_deprecated_parameters_hash_equality
|
89
83
|
)
|
90
84
|
|
91
85
|
filtered_options.each do |k, v|
|
@@ -108,7 +108,7 @@ module ActionController
|
|
108
108
|
set_header k, "application/x-www-form-urlencoded"
|
109
109
|
end
|
110
110
|
|
111
|
-
case content_mime_type
|
111
|
+
case content_mime_type&.to_sym
|
112
112
|
when nil
|
113
113
|
raise "Unknown Content-Type: #{content_type}"
|
114
114
|
when :json
|
@@ -123,7 +123,7 @@ module ActionController
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
-
data_stream = StringIO.new(data)
|
126
|
+
data_stream = StringIO.new(data.b)
|
127
127
|
set_header "CONTENT_LENGTH", data_stream.length.to_s
|
128
128
|
set_header "rack.input", data_stream
|
129
129
|
end
|
@@ -8,8 +8,7 @@ require "active_support/core_ext/array/wrap"
|
|
8
8
|
module ActionDispatch # :nodoc:
|
9
9
|
# # Action Dispatch Content Security Policy
|
10
10
|
#
|
11
|
-
# Configures the HTTP [Content-Security-Policy]
|
12
|
-
# (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
|
11
|
+
# Configures the HTTP [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
|
13
12
|
# response header to help protect against XSS and
|
14
13
|
# injection attacks.
|
15
14
|
#
|
@@ -227,8 +226,7 @@ module ActionDispatch # :nodoc:
|
|
227
226
|
end
|
228
227
|
end
|
229
228
|
|
230
|
-
# Enable the [report-uri]
|
231
|
-
# (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri)
|
229
|
+
# Enable the [report-uri](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri)
|
232
230
|
# directive. Violation reports will be sent to the
|
233
231
|
# specified URI:
|
234
232
|
#
|
@@ -238,8 +236,7 @@ module ActionDispatch # :nodoc:
|
|
238
236
|
@directives["report-uri"] = [uri]
|
239
237
|
end
|
240
238
|
|
241
|
-
# Specify asset types for which [Subresource Integrity]
|
242
|
-
# (https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) is required:
|
239
|
+
# Specify asset types for which [Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) is required:
|
243
240
|
#
|
244
241
|
# policy.require_sri_for :script, :style
|
245
242
|
#
|
@@ -255,8 +252,7 @@ module ActionDispatch # :nodoc:
|
|
255
252
|
end
|
256
253
|
end
|
257
254
|
|
258
|
-
# Specify whether a [sandbox]
|
259
|
-
# (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox)
|
255
|
+
# Specify whether a [sandbox](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox)
|
260
256
|
# should be enabled for the requested resource:
|
261
257
|
#
|
262
258
|
# policy.sandbox
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionDispatch
|
4
|
+
class ParamBuilder
|
5
|
+
def self.make_default(param_depth_limit)
|
6
|
+
new param_depth_limit
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :param_depth_limit
|
10
|
+
|
11
|
+
def initialize(param_depth_limit)
|
12
|
+
@param_depth_limit = param_depth_limit
|
13
|
+
end
|
14
|
+
|
15
|
+
cattr_accessor :default
|
16
|
+
self.default = make_default(100)
|
17
|
+
|
18
|
+
class << self
|
19
|
+
delegate :from_query_string, :from_pairs, :from_hash, to: :default
|
20
|
+
end
|
21
|
+
|
22
|
+
def from_query_string(qs, separator: nil, encoding_template: nil)
|
23
|
+
from_pairs QueryParser.each_pair(qs, separator), encoding_template: encoding_template
|
24
|
+
end
|
25
|
+
|
26
|
+
def from_pairs(pairs, encoding_template: nil)
|
27
|
+
params = make_params
|
28
|
+
|
29
|
+
pairs.each do |k, v|
|
30
|
+
if Hash === v
|
31
|
+
v = ActionDispatch::Http::UploadedFile.new(v)
|
32
|
+
end
|
33
|
+
|
34
|
+
store_nested_param(params, k, v, 0, encoding_template)
|
35
|
+
end
|
36
|
+
|
37
|
+
params
|
38
|
+
rescue ArgumentError => e
|
39
|
+
raise InvalidParameterError, e.message, e.backtrace
|
40
|
+
end
|
41
|
+
|
42
|
+
def from_hash(hash, encoding_template: nil)
|
43
|
+
# Force encodings from encoding template
|
44
|
+
hash = Request::Utils::CustomParamEncoder.encode_for_template(hash, encoding_template)
|
45
|
+
|
46
|
+
# Assert valid encoding
|
47
|
+
Request::Utils.check_param_encoding(hash)
|
48
|
+
|
49
|
+
# Convert hashes to HWIA (or UploadedFile), and deep-munge nils
|
50
|
+
# out of arrays
|
51
|
+
hash = Request::Utils.normalize_encode_params(hash)
|
52
|
+
|
53
|
+
hash
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def store_nested_param(params, name, v, depth, encoding_template = nil)
|
58
|
+
raise ParamsTooDeepError if depth >= param_depth_limit
|
59
|
+
|
60
|
+
if !name
|
61
|
+
# nil name, treat same as empty string (required by tests)
|
62
|
+
k = after = ""
|
63
|
+
elsif depth == 0
|
64
|
+
# Start of parsing, don't treat [] or [ at start of string specially
|
65
|
+
if start = name.index("[", 1)
|
66
|
+
# Start of parameter nesting, use part before brackets as key
|
67
|
+
k = name[0, start]
|
68
|
+
after = name[start, name.length]
|
69
|
+
else
|
70
|
+
# Plain parameter with no nesting
|
71
|
+
k = name
|
72
|
+
after = ""
|
73
|
+
end
|
74
|
+
elsif name.start_with?("[]")
|
75
|
+
# Array nesting
|
76
|
+
k = "[]"
|
77
|
+
after = name[2, name.length]
|
78
|
+
elsif name.start_with?("[") && (start = name.index("]", 1))
|
79
|
+
# Hash nesting, use the part inside brackets as the key
|
80
|
+
k = name[1, start - 1]
|
81
|
+
after = name[start + 1, name.length]
|
82
|
+
else
|
83
|
+
# Probably malformed input, nested but not starting with [
|
84
|
+
# treat full name as key for backwards compatibility.
|
85
|
+
k = name
|
86
|
+
after = ""
|
87
|
+
end
|
88
|
+
|
89
|
+
return if k.empty?
|
90
|
+
|
91
|
+
if depth == 0 && String === v
|
92
|
+
# We have to wait until we've found the top part of the name,
|
93
|
+
# because that's what the encoding template is configured with
|
94
|
+
if encoding_template && (designated_encoding = encoding_template[k]) && !v.frozen?
|
95
|
+
v.force_encoding(designated_encoding)
|
96
|
+
end
|
97
|
+
|
98
|
+
# ... and we can't validate the encoding until after we've
|
99
|
+
# applied any template override
|
100
|
+
unless v.valid_encoding?
|
101
|
+
raise InvalidParameterError, "Invalid encoding for parameter: #{v.scrub}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
if after == ""
|
106
|
+
if k == "[]" && depth != 0
|
107
|
+
return (v || !ActionDispatch::Request::Utils.perform_deep_munge) ? [v] : []
|
108
|
+
else
|
109
|
+
params[k] = v
|
110
|
+
end
|
111
|
+
elsif after == "["
|
112
|
+
params[name] = v
|
113
|
+
elsif after == "[]"
|
114
|
+
params[k] ||= []
|
115
|
+
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
116
|
+
params[k] << v if v || !ActionDispatch::Request::Utils.perform_deep_munge
|
117
|
+
elsif after.start_with?("[]")
|
118
|
+
# Recognize x[][y] (hash inside array) parameters
|
119
|
+
unless after[2] == "[" && after.end_with?("]") && (child_key = after[3, after.length - 4]) && !child_key.empty? && !child_key.index("[") && !child_key.index("]")
|
120
|
+
# Handle other nested array parameters
|
121
|
+
child_key = after[2, after.length]
|
122
|
+
end
|
123
|
+
params[k] ||= []
|
124
|
+
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
125
|
+
if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
|
126
|
+
store_nested_param(params[k].last, child_key, v, depth + 1)
|
127
|
+
else
|
128
|
+
params[k] << store_nested_param(make_params, child_key, v, depth + 1)
|
129
|
+
end
|
130
|
+
else
|
131
|
+
params[k] ||= make_params
|
132
|
+
raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
|
133
|
+
params[k] = store_nested_param(params[k], after, v, depth + 1)
|
134
|
+
end
|
135
|
+
|
136
|
+
params
|
137
|
+
end
|
138
|
+
|
139
|
+
def make_params
|
140
|
+
ActiveSupport::HashWithIndifferentAccess.new
|
141
|
+
end
|
142
|
+
|
143
|
+
def new_depth_limit(param_depth_limit)
|
144
|
+
self.class.new @params_class, param_depth_limit
|
145
|
+
end
|
146
|
+
|
147
|
+
def params_hash_type?(obj)
|
148
|
+
Hash === obj
|
149
|
+
end
|
150
|
+
|
151
|
+
def params_hash_has_key?(hash, key)
|
152
|
+
return false if key.include?("[]")
|
153
|
+
|
154
|
+
key.split(/[\[\]]+/).inject(hash) do |h, part|
|
155
|
+
next h if part == ""
|
156
|
+
return false unless params_hash_type?(h) && h.key?(part)
|
157
|
+
h[part]
|
158
|
+
end
|
159
|
+
|
160
|
+
true
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionDispatch
|
4
|
+
class ParamError < ActionDispatch::Http::Parameters::ParseError
|
5
|
+
def initialize(message = nil)
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.===(other)
|
10
|
+
super || (
|
11
|
+
defined?(Rack::Utils::ParameterTypeError) && Rack::Utils::ParameterTypeError === other ||
|
12
|
+
defined?(Rack::Utils::InvalidParameterError) && Rack::Utils::InvalidParameterError === other ||
|
13
|
+
defined?(Rack::QueryParser::ParamsTooDeepError) && Rack::QueryParser::ParamsTooDeepError === other
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ParameterTypeError < ParamError
|
19
|
+
end
|
20
|
+
|
21
|
+
class InvalidParameterError < ParamError
|
22
|
+
end
|
23
|
+
|
24
|
+
class ParamsTooDeepError < ParamError
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
|
5
|
+
module ActionDispatch
|
6
|
+
class QueryParser
|
7
|
+
DEFAULT_SEP = /& */n
|
8
|
+
COMMON_SEP = { ";" => /; */n, ";," => /[;,] */n, "&" => /& */n }
|
9
|
+
|
10
|
+
#--
|
11
|
+
# Note this departs from WHATWG's specified parsing algorithm by
|
12
|
+
# giving a nil value for keys that do not use '='. Callers that need
|
13
|
+
# the standard's interpretation can use `v.to_s`.
|
14
|
+
def self.each_pair(s, separator = nil)
|
15
|
+
return enum_for(:each_pair, s, separator) unless block_given?
|
16
|
+
|
17
|
+
(s || "").split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |part|
|
18
|
+
next if part.empty?
|
19
|
+
|
20
|
+
k, v = part.split("=", 2)
|
21
|
+
|
22
|
+
k = URI.decode_www_form_component(k)
|
23
|
+
v &&= URI.decode_www_form_component(v)
|
24
|
+
|
25
|
+
yield k, v
|
26
|
+
end
|
27
|
+
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -63,6 +63,9 @@ module ActionDispatch
|
|
63
63
|
|
64
64
|
def initialize(env)
|
65
65
|
super
|
66
|
+
|
67
|
+
@rack_request = Rack::Request.new(env)
|
68
|
+
|
66
69
|
@method = nil
|
67
70
|
@request_method = nil
|
68
71
|
@remote_ip = nil
|
@@ -71,6 +74,8 @@ module ActionDispatch
|
|
71
74
|
@ip = nil
|
72
75
|
end
|
73
76
|
|
77
|
+
attr_reader :rack_request
|
78
|
+
|
74
79
|
def commit_cookie_jar! # :nodoc:
|
75
80
|
end
|
76
81
|
|
@@ -388,15 +393,12 @@ module ActionDispatch
|
|
388
393
|
# Override Rack's GET method to support indifferent access.
|
389
394
|
def GET
|
390
395
|
fetch_header("action_dispatch.request.query_parameters") do |k|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
# Check for non UTF-8 parameter values, which would cause errors later
|
396
|
-
Request::Utils.check_param_encoding(rack_query_params)
|
397
|
-
set_header k, Request::Utils.normalize_encode_params(rack_query_params)
|
396
|
+
encoding_template = Request::Utils::CustomParamEncoder.action_encoding_template(self, path_parameters[:controller], path_parameters[:action])
|
397
|
+
rack_query_params = ActionDispatch::ParamBuilder.from_query_string(rack_request.query_string, encoding_template: encoding_template)
|
398
|
+
|
399
|
+
set_header k, rack_query_params
|
398
400
|
end
|
399
|
-
rescue
|
401
|
+
rescue ActionDispatch::ParamError => e
|
400
402
|
raise ActionController::BadRequest.new("Invalid query parameters: #{e.message}")
|
401
403
|
end
|
402
404
|
alias :query_parameters :GET
|
@@ -404,18 +406,54 @@ module ActionDispatch
|
|
404
406
|
# Override Rack's POST method to support indifferent access.
|
405
407
|
def POST
|
406
408
|
fetch_header("action_dispatch.request.request_parameters") do
|
407
|
-
|
408
|
-
|
409
|
+
encoding_template = Request::Utils::CustomParamEncoder.action_encoding_template(self, path_parameters[:controller], path_parameters[:action])
|
410
|
+
|
411
|
+
param_list = nil
|
412
|
+
pr = parse_formatted_parameters(params_parsers) do
|
413
|
+
if param_list = request_parameters_list
|
414
|
+
ActionDispatch::ParamBuilder.from_pairs(param_list, encoding_template: encoding_template)
|
415
|
+
else
|
416
|
+
# We're not using a version of Rack that provides raw form
|
417
|
+
# pairs; we must use its hash (and thus post-process it below).
|
418
|
+
fallback_request_parameters
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
# If the request body was parsed by a custom parser like JSON
|
423
|
+
# (and thus the above block was not run), we need to
|
424
|
+
# post-process the result hash.
|
425
|
+
if param_list.nil?
|
426
|
+
pr = ActionDispatch::ParamBuilder.from_hash(pr, encoding_template: encoding_template)
|
409
427
|
end
|
410
|
-
|
411
|
-
|
412
|
-
self.request_parameters = Request::Utils.normalize_encode_params(pr)
|
428
|
+
|
429
|
+
self.request_parameters = pr
|
413
430
|
end
|
414
|
-
rescue
|
431
|
+
rescue ActionDispatch::ParamError, EOFError => e
|
415
432
|
raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
|
416
433
|
end
|
417
434
|
alias :request_parameters :POST
|
418
435
|
|
436
|
+
def request_parameters_list
|
437
|
+
# We don't use Rack's parse result, but we must call it so Rack
|
438
|
+
# can populate the rack.request.* keys we need.
|
439
|
+
rack_post = rack_request.POST
|
440
|
+
|
441
|
+
if form_pairs = get_header("rack.request.form_pairs")
|
442
|
+
# Multipart
|
443
|
+
form_pairs
|
444
|
+
elsif form_vars = get_header("rack.request.form_vars")
|
445
|
+
# URL-encoded
|
446
|
+
ActionDispatch::QueryParser.each_pair(form_vars)
|
447
|
+
elsif rack_post && !rack_post.empty?
|
448
|
+
# It was multipart, but Rack did not preserve a pair list
|
449
|
+
# (probably too old). Flat parameter list is not available.
|
450
|
+
nil
|
451
|
+
else
|
452
|
+
# No request body, or not a format Rack knows
|
453
|
+
[]
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
419
457
|
# Returns the authorization header regardless of whether it was specified
|
420
458
|
# directly or through one of the proxy alternatives.
|
421
459
|
def authorization
|
@@ -492,6 +530,10 @@ module ActionDispatch
|
|
492
530
|
yield
|
493
531
|
end
|
494
532
|
end
|
533
|
+
|
534
|
+
def fallback_request_parameters
|
535
|
+
rack_request.POST
|
536
|
+
end
|
495
537
|
end
|
496
538
|
end
|
497
539
|
|
@@ -15,17 +15,12 @@ module ActionDispatch
|
|
15
15
|
paths = RESCUES_TEMPLATE_PATHS.dup
|
16
16
|
lookup_context = ActionView::LookupContext.new(paths)
|
17
17
|
super(lookup_context, assigns, nil)
|
18
|
-
@exception_wrapper = assigns[:exception_wrapper]
|
19
18
|
end
|
20
19
|
|
21
20
|
def compiled_method_container
|
22
21
|
self.class
|
23
22
|
end
|
24
23
|
|
25
|
-
def error_highlight_available?
|
26
|
-
@exception_wrapper.error_highlight_available?
|
27
|
-
end
|
28
|
-
|
29
24
|
def debug_params(params)
|
30
25
|
clean_params = params.clone
|
31
26
|
clean_params.delete("action")
|
@@ -201,12 +201,6 @@ module ActionDispatch
|
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
204
|
-
def error_highlight_available?
|
205
|
-
# ErrorHighlight.spot with backtrace_location keyword is available since
|
206
|
-
# error_highlight 0.4.0
|
207
|
-
defined?(ErrorHighlight) && Gem::Version.new(ErrorHighlight::VERSION) >= Gem::Version.new("0.4.0")
|
208
|
-
end
|
209
|
-
|
210
204
|
def trace_to_show
|
211
205
|
if traces["Application Trace"].empty? && rescue_template != "routing_error"
|
212
206
|
"Full Trace"
|
@@ -28,9 +28,6 @@
|
|
28
28
|
</tr>
|
29
29
|
</table>
|
30
30
|
</div>
|
31
|
-
<%- unless self.error_highlight_available? -%>
|
32
|
-
<p class="error_highlight_tip">Tip: You may want to add <code>gem "error_highlight", ">= 0.4.0"</code> into your Gemfile, which will display the fine-grained error location.</p>
|
33
|
-
<%- end -%>
|
34
31
|
</div>
|
35
32
|
<% end %>
|
36
33
|
<% end %>
|
@@ -83,8 +83,8 @@ module ActionDispatch
|
|
83
83
|
end
|
84
84
|
|
85
85
|
class CustomParamEncoder # :nodoc:
|
86
|
-
def self.
|
87
|
-
return params unless
|
86
|
+
def self.encode_for_template(params, encoding_template)
|
87
|
+
return params unless encoding_template
|
88
88
|
params.except(:controller, :action).each do |key, value|
|
89
89
|
ActionDispatch::Request::Utils.each_param_value(value) do |param|
|
90
90
|
# If `param` is frozen, it comes from the router defaults
|
@@ -98,8 +98,14 @@ module ActionDispatch
|
|
98
98
|
params
|
99
99
|
end
|
100
100
|
|
101
|
+
def self.encode(request, params, controller, action)
|
102
|
+
encoding_template = action_encoding_template(request, controller, action)
|
103
|
+
encode_for_template(params, encoding_template)
|
104
|
+
end
|
105
|
+
|
101
106
|
def self.action_encoding_template(request, controller, action) # :nodoc:
|
102
|
-
|
107
|
+
controller && controller.valid_encoding? &&
|
108
|
+
request.controller_class_for(controller).action_encoding_template(action)
|
103
109
|
rescue MissingController
|
104
110
|
nil
|
105
111
|
end
|
@@ -375,35 +375,18 @@ module ActionDispatch
|
|
375
375
|
Routing::RouteSet::Dispatcher.new raise_on_name_error
|
376
376
|
end
|
377
377
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
next if location.path.start_with?(action_dispatch_dir)
|
378
|
+
def route_source_location
|
379
|
+
if Mapper.route_source_locations
|
380
|
+
action_dispatch_dir = File.expand_path("..", __dir__)
|
381
|
+
Thread.each_caller_location do |location|
|
382
|
+
next if location.path.start_with?(action_dispatch_dir)
|
384
383
|
|
385
|
-
|
386
|
-
|
384
|
+
cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
|
385
|
+
next if cleaned_path.nil?
|
387
386
|
|
388
|
-
|
389
|
-
end
|
390
|
-
nil
|
391
|
-
end
|
392
|
-
end
|
393
|
-
else
|
394
|
-
def route_source_location
|
395
|
-
if Mapper.route_source_locations
|
396
|
-
action_dispatch_dir = File.expand_path("..", __dir__)
|
397
|
-
caller_locations.each do |location|
|
398
|
-
next if location.path.start_with?(action_dispatch_dir)
|
399
|
-
|
400
|
-
cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
|
401
|
-
next if cleaned_path.nil?
|
402
|
-
|
403
|
-
return "#{cleaned_path}:#{location.lineno}"
|
404
|
-
end
|
405
|
-
nil
|
387
|
+
return "#{cleaned_path}:#{location.lineno}"
|
406
388
|
end
|
389
|
+
nil
|
407
390
|
end
|
408
391
|
end
|
409
392
|
end
|
@@ -1179,6 +1162,16 @@ module ActionDispatch
|
|
1179
1162
|
CANONICAL_ACTIONS = %w(index create new show update destroy)
|
1180
1163
|
|
1181
1164
|
class Resource # :nodoc:
|
1165
|
+
class << self
|
1166
|
+
def default_actions(api_only)
|
1167
|
+
if api_only
|
1168
|
+
[:index, :create, :show, :update, :destroy]
|
1169
|
+
else
|
1170
|
+
[:index, :create, :new, :show, :update, :destroy, :edit]
|
1171
|
+
end
|
1172
|
+
end
|
1173
|
+
end
|
1174
|
+
|
1182
1175
|
attr_reader :controller, :path, :param
|
1183
1176
|
|
1184
1177
|
def initialize(entities, api_only, shallow, options = {})
|
@@ -1186,6 +1179,11 @@ module ActionDispatch
|
|
1186
1179
|
raise ArgumentError, ":param option can't contain colons"
|
1187
1180
|
end
|
1188
1181
|
|
1182
|
+
valid_actions = self.class.default_actions(false) # ignore api_only for this validation
|
1183
|
+
if invalid_actions = invalid_only_except_options(options, valid_actions).presence
|
1184
|
+
raise ArgumentError, ":only and :except must include only #{valid_actions}, but also included #{invalid_actions}"
|
1185
|
+
end
|
1186
|
+
|
1189
1187
|
@name = entities.to_s
|
1190
1188
|
@path = (options[:path] || @name).to_s
|
1191
1189
|
@controller = (options[:controller] || @name).to_s
|
@@ -1199,11 +1197,7 @@ module ActionDispatch
|
|
1199
1197
|
end
|
1200
1198
|
|
1201
1199
|
def default_actions
|
1202
|
-
|
1203
|
-
[:index, :create, :show, :update, :destroy]
|
1204
|
-
else
|
1205
|
-
[:index, :create, :new, :show, :update, :destroy, :edit]
|
1206
|
-
end
|
1200
|
+
self.class.default_actions(@api_only)
|
1207
1201
|
end
|
1208
1202
|
|
1209
1203
|
def actions
|
@@ -1271,9 +1265,24 @@ module ActionDispatch
|
|
1271
1265
|
end
|
1272
1266
|
|
1273
1267
|
def singleton?; false; end
|
1268
|
+
|
1269
|
+
private
|
1270
|
+
def invalid_only_except_options(options, valid_actions)
|
1271
|
+
options.values_at(:only, :except).flatten.compact.uniq.map(&:to_sym) - valid_actions
|
1272
|
+
end
|
1274
1273
|
end
|
1275
1274
|
|
1276
1275
|
class SingletonResource < Resource # :nodoc:
|
1276
|
+
class << self
|
1277
|
+
def default_actions(api_only)
|
1278
|
+
if api_only
|
1279
|
+
[:show, :create, :update, :destroy]
|
1280
|
+
else
|
1281
|
+
[:show, :create, :update, :destroy, :new, :edit]
|
1282
|
+
end
|
1283
|
+
end
|
1284
|
+
end
|
1285
|
+
|
1277
1286
|
def initialize(entities, api_only, shallow, options)
|
1278
1287
|
super
|
1279
1288
|
@as = nil
|
@@ -1282,11 +1291,7 @@ module ActionDispatch
|
|
1282
1291
|
end
|
1283
1292
|
|
1284
1293
|
def default_actions
|
1285
|
-
|
1286
|
-
[:show, :create, :update, :destroy]
|
1287
|
-
else
|
1288
|
-
[:show, :create, :update, :destroy, :new, :edit]
|
1289
|
-
end
|
1294
|
+
self.class.default_actions(@api_only)
|
1290
1295
|
end
|
1291
1296
|
|
1292
1297
|
def plural
|
@@ -1347,7 +1352,7 @@ module ActionDispatch
|
|
1347
1352
|
end
|
1348
1353
|
|
1349
1354
|
with_scope_level(:resource) do
|
1350
|
-
options = apply_action_options options
|
1355
|
+
options = apply_action_options :resource, options
|
1351
1356
|
resource_scope(SingletonResource.new(resources.pop, api_only?, @scope[:shallow], options)) do
|
1352
1357
|
yield if block_given?
|
1353
1358
|
|
@@ -1517,7 +1522,7 @@ module ActionDispatch
|
|
1517
1522
|
end
|
1518
1523
|
|
1519
1524
|
with_scope_level(:resources) do
|
1520
|
-
options = apply_action_options options
|
1525
|
+
options = apply_action_options :resources, options
|
1521
1526
|
resource_scope(Resource.new(resources.pop, api_only?, @scope[:shallow], options)) do
|
1522
1527
|
yield if block_given?
|
1523
1528
|
|
@@ -1786,17 +1791,32 @@ module ActionDispatch
|
|
1786
1791
|
false
|
1787
1792
|
end
|
1788
1793
|
|
1789
|
-
def apply_action_options(options)
|
1794
|
+
def apply_action_options(method, options)
|
1790
1795
|
return options if action_options? options
|
1791
|
-
options.merge scope_action_options
|
1796
|
+
options.merge scope_action_options(method)
|
1792
1797
|
end
|
1793
1798
|
|
1794
1799
|
def action_options?(options)
|
1795
1800
|
options[:only] || options[:except]
|
1796
1801
|
end
|
1797
1802
|
|
1798
|
-
def scope_action_options
|
1799
|
-
@scope[:action_options]
|
1803
|
+
def scope_action_options(method)
|
1804
|
+
return {} unless @scope[:action_options]
|
1805
|
+
|
1806
|
+
actions = applicable_actions_for(method)
|
1807
|
+
@scope[:action_options].dup.tap do |options|
|
1808
|
+
(options[:only] = Array(options[:only]) & actions) if options[:only]
|
1809
|
+
(options[:except] = Array(options[:except]) & actions) if options[:except]
|
1810
|
+
end
|
1811
|
+
end
|
1812
|
+
|
1813
|
+
def applicable_actions_for(method)
|
1814
|
+
case method
|
1815
|
+
when :resource
|
1816
|
+
SingletonResource.default_actions(api_only?)
|
1817
|
+
when :resources
|
1818
|
+
Resource.default_actions(api_only?)
|
1819
|
+
end
|
1800
1820
|
end
|
1801
1821
|
|
1802
1822
|
def resource_scope?
|
@@ -2209,8 +2229,8 @@ module ActionDispatch
|
|
2209
2229
|
end
|
2210
2230
|
|
2211
2231
|
# Define custom polymorphic mappings of models to URLs. This alters the behavior
|
2212
|
-
# of `polymorphic_url` and consequently the behavior of `link_to
|
2213
|
-
# when passed a model instance, e.g:
|
2232
|
+
# of `polymorphic_url` and consequently the behavior of `link_to`, `form_with`
|
2233
|
+
# and `form_for` when passed a model instance, e.g:
|
2214
2234
|
#
|
2215
2235
|
# resource :basket
|
2216
2236
|
#
|
@@ -2219,7 +2239,7 @@ module ActionDispatch
|
|
2219
2239
|
# end
|
2220
2240
|
#
|
2221
2241
|
# This will now generate "/basket" when a `Basket` instance is passed to
|
2222
|
-
# `link_to` or `form_for` instead of the standard "/baskets/:id".
|
2242
|
+
# `link_to`, `form_with` or `form_for` instead of the standard "/baskets/:id".
|
2223
2243
|
#
|
2224
2244
|
# NOTE: This custom behavior only applies to simple polymorphic URLs where a
|
2225
2245
|
# single model instance is passed and not more complicated forms, e.g:
|
@@ -31,7 +31,7 @@ module ActionDispatch
|
|
31
31
|
# * `url_for`, so you can use it with a record as the argument, e.g.
|
32
32
|
# `url_for(@article)`;
|
33
33
|
# * ActionView::Helpers::FormHelper uses `polymorphic_path`, so you can write
|
34
|
-
# `
|
34
|
+
# `form_with(model: @article)` without having to specify `:url` parameter for the
|
35
35
|
# form action;
|
36
36
|
# * `redirect_to` (which, in fact, uses `url_for`) so you can write
|
37
37
|
# `redirect_to(post)` in your controllers;
|
@@ -61,7 +61,7 @@ module ActionDispatch
|
|
61
61
|
# argument to the method. For example:
|
62
62
|
#
|
63
63
|
# polymorphic_url([blog, @post]) # calls blog.post_path(@post)
|
64
|
-
#
|
64
|
+
# form_with(model: [blog, @post]) # => "/blog/posts/1"
|
65
65
|
#
|
66
66
|
module PolymorphicRoutes
|
67
67
|
# Constructs a call to a named RESTful route for the given record and returns
|
@@ -659,14 +659,14 @@ module ActionDispatch
|
|
659
659
|
if route.segment_keys.include?(:controller)
|
660
660
|
ActionDispatch.deprecator.warn(<<-MSG.squish)
|
661
661
|
Using a dynamic :controller segment in a route is deprecated and
|
662
|
-
will be removed in Rails
|
662
|
+
will be removed in Rails 8.1.
|
663
663
|
MSG
|
664
664
|
end
|
665
665
|
|
666
666
|
if route.segment_keys.include?(:action)
|
667
667
|
ActionDispatch.deprecator.warn(<<-MSG.squish)
|
668
668
|
Using a dynamic :action segment in a route is deprecated and
|
669
|
-
will be removed in Rails
|
669
|
+
will be removed in Rails 8.1.
|
670
670
|
MSG
|
671
671
|
end
|
672
672
|
|
@@ -87,8 +87,13 @@ module ActionDispatch
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def generate_response_message(expected, actual = @response.response_code)
|
90
|
-
|
91
|
-
|
90
|
+
lambda do
|
91
|
+
(+"Expected response to be a <#{code_with_name(expected)}>,"\
|
92
|
+
" but was a <#{code_with_name(actual)}>").
|
93
|
+
concat(location_if_redirected).
|
94
|
+
concat(exception_if_present).
|
95
|
+
concat(response_body_if_short)
|
96
|
+
end
|
92
97
|
end
|
93
98
|
|
94
99
|
def response_body_if_short
|
@@ -96,6 +101,11 @@ module ActionDispatch
|
|
96
101
|
"\nResponse body: #{@response.body}"
|
97
102
|
end
|
98
103
|
|
104
|
+
def exception_if_present
|
105
|
+
return "" unless ex = @request&.env&.[]("action_dispatch.exception")
|
106
|
+
"\n\nException while processing request: #{Minitest::UnexpectedError.new(ex).message}\n"
|
107
|
+
end
|
108
|
+
|
99
109
|
def location_if_redirected
|
100
110
|
return "" unless @response.redirection? && @response.location.present?
|
101
111
|
location = normalize_argument_to_redirection(@response.location)
|
@@ -118,9 +118,9 @@ module ActionDispatch
|
|
118
118
|
# assert_equal "/users", users_path
|
119
119
|
# end
|
120
120
|
#
|
121
|
-
def with_routing(&block)
|
121
|
+
def with_routing(config = nil, &block)
|
122
122
|
old_routes, old_controller = @routes, @controller
|
123
|
-
create_routes(&block)
|
123
|
+
create_routes(config, &block)
|
124
124
|
ensure
|
125
125
|
reset_routes(old_routes, old_controller)
|
126
126
|
end
|
@@ -267,8 +267,8 @@ module ActionDispatch
|
|
267
267
|
end
|
268
268
|
|
269
269
|
private
|
270
|
-
def create_routes
|
271
|
-
@routes = ActionDispatch::Routing::RouteSet.new
|
270
|
+
def create_routes(config = nil)
|
271
|
+
@routes = ActionDispatch::Routing::RouteSet.new(config || ActionDispatch::Routing::RouteSet::DEFAULT_CONFIG)
|
272
272
|
if @controller
|
273
273
|
@controller = @controller.clone
|
274
274
|
_routes = @routes
|
@@ -284,7 +284,17 @@ module ActionDispatch
|
|
284
284
|
|
285
285
|
# NOTE: rack-test v0.5 doesn't build a default uri correctly Make sure requested
|
286
286
|
# path is always a full URI.
|
287
|
-
|
287
|
+
uri = build_full_uri(path, request_env)
|
288
|
+
|
289
|
+
if method == :get && String === request_env[:params]
|
290
|
+
# rack-test will needlessly parse and rebuild a :params
|
291
|
+
# querystring, using Rack's query parser. At best that's a
|
292
|
+
# waste of time; at worst it can change the value.
|
293
|
+
|
294
|
+
uri << "?" << request_env.delete(:params)
|
295
|
+
end
|
296
|
+
|
297
|
+
session.request(uri, request_env)
|
288
298
|
|
289
299
|
@request_count += 1
|
290
300
|
@request = ActionDispatch::Request.new(session.last_request.env)
|
data/lib/action_dispatch.rb
CHANGED
@@ -53,7 +53,13 @@ module ActionDispatch
|
|
53
53
|
eager_autoload do
|
54
54
|
autoload_under "http" do
|
55
55
|
autoload :ContentSecurityPolicy
|
56
|
+
autoload :InvalidParameterError, "action_dispatch/http/param_error"
|
57
|
+
autoload :ParamBuilder
|
58
|
+
autoload :ParamError
|
59
|
+
autoload :ParameterTypeError, "action_dispatch/http/param_error"
|
60
|
+
autoload :ParamsTooDeepError, "action_dispatch/http/param_error"
|
56
61
|
autoload :PermissionsPolicy
|
62
|
+
autoload :QueryParser
|
57
63
|
autoload :Request
|
58
64
|
autoload :Response
|
59
65
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.0.0.
|
4
|
+
version: 8.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 8.0.0.
|
19
|
+
version: 8.0.0.rc1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 8.0.0.
|
26
|
+
version: 8.0.0.rc1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: nokogiri
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,28 +128,28 @@ dependencies:
|
|
128
128
|
requirements:
|
129
129
|
- - '='
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 8.0.0.
|
131
|
+
version: 8.0.0.rc1
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - '='
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 8.0.0.
|
138
|
+
version: 8.0.0.rc1
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: activemodel
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - '='
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 8.0.0.
|
145
|
+
version: 8.0.0.rc1
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - '='
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 8.0.0.
|
152
|
+
version: 8.0.0.rc1
|
153
153
|
description: Web apps on Rails. Simple, battle-tested conventions for building and
|
154
154
|
testing MVC web applications. Works with any Rack-compatible server.
|
155
155
|
email: david@loudthinking.com
|
@@ -233,8 +233,11 @@ files:
|
|
233
233
|
- lib/action_dispatch/http/mime_negotiation.rb
|
234
234
|
- lib/action_dispatch/http/mime_type.rb
|
235
235
|
- lib/action_dispatch/http/mime_types.rb
|
236
|
+
- lib/action_dispatch/http/param_builder.rb
|
237
|
+
- lib/action_dispatch/http/param_error.rb
|
236
238
|
- lib/action_dispatch/http/parameters.rb
|
237
239
|
- lib/action_dispatch/http/permissions_policy.rb
|
240
|
+
- lib/action_dispatch/http/query_parser.rb
|
238
241
|
- lib/action_dispatch/http/rack_cache.rb
|
239
242
|
- lib/action_dispatch/http/request.rb
|
240
243
|
- lib/action_dispatch/http/response.rb
|
@@ -347,10 +350,10 @@ licenses:
|
|
347
350
|
- MIT
|
348
351
|
metadata:
|
349
352
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
350
|
-
changelog_uri: https://github.com/rails/rails/blob/v8.0.0.
|
351
|
-
documentation_uri: https://api.rubyonrails.org/v8.0.0.
|
353
|
+
changelog_uri: https://github.com/rails/rails/blob/v8.0.0.rc1/actionpack/CHANGELOG.md
|
354
|
+
documentation_uri: https://api.rubyonrails.org/v8.0.0.rc1/
|
352
355
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
353
|
-
source_code_uri: https://github.com/rails/rails/tree/v8.0.0.
|
356
|
+
source_code_uri: https://github.com/rails/rails/tree/v8.0.0.rc1/actionpack
|
354
357
|
rubygems_mfa_required: 'true'
|
355
358
|
post_install_message:
|
356
359
|
rdoc_options: []
|