actionpack 6.1.7.6 → 7.0.0.alpha1
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 +99 -584
- data/MIT-LICENSE +2 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +7 -21
- data/lib/abstract_controller/caching/fragments.rb +2 -2
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +9 -8
- data/lib/abstract_controller/collector.rb +2 -2
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +3 -2
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/translation.rb +0 -2
- data/lib/abstract_controller/url_for.rb +4 -6
- data/lib/action_controller/api.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +38 -1
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/cookies.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +5 -13
- data/lib/action_controller/metal/exceptions.rb +19 -30
- data/lib/action_controller/metal/flash.rb +6 -2
- data/lib/action_controller/metal/http_authentication.rb +15 -16
- data/lib/action_controller/metal/instrumentation.rb +55 -52
- data/lib/action_controller/metal/live.rb +42 -2
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/params_wrapper.rb +7 -7
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/query_tags.rb +16 -0
- data/lib/action_controller/metal/redirecting.rb +49 -34
- data/lib/action_controller/metal/rendering.rb +9 -9
- data/lib/action_controller/metal/request_forgery_protection.rb +64 -20
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +1 -3
- data/lib/action_controller/metal/strong_parameters.rb +25 -29
- data/lib/action_controller/metal/testing.rb +0 -2
- data/lib/action_controller/metal.rb +7 -10
- data/lib/action_controller/railtie.rb +42 -5
- data/lib/action_controller/test_case.rb +6 -2
- data/lib/action_controller.rb +2 -5
- data/lib/action_dispatch/http/cache.rb +14 -7
- data/lib/action_dispatch/http/content_security_policy.rb +47 -37
- data/lib/action_dispatch/http/filter_parameters.rb +5 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +13 -3
- data/lib/action_dispatch/http/mime_type.rb +9 -11
- data/lib/action_dispatch/http/parameters.rb +4 -4
- data/lib/action_dispatch/http/permissions_policy.rb +1 -1
- data/lib/action_dispatch/http/request.rb +10 -19
- data/lib/action_dispatch/http/response.rb +3 -3
- data/lib/action_dispatch/http/url.rb +9 -10
- data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
- data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
- data/lib/action_dispatch/journey/nodes/node.rb +70 -5
- data/lib/action_dispatch/journey/path/pattern.rb +22 -13
- data/lib/action_dispatch/journey/route.rb +5 -12
- data/lib/action_dispatch/journey/router/utils.rb +2 -2
- data/lib/action_dispatch/journey/router.rb +1 -1
- data/lib/action_dispatch/journey/routes.rb +3 -3
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +0 -1
- data/lib/action_dispatch/middleware/cookies.rb +27 -31
- data/lib/action_dispatch/middleware/debug_exceptions.rb +6 -4
- data/lib/action_dispatch/middleware/debug_locks.rb +3 -3
- data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -0
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +9 -11
- data/lib/action_dispatch/middleware/host_authorization.rb +25 -73
- data/lib/action_dispatch/middleware/remote_ip.rb +16 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +6 -18
- data/lib/action_dispatch/middleware/stack.rb +50 -9
- data/lib/action_dispatch/middleware/static.rb +2 -5
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +28 -18
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +5 -14
- data/lib/action_dispatch/railtie.rb +8 -2
- data/lib/action_dispatch/request/session.rb +43 -13
- data/lib/action_dispatch/routing/mapper.rb +44 -72
- data/lib/action_dispatch/routing/redirection.rb +0 -2
- data/lib/action_dispatch/routing/route_set.rb +7 -4
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
- data/lib/action_dispatch/routing/url_for.rb +1 -2
- data/lib/action_dispatch/routing.rb +2 -2
- data/lib/action_dispatch/system_test_case.rb +6 -12
- data/lib/action_dispatch/system_testing/driver.rb +24 -4
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +10 -6
- data/lib/action_dispatch/testing/assertions.rb +2 -5
- data/lib/action_dispatch/testing/integration.rb +6 -8
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +21 -21
@@ -27,28 +27,13 @@ module ActionController
|
|
27
27
|
super("param is missing or the value is empty: #{param}")
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
@error = error
|
33
|
-
end
|
34
|
-
|
35
|
-
def corrections
|
36
|
-
if @error.param && @error.keys
|
37
|
-
maybe_these = @error.keys
|
30
|
+
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
31
|
+
include DidYouMean::Correctable # :nodoc:
|
38
32
|
|
39
|
-
|
40
|
-
|
41
|
-
}.reverse.first(4)
|
42
|
-
else
|
43
|
-
[]
|
44
|
-
end
|
33
|
+
def corrections # :nodoc:
|
34
|
+
@corrections ||= DidYouMean::SpellChecker.new(dictionary: keys).correct(param.to_s)
|
45
35
|
end
|
46
36
|
end
|
47
|
-
|
48
|
-
# We may not have DYM, and DYM might not let us register error handlers
|
49
|
-
if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
|
50
|
-
DidYouMean.correct_error(self, Correction)
|
51
|
-
end
|
52
37
|
end
|
53
38
|
|
54
39
|
# Raised when a supplied parameter is not expected and
|
@@ -106,11 +91,13 @@ module ActionController
|
|
106
91
|
#
|
107
92
|
# * +permit_all_parameters+ - If it's +true+, all the parameters will be
|
108
93
|
# permitted by default. The default is +false+.
|
109
|
-
# * +action_on_unpermitted_parameters+ -
|
110
|
-
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
94
|
+
# * +action_on_unpermitted_parameters+ - Controls behavior when parameters that are not explicitly
|
95
|
+
# permitted are found. The default value is <tt>:log</tt> in test and development environments,
|
96
|
+
# +false+ otherwise. The values can be:
|
97
|
+
# * +false+ to take no action.
|
98
|
+
# * <tt>:log</tt> to emit an <tt>ActiveSupport::Notifications.instrument</tt> event on the
|
99
|
+
# <tt>unpermitted_parameters.action_controller</tt> topic and log at the DEBUG level.
|
100
|
+
# * <tt>:raise</tt> to raise a <tt>ActionController::UnpermittedParameters</tt> exception.
|
114
101
|
#
|
115
102
|
# Examples:
|
116
103
|
#
|
@@ -277,8 +264,9 @@ module ActionController
|
|
277
264
|
# params = ActionController::Parameters.new(name: "Francesco")
|
278
265
|
# params.permitted? # => true
|
279
266
|
# Person.new(params) # => #<Person id: nil, name: "Francesco">
|
280
|
-
def initialize(parameters = {})
|
267
|
+
def initialize(parameters = {}, logging_context = {})
|
281
268
|
@parameters = parameters.with_indifferent_access
|
269
|
+
@logging_context = logging_context
|
282
270
|
@permitted = self.class.permit_all_parameters
|
283
271
|
end
|
284
272
|
|
@@ -940,7 +928,7 @@ module ActionController
|
|
940
928
|
when Array
|
941
929
|
return value if converted_arrays.member?(value)
|
942
930
|
converted = value.map { |_| convert_value_to_parameters(_) }
|
943
|
-
converted_arrays << converted
|
931
|
+
converted_arrays << converted
|
944
932
|
converted
|
945
933
|
when Hash
|
946
934
|
self.class.new(value)
|
@@ -952,7 +940,7 @@ module ActionController
|
|
952
940
|
def each_element(object, &block)
|
953
941
|
case object
|
954
942
|
when Array
|
955
|
-
object.grep(Parameters).
|
943
|
+
object.grep(Parameters).filter_map(&block)
|
956
944
|
when Parameters
|
957
945
|
if object.nested_attributes?
|
958
946
|
object.each_nested_attribute(&block)
|
@@ -968,7 +956,7 @@ module ActionController
|
|
968
956
|
case self.class.action_on_unpermitted_parameters
|
969
957
|
when :log
|
970
958
|
name = "unpermitted_parameters.action_controller"
|
971
|
-
ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys)
|
959
|
+
ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys, context: @logging_context)
|
972
960
|
when :raise
|
973
961
|
raise ActionController::UnpermittedParameters.new(unpermitted_keys)
|
974
962
|
end
|
@@ -1184,7 +1172,15 @@ module ActionController
|
|
1184
1172
|
# Returns a new ActionController::Parameters object that
|
1185
1173
|
# has been instantiated with the <tt>request.parameters</tt>.
|
1186
1174
|
def params
|
1187
|
-
@_params ||=
|
1175
|
+
@_params ||= begin
|
1176
|
+
context = {
|
1177
|
+
controller: self.class.name,
|
1178
|
+
action: action_name,
|
1179
|
+
request: request,
|
1180
|
+
params: request.filtered_parameters
|
1181
|
+
}
|
1182
|
+
Parameters.new(request.parameters, context)
|
1183
|
+
end
|
1188
1184
|
end
|
1189
1185
|
|
1190
1186
|
# Assigns the given +value+ to the +params+ hash. If +value+
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/array/extract_options"
|
4
4
|
require "action_dispatch/middleware/stack"
|
5
|
-
require "action_dispatch/http/request"
|
6
|
-
require "action_dispatch/http/response"
|
7
5
|
|
8
6
|
module ActionController
|
9
7
|
# Extend ActionDispatch middleware stack to make it aware of options
|
@@ -13,8 +11,8 @@ module ActionController
|
|
13
11
|
# use AuthenticationMiddleware, except: [:index, :show]
|
14
12
|
# end
|
15
13
|
#
|
16
|
-
class MiddlewareStack < ActionDispatch::MiddlewareStack
|
17
|
-
class Middleware < ActionDispatch::MiddlewareStack::Middleware
|
14
|
+
class MiddlewareStack < ActionDispatch::MiddlewareStack # :nodoc:
|
15
|
+
class Middleware < ActionDispatch::MiddlewareStack::Middleware # :nodoc:
|
18
16
|
def initialize(klass, args, actions, strategy, block)
|
19
17
|
@actions = actions
|
20
18
|
@strategy = strategy
|
@@ -184,7 +182,7 @@ module ActionController
|
|
184
182
|
response_body || response.committed?
|
185
183
|
end
|
186
184
|
|
187
|
-
def dispatch(name, request, response)
|
185
|
+
def dispatch(name, request, response) # :nodoc:
|
188
186
|
set_request!(request)
|
189
187
|
set_response!(response)
|
190
188
|
process(name)
|
@@ -196,12 +194,12 @@ module ActionController
|
|
196
194
|
@_response = response
|
197
195
|
end
|
198
196
|
|
199
|
-
def set_request!(request)
|
197
|
+
def set_request!(request) # :nodoc:
|
200
198
|
@_request = request
|
201
199
|
@_request.controller_instance = self
|
202
200
|
end
|
203
201
|
|
204
|
-
def to_a
|
202
|
+
def to_a # :nodoc:
|
205
203
|
response.to_a
|
206
204
|
end
|
207
205
|
|
@@ -219,10 +217,9 @@ module ActionController
|
|
219
217
|
class << self
|
220
218
|
# Pushes the given Rack middleware and its arguments to the bottom of the
|
221
219
|
# middleware stack.
|
222
|
-
def use(
|
223
|
-
middleware_stack.use(
|
220
|
+
def use(...)
|
221
|
+
middleware_stack.use(...)
|
224
222
|
end
|
225
|
-
ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
|
226
223
|
end
|
227
224
|
|
228
225
|
# Alias for +middleware_stack+.
|
@@ -8,8 +8,10 @@ require "action_controller/railties/helpers"
|
|
8
8
|
require "action_view/railtie"
|
9
9
|
|
10
10
|
module ActionController
|
11
|
-
class Railtie < Rails::Railtie
|
11
|
+
class Railtie < Rails::Railtie # :nodoc:
|
12
12
|
config.action_controller = ActiveSupport::OrderedOptions.new
|
13
|
+
config.action_controller.raise_on_open_redirects = false
|
14
|
+
config.action_controller.log_query_tags_around_actions = true
|
13
15
|
|
14
16
|
config.eager_load_namespaces << ActionController
|
15
17
|
|
@@ -25,14 +27,19 @@ module ActionController
|
|
25
27
|
options = app.config.action_controller
|
26
28
|
|
27
29
|
ActiveSupport.on_load(:action_controller, run_once: true) do
|
28
|
-
ActionController::Parameters.permit_all_parameters = options.
|
30
|
+
ActionController::Parameters.permit_all_parameters = options.permit_all_parameters || false
|
29
31
|
if app.config.action_controller[:always_permitted_parameters]
|
30
32
|
ActionController::Parameters.always_permitted_parameters =
|
31
|
-
app.config.action_controller.
|
33
|
+
app.config.action_controller.always_permitted_parameters
|
32
34
|
end
|
33
|
-
|
34
|
-
|
35
|
+
|
36
|
+
action_on_unpermitted_parameters = options.action_on_unpermitted_parameters
|
37
|
+
|
38
|
+
if action_on_unpermitted_parameters.nil?
|
39
|
+
action_on_unpermitted_parameters = (Rails.env.test? || Rails.env.development?) ? :log : false
|
35
40
|
end
|
41
|
+
|
42
|
+
ActionController::Parameters.action_on_unpermitted_parameters = action_on_unpermitted_parameters
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
@@ -55,6 +62,14 @@ module ActionController
|
|
55
62
|
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
|
56
63
|
extend ::ActionController::Railties::Helpers
|
57
64
|
|
65
|
+
# Configs used in other initializers
|
66
|
+
options = options.except(
|
67
|
+
:log_query_tags_around_actions,
|
68
|
+
:permit_all_parameters,
|
69
|
+
:action_on_unpermitted_parameters,
|
70
|
+
:always_permitted_parameters
|
71
|
+
)
|
72
|
+
|
58
73
|
options.each do |k, v|
|
59
74
|
k = "#{k}="
|
60
75
|
if respond_to?(k)
|
@@ -85,5 +100,27 @@ module ActionController
|
|
85
100
|
ActionController::Metal.descendants.each(&:action_methods) if config.eager_load
|
86
101
|
end
|
87
102
|
end
|
103
|
+
|
104
|
+
initializer "action_controller.query_log_tags" do |app|
|
105
|
+
query_logs_tags_enabled = app.config.respond_to?(:active_record) &&
|
106
|
+
app.config.active_record.query_log_tags_enabled &&
|
107
|
+
app.config.action_controller.log_query_tags_around_actions
|
108
|
+
|
109
|
+
if query_logs_tags_enabled
|
110
|
+
app.config.active_record.query_log_tags += [:controller, :action]
|
111
|
+
|
112
|
+
ActiveSupport.on_load(:action_controller) do
|
113
|
+
include ActionController::QueryTags
|
114
|
+
end
|
115
|
+
|
116
|
+
ActiveSupport.on_load(:active_record) do
|
117
|
+
ActiveRecord::QueryLogs.taggings.merge!(
|
118
|
+
controller: ->(context) { context[:controller].controller_name },
|
119
|
+
action: ->(context) { context[:controller].action_name },
|
120
|
+
namespaced_controller: ->(context) { context[:controller].class.name }
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
88
125
|
end
|
89
126
|
end
|
@@ -31,7 +31,7 @@ module ActionController
|
|
31
31
|
|
32
32
|
# ActionController::TestCase will be deprecated and moved to a gem in the future.
|
33
33
|
# Please use ActionDispatch::IntegrationTest going forward.
|
34
|
-
class TestRequest < ActionDispatch::TestRequest
|
34
|
+
class TestRequest < ActionDispatch::TestRequest # :nodoc:
|
35
35
|
DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
|
36
36
|
DEFAULT_ENV.delete "PATH_INFO"
|
37
37
|
|
@@ -179,7 +179,7 @@ module ActionController
|
|
179
179
|
|
180
180
|
# Methods #destroy and #load! are overridden to avoid calling methods on the
|
181
181
|
# @store object, which does not exist for the TestSession class.
|
182
|
-
class TestSession < Rack::Session::Abstract::PersistedSecure::SecureSessionHash
|
182
|
+
class TestSession < Rack::Session::Abstract::PersistedSecure::SecureSessionHash # :nodoc:
|
183
183
|
DEFAULT_OPTIONS = Rack::Session::Abstract::Persisted::DEFAULT_OPTIONS
|
184
184
|
|
185
185
|
def initialize(session = {})
|
@@ -214,6 +214,10 @@ module ActionController
|
|
214
214
|
@data.fetch(key.to_s, *args, &block)
|
215
215
|
end
|
216
216
|
|
217
|
+
def enabled?
|
218
|
+
true
|
219
|
+
end
|
220
|
+
|
217
221
|
private
|
218
222
|
def load!
|
219
223
|
@id
|
data/lib/action_controller.rb
CHANGED
@@ -18,10 +18,6 @@ module ActionController
|
|
18
18
|
end
|
19
19
|
|
20
20
|
autoload_under "metal" do
|
21
|
-
eager_autoload do
|
22
|
-
autoload :Live
|
23
|
-
end
|
24
|
-
|
25
21
|
autoload :ConditionalGet
|
26
22
|
autoload :ContentSecurityPolicy
|
27
23
|
autoload :Cookies
|
@@ -37,9 +33,11 @@ module ActionController
|
|
37
33
|
autoload :BasicImplicitRender
|
38
34
|
autoload :ImplicitRender
|
39
35
|
autoload :Instrumentation
|
36
|
+
autoload :Live
|
40
37
|
autoload :Logging
|
41
38
|
autoload :MimeResponds
|
42
39
|
autoload :ParamsWrapper
|
40
|
+
autoload :QueryTags
|
43
41
|
autoload :Redirecting
|
44
42
|
autoload :Renderers
|
45
43
|
autoload :Rendering
|
@@ -65,5 +63,4 @@ require "active_support/core_ext/module/attribute_accessors"
|
|
65
63
|
require "active_support/core_ext/load_error"
|
66
64
|
require "active_support/core_ext/module/attr_internal"
|
67
65
|
require "active_support/core_ext/name_error"
|
68
|
-
require "active_support/core_ext/uri"
|
69
66
|
require "active_support/inflector"
|
@@ -18,7 +18,7 @@ module ActionDispatch
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def if_none_match_etags
|
21
|
-
if_none_match ? if_none_match.split(
|
21
|
+
if_none_match ? if_none_match.split(/\s*,\s*/) : []
|
22
22
|
end
|
23
23
|
|
24
24
|
def not_modified?(modified_at)
|
@@ -187,13 +187,20 @@ module ActionDispatch
|
|
187
187
|
|
188
188
|
return if control.empty? && cache_control.empty? # Let middleware handle default behavior
|
189
189
|
|
190
|
-
if
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
190
|
+
if cache_control.any?
|
191
|
+
# Any caching directive coming from a controller overrides
|
192
|
+
# no-cache/no-store in the default Cache-Control header.
|
193
|
+
control.delete(:no_cache)
|
194
|
+
control.delete(:no_store)
|
195
195
|
|
196
|
-
|
196
|
+
if extras = control.delete(:extras)
|
197
|
+
cache_control[:extras] ||= []
|
198
|
+
cache_control[:extras] += extras
|
199
|
+
cache_control[:extras].uniq!
|
200
|
+
end
|
201
|
+
|
202
|
+
control.merge! cache_control
|
203
|
+
end
|
197
204
|
|
198
205
|
options = []
|
199
206
|
|
@@ -1,9 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/deep_dup"
|
4
|
-
require "active_support/core_ext/array/wrap"
|
5
4
|
|
6
|
-
module ActionDispatch
|
5
|
+
module ActionDispatch # :nodoc:
|
7
6
|
class ContentSecurityPolicy
|
8
7
|
class Middleware
|
9
8
|
CONTENT_TYPE = "Content-Type"
|
@@ -18,6 +17,7 @@ module ActionDispatch #:nodoc:
|
|
18
17
|
request = ActionDispatch::Request.new env
|
19
18
|
_, headers, _ = response = @app.call(env)
|
20
19
|
|
20
|
+
return response unless html_response?(headers)
|
21
21
|
return response if policy_present?(headers)
|
22
22
|
|
23
23
|
if policy = request.content_security_policy
|
@@ -31,6 +31,12 @@ module ActionDispatch #:nodoc:
|
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
34
|
+
def html_response?(headers)
|
35
|
+
if content_type = headers[CONTENT_TYPE]
|
36
|
+
/html/.match?(content_type)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
34
40
|
def header_name(request)
|
35
41
|
if request.content_security_policy_report_only
|
36
42
|
POLICY_REPORT_ONLY
|
@@ -100,43 +106,47 @@ module ActionDispatch #:nodoc:
|
|
100
106
|
end
|
101
107
|
|
102
108
|
MAPPINGS = {
|
103
|
-
self:
|
104
|
-
unsafe_eval:
|
105
|
-
unsafe_inline:
|
106
|
-
none:
|
107
|
-
http:
|
108
|
-
https:
|
109
|
-
data:
|
110
|
-
mediastream:
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
109
|
+
self: "'self'",
|
110
|
+
unsafe_eval: "'unsafe-eval'",
|
111
|
+
unsafe_inline: "'unsafe-inline'",
|
112
|
+
none: "'none'",
|
113
|
+
http: "http:",
|
114
|
+
https: "https:",
|
115
|
+
data: "data:",
|
116
|
+
mediastream: "mediastream:",
|
117
|
+
allow_duplicates: "'allow-duplicates'",
|
118
|
+
blob: "blob:",
|
119
|
+
filesystem: "filesystem:",
|
120
|
+
report_sample: "'report-sample'",
|
121
|
+
script: "'script'",
|
122
|
+
strict_dynamic: "'strict-dynamic'",
|
123
|
+
ws: "ws:",
|
124
|
+
wss: "wss:"
|
117
125
|
}.freeze
|
118
126
|
|
119
127
|
DIRECTIVES = {
|
120
|
-
base_uri:
|
121
|
-
child_src:
|
122
|
-
connect_src:
|
123
|
-
default_src:
|
124
|
-
font_src:
|
125
|
-
form_action:
|
126
|
-
frame_ancestors:
|
127
|
-
frame_src:
|
128
|
-
img_src:
|
129
|
-
manifest_src:
|
130
|
-
media_src:
|
131
|
-
object_src:
|
132
|
-
prefetch_src:
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
128
|
+
base_uri: "base-uri",
|
129
|
+
child_src: "child-src",
|
130
|
+
connect_src: "connect-src",
|
131
|
+
default_src: "default-src",
|
132
|
+
font_src: "font-src",
|
133
|
+
form_action: "form-action",
|
134
|
+
frame_ancestors: "frame-ancestors",
|
135
|
+
frame_src: "frame-src",
|
136
|
+
img_src: "img-src",
|
137
|
+
manifest_src: "manifest-src",
|
138
|
+
media_src: "media-src",
|
139
|
+
object_src: "object-src",
|
140
|
+
prefetch_src: "prefetch-src",
|
141
|
+
require_trusted_types_for: "require-trusted-types-for",
|
142
|
+
script_src: "script-src",
|
143
|
+
script_src_attr: "script-src-attr",
|
144
|
+
script_src_elem: "script-src-elem",
|
145
|
+
style_src: "style-src",
|
146
|
+
style_src_attr: "style-src-attr",
|
147
|
+
style_src_elem: "style-src-elem",
|
148
|
+
trusted_types: "trusted-types",
|
149
|
+
worker_src: "worker-src"
|
140
150
|
}.freeze
|
141
151
|
|
142
152
|
DEFAULT_NONCE_DIRECTIVES = %w[script-src style-src].freeze
|
@@ -266,7 +276,7 @@ module ActionDispatch #:nodoc:
|
|
266
276
|
raise RuntimeError, "Missing context for the dynamic content security policy source: #{source.inspect}"
|
267
277
|
else
|
268
278
|
resolved = context.instance_exec(&source)
|
269
|
-
|
279
|
+
resolved.is_a?(Symbol) ? apply_mapping(resolved) : resolved
|
270
280
|
end
|
271
281
|
else
|
272
282
|
raise RuntimeError, "Unexpected content security policy source: #{source.inspect}"
|
@@ -18,6 +18,11 @@ module ActionDispatch
|
|
18
18
|
# env["action_dispatch.parameter_filter"] = [:foo, "bar"]
|
19
19
|
# => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
|
20
20
|
#
|
21
|
+
# env["action_dispatch.parameter_filter"] = [ /\Apin\z/i, /\Apin_/i ]
|
22
|
+
# => replaces the value for the exact (case-insensitive) key 'pin' and all
|
23
|
+
# (case-insensitive) keys beginning with 'pin_', with "[FILTERED]"
|
24
|
+
# Does not match keys with 'pin' as a substring, such as 'shipping_id'.
|
25
|
+
#
|
21
26
|
# env["action_dispatch.parameter_filter"] = [ "credit_card.code" ]
|
22
27
|
# => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
|
23
28
|
# change { file: { code: "xxxx"} }
|
@@ -16,12 +16,13 @@ module ActionDispatch
|
|
16
16
|
|
17
17
|
included do
|
18
18
|
mattr_accessor :ignore_accept_header, default: false
|
19
|
+
cattr_accessor :return_only_media_type_on_content_type, default: false
|
19
20
|
end
|
20
21
|
|
21
22
|
# The MIME type of the HTTP request, such as Mime[:xml].
|
22
23
|
def content_mime_type
|
23
24
|
fetch_header("action_dispatch.request.content_type") do |k|
|
24
|
-
v = if get_header("CONTENT_TYPE") =~ /^([
|
25
|
+
v = if get_header("CONTENT_TYPE") =~ /^([^,;]*)/
|
25
26
|
Mime::Type.lookup($1.strip.downcase)
|
26
27
|
else
|
27
28
|
nil
|
@@ -33,7 +34,16 @@ module ActionDispatch
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def content_type
|
36
|
-
|
37
|
+
if self.class.return_only_media_type_on_content_type
|
38
|
+
ActiveSupport::Deprecation.warn(
|
39
|
+
"Rails 7.1 will return Content-Type header without modification." \
|
40
|
+
" If you want just the MIME type, please use `#media_type` instead."
|
41
|
+
)
|
42
|
+
|
43
|
+
content_mime_type&.to_s
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
37
47
|
end
|
38
48
|
|
39
49
|
def has_content_type? # :nodoc:
|
@@ -92,7 +102,7 @@ module ActionDispatch
|
|
92
102
|
def variant=(variant)
|
93
103
|
variant = Array(variant)
|
94
104
|
|
95
|
-
if variant.all?
|
105
|
+
if variant.all?(Symbol)
|
96
106
|
@variant = ActiveSupport::ArrayInquirer.new(variant)
|
97
107
|
else
|
98
108
|
raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols."
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "singleton"
|
4
|
-
require "active_support/core_ext/symbol/starts_ends_with"
|
5
4
|
|
6
5
|
module Mime
|
7
6
|
class Mimes
|
@@ -14,8 +13,8 @@ module Mime
|
|
14
13
|
@symbols = []
|
15
14
|
end
|
16
15
|
|
17
|
-
def each
|
18
|
-
@mimes.each
|
16
|
+
def each(&block)
|
17
|
+
@mimes.each(&block)
|
19
18
|
end
|
20
19
|
|
21
20
|
def <<(type)
|
@@ -43,9 +42,9 @@ module Mime
|
|
43
42
|
Type.lookup_by_extension(type)
|
44
43
|
end
|
45
44
|
|
46
|
-
def fetch(type)
|
45
|
+
def fetch(type, &block)
|
47
46
|
return type if type.is_a?(Type)
|
48
|
-
EXTENSION_LOOKUP.fetch(type.to_s)
|
47
|
+
EXTENSION_LOOKUP.fetch(type.to_s, &block)
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
@@ -68,7 +67,7 @@ module Mime
|
|
68
67
|
@register_callbacks = []
|
69
68
|
|
70
69
|
# A simple helper class used in parsing the accept header.
|
71
|
-
class AcceptItem
|
70
|
+
class AcceptItem # :nodoc:
|
72
71
|
attr_accessor :index, :name, :q
|
73
72
|
alias :to_s :name
|
74
73
|
|
@@ -86,7 +85,7 @@ module Mime
|
|
86
85
|
end
|
87
86
|
end
|
88
87
|
|
89
|
-
class AcceptList
|
88
|
+
class AcceptList # :nodoc:
|
90
89
|
def self.sort!(list)
|
91
90
|
list.sort!
|
92
91
|
|
@@ -226,10 +225,9 @@ module Mime
|
|
226
225
|
attr_reader :hash
|
227
226
|
|
228
227
|
MIME_NAME = "[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}"
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?>\s*#{MIME_PARAMETER}\s*)*)\z/
|
228
|
+
MIME_PARAMETER_VALUE = "#{Regexp.escape('"')}?#{MIME_NAME}#{Regexp.escape('"')}?"
|
229
|
+
MIME_PARAMETER = "\s*;\s*#{MIME_NAME}(?:=#{MIME_PARAMETER_VALUE})?"
|
230
|
+
MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?>#{MIME_PARAMETER})*\s*)\z/
|
233
231
|
|
234
232
|
class InvalidMimeType < StandardError; end
|
235
233
|
|
@@ -17,8 +17,8 @@ module ActionDispatch
|
|
17
17
|
# Raised when raw data from the request cannot be parsed by the parser
|
18
18
|
# defined for request's content MIME type.
|
19
19
|
class ParseError < StandardError
|
20
|
-
def initialize
|
21
|
-
super(
|
20
|
+
def initialize(message = $!.message)
|
21
|
+
super(message)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -62,7 +62,7 @@ module ActionDispatch
|
|
62
62
|
end
|
63
63
|
alias :params :parameters
|
64
64
|
|
65
|
-
def path_parameters=(parameters)
|
65
|
+
def path_parameters=(parameters) # :nodoc:
|
66
66
|
delete_header("action_dispatch.request.parameters")
|
67
67
|
|
68
68
|
parameters = Request::Utils.set_binary_encoding(self, parameters, parameters[:controller], parameters[:action])
|
@@ -93,7 +93,7 @@ module ActionDispatch
|
|
93
93
|
strategy.call(raw_post)
|
94
94
|
rescue # JSON or Ruby code block errors.
|
95
95
|
log_parse_error_once
|
96
|
-
raise ParseError
|
96
|
+
raise ParseError, "Error occurred while parsing request parameters"
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|