actionpack 5.2.8.1 → 6.0.6
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.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +270 -347
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/abstract_controller/base.rb +4 -3
- data/lib/abstract_controller/caching/fragments.rb +6 -22
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +12 -0
- data/lib/abstract_controller/collector.rb +1 -2
- data/lib/abstract_controller/helpers.rb +7 -6
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
- data/lib/abstract_controller/translation.rb +4 -4
- data/lib/action_controller/api.rb +2 -1
- data/lib/action_controller/base.rb +2 -7
- data/lib/action_controller/caching.rb +1 -2
- data/lib/action_controller/log_subscriber.rb +8 -5
- data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
- data/lib/action_controller/metal/conditional_get.rb +9 -3
- data/lib/action_controller/metal/content_security_policy.rb +0 -1
- data/lib/action_controller/metal/data_streaming.rb +5 -6
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +23 -2
- data/lib/action_controller/metal/flash.rb +5 -5
- data/lib/action_controller/metal/force_ssl.rb +15 -56
- data/lib/action_controller/metal/head.rb +1 -1
- data/lib/action_controller/metal/helpers.rb +3 -4
- data/lib/action_controller/metal/http_authentication.rb +20 -21
- data/lib/action_controller/metal/implicit_render.rb +4 -14
- data/lib/action_controller/metal/instrumentation.rb +3 -6
- data/lib/action_controller/metal/live.rb +29 -31
- data/lib/action_controller/metal/mime_responds.rb +13 -2
- data/lib/action_controller/metal/params_wrapper.rb +18 -14
- data/lib/action_controller/metal/redirecting.rb +5 -5
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +2 -3
- data/lib/action_controller/metal/request_forgery_protection.rb +25 -48
- data/lib/action_controller/metal/streaming.rb +0 -1
- data/lib/action_controller/metal/strong_parameters.rb +65 -44
- data/lib/action_controller/metal/url_for.rb +1 -1
- data/lib/action_controller/metal.rb +8 -6
- data/lib/action_controller/railties/helpers.rb +1 -1
- data/lib/action_controller/renderer.rb +17 -3
- data/lib/action_controller/template_assertions.rb +1 -1
- data/lib/action_controller/test_case.rb +7 -8
- data/lib/action_controller.rb +5 -1
- data/lib/action_dispatch/http/cache.rb +14 -11
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +28 -17
- data/lib/action_dispatch/http/filter_parameters.rb +8 -7
- data/lib/action_dispatch/http/filter_redirect.rb +1 -2
- data/lib/action_dispatch/http/headers.rb +1 -2
- data/lib/action_dispatch/http/mime_negotiation.rb +13 -6
- data/lib/action_dispatch/http/mime_type.rb +14 -8
- data/lib/action_dispatch/http/parameter_filter.rb +5 -79
- data/lib/action_dispatch/http/parameters.rb +15 -6
- data/lib/action_dispatch/http/request.rb +21 -14
- data/lib/action_dispatch/http/response.rb +40 -21
- data/lib/action_dispatch/http/upload.rb +9 -1
- data/lib/action_dispatch/http/url.rb +81 -82
- data/lib/action_dispatch/journey/formatter.rb +2 -3
- data/lib/action_dispatch/journey/gtg/builder.rb +0 -1
- data/lib/action_dispatch/journey/gtg/transition_table.rb +0 -1
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -2
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -1
- data/lib/action_dispatch/journey/nodes/node.rb +9 -8
- data/lib/action_dispatch/journey/path/pattern.rb +6 -3
- data/lib/action_dispatch/journey/route.rb +5 -4
- data/lib/action_dispatch/journey/router/utils.rb +10 -10
- data/lib/action_dispatch/journey/router.rb +0 -4
- data/lib/action_dispatch/journey/routes.rb +0 -2
- data/lib/action_dispatch/journey/scanner.rb +10 -4
- data/lib/action_dispatch/journey/visitors.rb +1 -4
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -4
- data/lib/action_dispatch/middleware/cookies.rb +62 -78
- data/lib/action_dispatch/middleware/debug_exceptions.rb +45 -61
- data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +49 -16
- data/lib/action_dispatch/middleware/flash.rb +1 -1
- data/lib/action_dispatch/middleware/host_authorization.rb +121 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +6 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +9 -12
- data/lib/action_dispatch/middleware/request_id.rb +2 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +0 -1
- data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -7
- data/lib/action_dispatch/middleware/show_exceptions.rb +1 -2
- data/lib/action_dispatch/middleware/ssl.rb +8 -8
- data/lib/action_dispatch/middleware/stack.rb +38 -2
- data/lib/action_dispatch/middleware/static.rb +6 -7
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +7 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +5 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +3 -0
- data/lib/action_dispatch/railtie.rb +7 -2
- data/lib/action_dispatch/request/session.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +97 -50
- data/lib/action_dispatch/routing/mapper.rb +63 -42
- data/lib/action_dispatch/routing/polymorphic_routes.rb +3 -6
- data/lib/action_dispatch/routing/route_set.rb +25 -31
- data/lib/action_dispatch/routing/url_for.rb +2 -2
- data/lib/action_dispatch/routing.rb +21 -20
- data/lib/action_dispatch/system_test_case.rb +44 -6
- data/lib/action_dispatch/system_testing/browser.rb +38 -7
- data/lib/action_dispatch/system_testing/driver.rb +11 -2
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -5
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +7 -6
- data/lib/action_dispatch/testing/assertion_response.rb +0 -1
- data/lib/action_dispatch/testing/assertions/response.rb +2 -3
- data/lib/action_dispatch/testing/assertions/routing.rb +15 -3
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/integration.rb +33 -12
- data/lib/action_dispatch/testing/request_encoder.rb +2 -2
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch/testing/test_response.rb +4 -32
- data/lib/action_dispatch.rb +7 -2
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +29 -15
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "active_support/parameter_filter"
|
4
4
|
|
5
5
|
module ActionDispatch
|
6
6
|
module Http
|
@@ -9,8 +9,8 @@ module ActionDispatch
|
|
9
9
|
# sub-hashes of the params hash to filter. Filtering only certain sub-keys
|
10
10
|
# from a hash is possible by using the dot notation: 'credit_card.number'.
|
11
11
|
# If a block is given, each key and value of the params hash and all
|
12
|
-
# sub-hashes
|
13
|
-
# String#replace or similar
|
12
|
+
# sub-hashes are passed to it, where the value or the key can be replaced using
|
13
|
+
# String#replace or similar methods.
|
14
14
|
#
|
15
15
|
# env["action_dispatch.parameter_filter"] = [:password]
|
16
16
|
# => replaces the value to all keys matching /password/i with "[FILTERED]"
|
@@ -28,8 +28,8 @@ module ActionDispatch
|
|
28
28
|
# => reverses the value to all keys matching /secret/i
|
29
29
|
module FilterParameters
|
30
30
|
ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc:
|
31
|
-
NULL_PARAM_FILTER = ParameterFilter.new # :nodoc:
|
32
|
-
NULL_ENV_FILTER = ParameterFilter.new ENV_MATCH # :nodoc:
|
31
|
+
NULL_PARAM_FILTER = ActiveSupport::ParameterFilter.new # :nodoc:
|
32
|
+
NULL_ENV_FILTER = ActiveSupport::ParameterFilter.new ENV_MATCH # :nodoc:
|
33
33
|
|
34
34
|
def initialize
|
35
35
|
super
|
@@ -41,6 +41,8 @@ module ActionDispatch
|
|
41
41
|
# Returns a hash of parameters with all sensitive data replaced.
|
42
42
|
def filtered_parameters
|
43
43
|
@filtered_parameters ||= parameter_filter.filter(parameters)
|
44
|
+
rescue ActionDispatch::Http::Parameters::ParseError
|
45
|
+
@filtered_parameters = {}
|
44
46
|
end
|
45
47
|
|
46
48
|
# Returns a hash of request.env with all sensitive data replaced.
|
@@ -54,7 +56,6 @@ module ActionDispatch
|
|
54
56
|
end
|
55
57
|
|
56
58
|
private
|
57
|
-
|
58
59
|
def parameter_filter # :doc:
|
59
60
|
parameter_filter_for fetch_header("action_dispatch.parameter_filter") {
|
60
61
|
return NULL_PARAM_FILTER
|
@@ -69,7 +70,7 @@ module ActionDispatch
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def parameter_filter_for(filters) # :doc:
|
72
|
-
ParameterFilter.new(filters)
|
73
|
+
ActiveSupport::ParameterFilter.new(filters)
|
73
74
|
end
|
74
75
|
|
75
76
|
KV_RE = "[^&;=]+"
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module ActionDispatch
|
4
4
|
module Http
|
5
5
|
module FilterRedirect
|
6
|
-
FILTERED = "[FILTERED]"
|
6
|
+
FILTERED = "[FILTERED]" # :nodoc:
|
7
7
|
|
8
8
|
def filtered_location # :nodoc:
|
9
9
|
if location_filter_match?
|
@@ -14,7 +14,6 @@ module ActionDispatch
|
|
14
14
|
end
|
15
15
|
|
16
16
|
private
|
17
|
-
|
18
17
|
def location_filters
|
19
18
|
if request
|
20
19
|
request.get_header("action_dispatch.redirect_filter") || []
|
@@ -116,12 +116,11 @@ module ActionDispatch
|
|
116
116
|
def env; @req.env.dup; end
|
117
117
|
|
118
118
|
private
|
119
|
-
|
120
119
|
# Converts an HTTP header name to an environment variable name if it is
|
121
120
|
# not contained within the headers hash.
|
122
121
|
def env_name(key)
|
123
122
|
key = key.to_s
|
124
|
-
if key
|
123
|
+
if HTTP_HEADER.match?(key)
|
125
124
|
key = key.upcase.tr("-", "_")
|
126
125
|
key = "HTTP_" + key unless CGI_VARIABLES.include?(key)
|
127
126
|
end
|
@@ -7,6 +7,13 @@ module ActionDispatch
|
|
7
7
|
module MimeNegotiation
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
|
+
class InvalidType < ::Mime::Type::InvalidMimeType; end
|
11
|
+
|
12
|
+
RESCUABLE_MIME_FORMAT_ERRORS = [
|
13
|
+
ActionController::BadRequest,
|
14
|
+
ActionDispatch::Http::Parameters::ParseError,
|
15
|
+
]
|
16
|
+
|
10
17
|
included do
|
11
18
|
mattr_accessor :ignore_accept_header, default: false
|
12
19
|
end
|
@@ -20,6 +27,8 @@ module ActionDispatch
|
|
20
27
|
nil
|
21
28
|
end
|
22
29
|
set_header k, v
|
30
|
+
rescue ::Mime::Type::InvalidMimeType => e
|
31
|
+
raise InvalidType, e.message
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
@@ -42,6 +51,8 @@ module ActionDispatch
|
|
42
51
|
Mime::Type.parse(header)
|
43
52
|
end
|
44
53
|
set_header k, v
|
54
|
+
rescue ::Mime::Type::InvalidMimeType => e
|
55
|
+
raise InvalidType, e.message
|
45
56
|
end
|
46
57
|
end
|
47
58
|
|
@@ -59,7 +70,7 @@ module ActionDispatch
|
|
59
70
|
fetch_header("action_dispatch.request.formats") do |k|
|
60
71
|
params_readable = begin
|
61
72
|
parameters[:format]
|
62
|
-
rescue
|
73
|
+
rescue *RESCUABLE_MIME_FORMAT_ERRORS
|
63
74
|
false
|
64
75
|
end
|
65
76
|
|
@@ -90,10 +101,7 @@ module ActionDispatch
|
|
90
101
|
if variant.all? { |v| v.is_a?(Symbol) }
|
91
102
|
@variant = ActiveSupport::ArrayInquirer.new(variant)
|
92
103
|
else
|
93
|
-
raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols.
|
94
|
-
"For security reasons, never directly set the variant to a user-provided value, " \
|
95
|
-
"like params[:variant].to_sym. Check user-provided value against a whitelist first, " \
|
96
|
-
"then set the variant: request.variant = :tablet if params[:variant] == 'tablet'"
|
104
|
+
raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols."
|
97
105
|
end
|
98
106
|
end
|
99
107
|
|
@@ -152,7 +160,6 @@ module ActionDispatch
|
|
152
160
|
end
|
153
161
|
|
154
162
|
private
|
155
|
-
|
156
163
|
BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/
|
157
164
|
|
158
165
|
def valid_accept_header # :doc:
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# -*- frozen-string-literal: true -*-
|
4
|
-
|
5
3
|
require "singleton"
|
6
4
|
require "active_support/core_ext/string/starts_ends_with"
|
7
5
|
|
@@ -74,7 +72,7 @@ module Mime
|
|
74
72
|
def initialize(index, name, q = nil)
|
75
73
|
@index = index
|
76
74
|
@name = name
|
77
|
-
q ||= 0.0 if @name == "*/*"
|
75
|
+
q ||= 0.0 if @name == "*/*" # Default wildcard match to end of list.
|
78
76
|
@q = ((q || 1.0).to_f * 100).to_i
|
79
77
|
end
|
80
78
|
|
@@ -172,6 +170,7 @@ module Mime
|
|
172
170
|
def parse(accept_header)
|
173
171
|
if !accept_header.include?(",")
|
174
172
|
accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first
|
173
|
+
return [] unless accept_header
|
175
174
|
parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)].compact
|
176
175
|
else
|
177
176
|
list, index = [], 0
|
@@ -223,7 +222,18 @@ module Mime
|
|
223
222
|
|
224
223
|
attr_reader :hash
|
225
224
|
|
225
|
+
MIME_NAME = "[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}"
|
226
|
+
MIME_PARAMETER_KEY = "[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}"
|
227
|
+
MIME_PARAMETER_VALUE = "#{Regexp.escape('"')}?[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}#{Regexp.escape('"')}?"
|
228
|
+
MIME_PARAMETER = "\s*\;\s*#{MIME_PARAMETER_KEY}(?:\=#{MIME_PARAMETER_VALUE})?"
|
229
|
+
MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?>\s*#{MIME_PARAMETER}\s*)*)\z/
|
230
|
+
|
231
|
+
class InvalidMimeType < StandardError; end
|
232
|
+
|
226
233
|
def initialize(string, symbol = nil, synonyms = [])
|
234
|
+
unless MIME_REGEXP.match?(string)
|
235
|
+
raise InvalidMimeType, "#{string.inspect} is not a valid MIME type"
|
236
|
+
end
|
227
237
|
@symbol, @synonyms = symbol, synonyms
|
228
238
|
@string = string
|
229
239
|
@hash = [@string, @synonyms, @symbol].hash
|
@@ -279,14 +289,10 @@ module Mime
|
|
279
289
|
|
280
290
|
def all?; false; end
|
281
291
|
|
282
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
283
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
284
292
|
protected
|
285
|
-
|
286
293
|
attr_reader :string, :synonyms
|
287
294
|
|
288
295
|
private
|
289
|
-
|
290
296
|
def to_ary; end
|
291
297
|
def to_a; end
|
292
298
|
|
@@ -307,7 +313,7 @@ module Mime
|
|
307
313
|
include Singleton
|
308
314
|
|
309
315
|
def initialize
|
310
|
-
super "*/*",
|
316
|
+
super "*/*", nil
|
311
317
|
end
|
312
318
|
|
313
319
|
def all?; true; end
|
@@ -1,86 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/
|
3
|
+
require "active_support/deprecation/constant_accessor"
|
4
|
+
require "active_support/parameter_filter"
|
4
5
|
|
5
6
|
module ActionDispatch
|
6
7
|
module Http
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def initialize(filters = [])
|
11
|
-
@filters = filters
|
12
|
-
end
|
13
|
-
|
14
|
-
def filter(params)
|
15
|
-
compiled_filter.call(params)
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def compiled_filter
|
21
|
-
@compiled_filter ||= CompiledFilter.compile(@filters)
|
22
|
-
end
|
23
|
-
|
24
|
-
class CompiledFilter # :nodoc:
|
25
|
-
def self.compile(filters)
|
26
|
-
return lambda { |params| params.dup } if filters.empty?
|
27
|
-
|
28
|
-
strings, regexps, blocks = [], [], []
|
29
|
-
|
30
|
-
filters.each do |item|
|
31
|
-
case item
|
32
|
-
when Proc
|
33
|
-
blocks << item
|
34
|
-
when Regexp
|
35
|
-
regexps << item
|
36
|
-
else
|
37
|
-
strings << Regexp.escape(item.to_s)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
|
42
|
-
deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
|
43
|
-
|
44
|
-
regexps << Regexp.new(strings.join("|".freeze), true) unless strings.empty?
|
45
|
-
deep_regexps << Regexp.new(deep_strings.join("|".freeze), true) unless deep_strings.empty?
|
46
|
-
|
47
|
-
new regexps, deep_regexps, blocks
|
48
|
-
end
|
49
|
-
|
50
|
-
attr_reader :regexps, :deep_regexps, :blocks
|
51
|
-
|
52
|
-
def initialize(regexps, deep_regexps, blocks)
|
53
|
-
@regexps = regexps
|
54
|
-
@deep_regexps = deep_regexps.any? ? deep_regexps : nil
|
55
|
-
@blocks = blocks
|
56
|
-
end
|
57
|
-
|
58
|
-
def call(original_params, parents = [])
|
59
|
-
filtered_params = original_params.class.new
|
60
|
-
|
61
|
-
original_params.each do |key, value|
|
62
|
-
parents.push(key) if deep_regexps
|
63
|
-
if regexps.any? { |r| key =~ r }
|
64
|
-
value = FILTERED
|
65
|
-
elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| joined =~ r }
|
66
|
-
value = FILTERED
|
67
|
-
elsif value.is_a?(Hash)
|
68
|
-
value = call(value, parents)
|
69
|
-
elsif value.is_a?(Array)
|
70
|
-
value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v }
|
71
|
-
elsif blocks.any?
|
72
|
-
key = key.dup if key.duplicable?
|
73
|
-
value = value.dup if value.duplicable?
|
74
|
-
blocks.each { |b| b.call(key, value) }
|
75
|
-
end
|
76
|
-
parents.pop if deep_regexps
|
77
|
-
|
78
|
-
filtered_params[key] = value
|
79
|
-
end
|
80
|
-
|
81
|
-
filtered_params
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
8
|
+
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
9
|
+
deprecate_constant "ParameterFilter", "ActiveSupport::ParameterFilter",
|
10
|
+
message: "ActionDispatch::Http::ParameterFilter is deprecated and will be removed from Rails 6.1. Use ActiveSupport::ParameterFilter instead."
|
85
11
|
end
|
86
12
|
end
|
@@ -85,12 +85,11 @@ module ActionDispatch
|
|
85
85
|
end
|
86
86
|
|
87
87
|
private
|
88
|
-
|
89
88
|
def set_binary_encoding(params, controller, action)
|
90
89
|
return params unless controller && controller.valid_encoding?
|
91
90
|
|
92
91
|
if binary_params_for?(controller, action)
|
93
|
-
ActionDispatch::Request::Utils.each_param_value(params) do |param|
|
92
|
+
ActionDispatch::Request::Utils.each_param_value(params.except(:controller, :action)) do |param|
|
94
93
|
param.force_encoding ::Encoding::ASCII_8BIT
|
95
94
|
end
|
96
95
|
end
|
@@ -99,7 +98,7 @@ module ActionDispatch
|
|
99
98
|
|
100
99
|
def binary_params_for?(controller, action)
|
101
100
|
controller_class_for(controller).binary_params_for?(action)
|
102
|
-
rescue
|
101
|
+
rescue MissingController
|
103
102
|
false
|
104
103
|
end
|
105
104
|
|
@@ -111,13 +110,23 @@ module ActionDispatch
|
|
111
110
|
begin
|
112
111
|
strategy.call(raw_post)
|
113
112
|
rescue # JSON or Ruby code block errors.
|
114
|
-
|
115
|
-
my_logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{raw_post}"
|
116
|
-
|
113
|
+
log_parse_error_once
|
117
114
|
raise ParseError
|
118
115
|
end
|
119
116
|
end
|
120
117
|
|
118
|
+
def log_parse_error_once
|
119
|
+
@parse_error_logged ||= begin
|
120
|
+
parse_logger = logger || ActiveSupport::Logger.new($stderr)
|
121
|
+
parse_logger.debug <<~MSG.chomp
|
122
|
+
Error occurred while parsing request parameters.
|
123
|
+
Contents:
|
124
|
+
|
125
|
+
#{raw_post}
|
126
|
+
MSG
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
121
130
|
def params_parsers
|
122
131
|
ActionDispatch::Request.parameter_parsers
|
123
132
|
end
|
@@ -85,7 +85,15 @@ module ActionDispatch
|
|
85
85
|
if name
|
86
86
|
controller_param = name.underscore
|
87
87
|
const_name = "#{controller_param.camelize}Controller"
|
88
|
-
|
88
|
+
begin
|
89
|
+
ActiveSupport::Dependencies.constantize(const_name)
|
90
|
+
rescue NameError => error
|
91
|
+
if error.missing_name == const_name || const_name.start_with?("#{error.missing_name}::")
|
92
|
+
raise MissingController.new(error.message, error.name)
|
93
|
+
else
|
94
|
+
raise
|
95
|
+
end
|
96
|
+
end
|
89
97
|
else
|
90
98
|
PASS_NOT_FOUND
|
91
99
|
end
|
@@ -125,6 +133,8 @@ module ActionDispatch
|
|
125
133
|
HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym
|
126
134
|
}
|
127
135
|
|
136
|
+
alias raw_request_method request_method # :nodoc:
|
137
|
+
|
128
138
|
# Returns the HTTP \method that the application should see.
|
129
139
|
# In the case where the \method was overridden by a middleware
|
130
140
|
# (for instance, if a HEAD request was converted to a GET,
|
@@ -136,11 +146,11 @@ module ActionDispatch
|
|
136
146
|
end
|
137
147
|
|
138
148
|
def routes # :nodoc:
|
139
|
-
get_header("action_dispatch.routes"
|
149
|
+
get_header("action_dispatch.routes")
|
140
150
|
end
|
141
151
|
|
142
152
|
def routes=(routes) # :nodoc:
|
143
|
-
set_header("action_dispatch.routes"
|
153
|
+
set_header("action_dispatch.routes", routes)
|
144
154
|
end
|
145
155
|
|
146
156
|
def engine_script_name(_routes) # :nodoc:
|
@@ -158,11 +168,11 @@ module ActionDispatch
|
|
158
168
|
end
|
159
169
|
|
160
170
|
def controller_instance # :nodoc:
|
161
|
-
get_header("action_controller.instance"
|
171
|
+
get_header("action_controller.instance")
|
162
172
|
end
|
163
173
|
|
164
174
|
def controller_instance=(controller) # :nodoc:
|
165
|
-
set_header("action_controller.instance"
|
175
|
+
set_header("action_controller.instance", controller)
|
166
176
|
end
|
167
177
|
|
168
178
|
def http_auth_salt
|
@@ -173,7 +183,7 @@ module ActionDispatch
|
|
173
183
|
# We're treating `nil` as "unset", and we want the default setting to be
|
174
184
|
# `true`. This logic should be extracted to `env_config` and calculated
|
175
185
|
# once.
|
176
|
-
!(get_header("action_dispatch.show_exceptions"
|
186
|
+
!(get_header("action_dispatch.show_exceptions") == false)
|
177
187
|
end
|
178
188
|
|
179
189
|
# Returns a symbol form of the #request_method.
|
@@ -280,10 +290,10 @@ module ActionDispatch
|
|
280
290
|
end
|
281
291
|
|
282
292
|
def remote_ip=(remote_ip)
|
283
|
-
set_header "action_dispatch.remote_ip"
|
293
|
+
set_header "action_dispatch.remote_ip", remote_ip
|
284
294
|
end
|
285
295
|
|
286
|
-
ACTION_DISPATCH_REQUEST_ID = "action_dispatch.request_id"
|
296
|
+
ACTION_DISPATCH_REQUEST_ID = "action_dispatch.request_id" # :nodoc:
|
287
297
|
|
288
298
|
# Returns the unique request id, which is based on either the X-Request-Id header that can
|
289
299
|
# be generated by a firewall, load balancer, or web server or by the RequestId middleware
|
@@ -383,9 +393,6 @@ module ActionDispatch
|
|
383
393
|
end
|
384
394
|
self.request_parameters = Request::Utils.normalize_encode_params(pr)
|
385
395
|
end
|
386
|
-
rescue Http::Parameters::ParseError # one of the parse strategies blew up
|
387
|
-
self.request_parameters = Request::Utils.normalize_encode_params(super || {})
|
388
|
-
raise
|
389
396
|
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
|
390
397
|
raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
|
391
398
|
end
|
@@ -407,18 +414,18 @@ module ActionDispatch
|
|
407
414
|
|
408
415
|
def request_parameters=(params)
|
409
416
|
raise if params.nil?
|
410
|
-
set_header("action_dispatch.request.request_parameters"
|
417
|
+
set_header("action_dispatch.request.request_parameters", params)
|
411
418
|
end
|
412
419
|
|
413
420
|
def logger
|
414
|
-
get_header("action_dispatch.logger"
|
421
|
+
get_header("action_dispatch.logger")
|
415
422
|
end
|
416
423
|
|
417
424
|
def commit_flash
|
418
425
|
end
|
419
426
|
|
420
427
|
def ssl?
|
421
|
-
super || scheme == "wss"
|
428
|
+
super || scheme == "wss"
|
422
429
|
end
|
423
430
|
|
424
431
|
private
|
@@ -78,13 +78,14 @@ module ActionDispatch # :nodoc:
|
|
78
78
|
x
|
79
79
|
end
|
80
80
|
|
81
|
-
CONTENT_TYPE = "Content-Type"
|
82
|
-
SET_COOKIE = "Set-Cookie"
|
83
|
-
LOCATION = "Location"
|
81
|
+
CONTENT_TYPE = "Content-Type"
|
82
|
+
SET_COOKIE = "Set-Cookie"
|
83
|
+
LOCATION = "Location"
|
84
84
|
NO_CONTENT_CODES = [100, 101, 102, 204, 205, 304]
|
85
85
|
|
86
86
|
cattr_accessor :default_charset, default: "utf-8"
|
87
87
|
cattr_accessor :default_headers
|
88
|
+
cattr_accessor :return_only_media_type_on_content_type, default: false
|
88
89
|
|
89
90
|
include Rack::Response::Helpers
|
90
91
|
# Aliasing these off because AD::Http::Cache::Response defines them.
|
@@ -105,7 +106,7 @@ module ActionDispatch # :nodoc:
|
|
105
106
|
|
106
107
|
def body
|
107
108
|
@str_body ||= begin
|
108
|
-
buf = ""
|
109
|
+
buf = +""
|
109
110
|
each { |chunk| buf << chunk }
|
110
111
|
buf
|
111
112
|
end
|
@@ -142,7 +143,6 @@ module ActionDispatch # :nodoc:
|
|
142
143
|
end
|
143
144
|
|
144
145
|
private
|
145
|
-
|
146
146
|
def each_chunk(&block)
|
147
147
|
@buf.each(&block)
|
148
148
|
end
|
@@ -224,16 +224,6 @@ module ActionDispatch # :nodoc:
|
|
224
224
|
@status = Rack::Utils.status_code(status)
|
225
225
|
end
|
226
226
|
|
227
|
-
# Sets the HTTP content type.
|
228
|
-
def content_type=(content_type)
|
229
|
-
return unless content_type
|
230
|
-
new_header_info = parse_content_type(content_type.to_s)
|
231
|
-
prev_header_info = parsed_content_type_header
|
232
|
-
charset = new_header_info.charset || prev_header_info.charset
|
233
|
-
charset ||= self.class.default_charset unless prev_header_info.mime_type
|
234
|
-
set_content_type new_header_info.mime_type, charset
|
235
|
-
end
|
236
|
-
|
237
227
|
# Sets the HTTP response's content MIME type. For example, in the controller
|
238
228
|
# you could write this:
|
239
229
|
#
|
@@ -242,8 +232,32 @@ module ActionDispatch # :nodoc:
|
|
242
232
|
# If a character set has been defined for this response (see charset=) then
|
243
233
|
# the character set information will also be included in the content type
|
244
234
|
# information.
|
235
|
+
def content_type=(content_type)
|
236
|
+
return unless content_type
|
237
|
+
new_header_info = parse_content_type(content_type.to_s)
|
238
|
+
prev_header_info = parsed_content_type_header
|
239
|
+
charset = new_header_info.charset || prev_header_info.charset
|
240
|
+
charset ||= self.class.default_charset unless prev_header_info.mime_type
|
241
|
+
set_content_type new_header_info.mime_type, charset
|
242
|
+
end
|
245
243
|
|
244
|
+
# Content type of response.
|
246
245
|
def content_type
|
246
|
+
if self.class.return_only_media_type_on_content_type
|
247
|
+
ActiveSupport::Deprecation.warn(
|
248
|
+
"Rails 6.1 will return Content-Type header without modification." \
|
249
|
+
" If you want just the MIME type, please use `#media_type` instead."
|
250
|
+
)
|
251
|
+
|
252
|
+
content_type = super
|
253
|
+
content_type ? content_type.split(/;\s*charset=/)[0].presence : content_type
|
254
|
+
else
|
255
|
+
super.presence
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# Media type of response.
|
260
|
+
def media_type
|
247
261
|
parsed_content_type_header.mime_type
|
248
262
|
end
|
249
263
|
|
@@ -404,15 +418,18 @@ module ActionDispatch # :nodoc:
|
|
404
418
|
end
|
405
419
|
|
406
420
|
private
|
407
|
-
|
408
421
|
ContentTypeHeader = Struct.new :mime_type, :charset
|
409
422
|
NullContentTypeHeader = ContentTypeHeader.new nil, nil
|
410
423
|
|
424
|
+
CONTENT_TYPE_PARSER = /
|
425
|
+
\A
|
426
|
+
(?<mime_type>[^;\s]+\s*(?:;\s*(?:(?!charset)[^;\s])+)*)?
|
427
|
+
(?:;\s*charset=(?<quote>"?)(?<charset>[^;\s]+)\k<quote>)?
|
428
|
+
/x # :nodoc:
|
429
|
+
|
411
430
|
def parse_content_type(content_type)
|
412
|
-
if content_type
|
413
|
-
|
414
|
-
type = nil if type && type.empty?
|
415
|
-
ContentTypeHeader.new(type, charset)
|
431
|
+
if content_type && match = CONTENT_TYPE_PARSER.match(content_type)
|
432
|
+
ContentTypeHeader.new(match[:mime_type], match[:charset])
|
416
433
|
else
|
417
434
|
NullContentTypeHeader
|
418
435
|
end
|
@@ -459,7 +476,7 @@ module ActionDispatch # :nodoc:
|
|
459
476
|
end
|
460
477
|
|
461
478
|
def assign_default_content_type_and_charset!
|
462
|
-
return if
|
479
|
+
return if media_type
|
463
480
|
|
464
481
|
ct = parsed_content_type_header
|
465
482
|
set_content_type(ct.mime_type || Mime[:html].to_s,
|
@@ -517,4 +534,6 @@ module ActionDispatch # :nodoc:
|
|
517
534
|
end
|
518
535
|
end
|
519
536
|
end
|
537
|
+
|
538
|
+
ActiveSupport.run_load_hooks(:action_dispatch_response, Response)
|
520
539
|
end
|
@@ -20,7 +20,6 @@ module ActionDispatch
|
|
20
20
|
# A +Tempfile+ object with the actual uploaded file. Note that some of
|
21
21
|
# its interface is available directly.
|
22
22
|
attr_accessor :tempfile
|
23
|
-
alias :to_io :tempfile
|
24
23
|
|
25
24
|
# A string with the headers of the multipart request.
|
26
25
|
attr_accessor :headers
|
@@ -65,6 +64,11 @@ module ActionDispatch
|
|
65
64
|
@tempfile.path
|
66
65
|
end
|
67
66
|
|
67
|
+
# Shortcut for +tempfile.to_path+.
|
68
|
+
def to_path
|
69
|
+
@tempfile.to_path
|
70
|
+
end
|
71
|
+
|
68
72
|
# Shortcut for +tempfile.rewind+.
|
69
73
|
def rewind
|
70
74
|
@tempfile.rewind
|
@@ -79,6 +83,10 @@ module ActionDispatch
|
|
79
83
|
def eof?
|
80
84
|
@tempfile.eof?
|
81
85
|
end
|
86
|
+
|
87
|
+
def to_io
|
88
|
+
@tempfile.to_io
|
89
|
+
end
|
82
90
|
end
|
83
91
|
end
|
84
92
|
end
|